【问题标题】:Convert 2D pixel array into BufferedImage将 2D 像素数组转换为 BufferedImage
【发布时间】:2017-03-05 23:45:26
【问题描述】:

我使用了this SO question 中接受的答案代码。现在,我想转换回 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;
}

但它不起作用,因为它将一维数组作为参数,而不是二维数组。

【问题讨论】:

    标签: java image bufferedimage pixels


    【解决方案1】:

    如果您的 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 ;
        }
    }
    

    【讨论】:

    • FloatCS 类是什么?
    • 对不起,我忘记了。在这里。
    【解决方案2】:

    除了使用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_*类型都是这种情况)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多