2017-03-05 125 views
3

我使用了從this SO接受的答案代碼。現在,我想要將其轉換回BufferedImage(最好不要使用setRGB())。我試過這個:將2D像素數組轉換爲BufferedImage

private BufferedImage createImage(int[][] pixelData, BufferedImage outputImage){ 
    final int[] outputImagePixelData = ((DataBufferInt) outputImage.getRaster().getDataBuffer()).getData(); 
    System.arraycopy(pixelData, 0, outputImagePixelData, 0, pixelData.length); 
    return outputImage; 
} 

但它不起作用,因爲它需要一維數組作爲參數,而不是二維數組。

回答

2

如果您outputImage已具有良好的類型和格式,那麼你可以簡單地做使用循環一個2D到1D轉換(假設你的陣列編碼爲[nbRows] [RowLength]):

private BufferedImage createImage(int[][] pixelData, BufferedImage outputImage) 
    { 
    int[] outputImagePixelData = ((DataBufferInt) outputImage.getRaster().getDataBuffer()).getData() ; 

    final int width = outputImage.getWidth() ; 
    final int height = outputImage.getHeight() ; 

    for (int y=0, pos=0 ; y < height ; y++) 
     for (int x=0 ; x < width ; x++, pos++) 
      outputImagePixelData[pos] = pixelData[y][x] ; 

    return outputImage; 
    } 

但是, INT類型在BufferedImage中沒有很好定義。默認情況下,您有TYPE_INT_RGB和TYPE_INT_ARGB,它們將像素編碼的R,G,B,A值與單個INT連接起來。如果你想創建類型INT與單通道灰度級的BufferedImage,那麼你應該做的:

private BufferedImage createImage(int[][] pixelData) 
    { 
    final int width = pixelData[0].length ; 
    final int height = pixelData.length ; 
    // First I create a BufferedImage with a DataBufferInt, with the appropriate dimensions and number of channels/bands/colors 
    ColorSpace myColorSpace = new FloatCS(ColorSpace.TYPE_GRAY, channel) ; 
    int[] bits = new int[]{32} ; 
    ColorModel myColorModel = new ComponentColorModel(myColorSpace,bits,false,false,ColorModel.OPAQUE,DataBuffer.TYPE_INT) ; 
    BufferedImage outputImage = new BufferedImage(myColorModel, myColorModel.createCompatibleWritableRaster(width, height), false, null) ; 

    int[] outputImagePixelData = ((DataBufferInt) outputImage.getRaster().getDataBuffer()).getData() ; 

    for (int y=0, pos=0 ; y < height ; y++) 
     for (int x=0 ; x < width ; x++, pos++) 
      outputImagePixelData[pos] = pixelData[y][x] ; 

    return outputImage ; 
    } 

隨着FloatCS是ColorSpace類。當你想要特定的ColorSpace像Lab,HLS等時,你必須創建你自己的ColorSpace類。

public class FloatCS extends ColorSpace 
{ 

private static final long serialVersionUID = -7713114653902159981L; 

private ColorSpace rgb = ColorSpace.getInstance(ColorSpace.CS_sRGB) ; 

public FloatCS(int type, int channel) 
    { 
    super(type, channel) ; 
    } 


@Override 
public float[] fromCIEXYZ(float[] pixel) 
    { 
    return fromRGB(rgb.fromCIEXYZ(pixel)) ; 
    } 

@Override 
public float[] fromRGB(float[] RGB) 
    { 
    return RGB ; 
    } 

@Override 
public float[] toCIEXYZ(float[] pixel) 
    { 
    return rgb.toCIEXYZ(toRGB(pixel)) ; 
    } 

@Override 
public float[] toRGB(float[] nRGB) 
    { 
    return nRGB ; 
    } 
} 
+0

什麼是FloatCS類? –

+0

對不起,我忘了。這裏是。 – FiReTiTi

1

代替使用System.arraycopy的,可以簡單地使用一個雙for -loop和迭代x/y,這樣的事情:

private BufferedImage createImage(int[][] pixelData, BufferedImage outputImage) { 
    int[] outputImagePixelData = ((DataBufferInt) outputImage.getRaster().getDataBuffer()).getData(); 

    int width = outputImage.getWidth(); 
    int height = outputImage.getHeight(); 

    for (int y = 0; y < height; y++) { 
     for (int x = 0; x < width; x++) { 
      outputImagePixelData[y * width + x] = pixelData[x][y]; 
     } 
    } 

    return outputImage; 
} 

上述代碼假定一個數組元素對應於一個像素元件(對於所有BufferedImage.TYPE_INT_*類型都是這種情況)。