将2D像素阵列转换为BufferedImage

时间:2017-03-05 23:45:26

标签: java image bufferedimage pixels

我使用了来自this SO问题的已接受答案的代码。现在,我想转换回BufferedImage(最好不要使用setRGB())。我试过这个:

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;
}

但它不起作用,因为它将1D数组作为参数,而不是2D数组。

2 个答案:

答案 0 :(得分: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 ;
    }
}

答案 1 :(得分:1)

您可以简单地使用双System.arraycopy - 循环并迭代for / 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_*类型都是如此)。