ColorModels和WritableRasters如何在java BufferedImages中工作?

时间:2014-07-08 19:16:47

标签: java image bufferedimage

在Java中使用BufferedImage类时,我通常使用带参数int width, int height, int type的构造函数。但是,对于某个应用程序,我想要一个使用ARGB顺序的字节存储颜色数据的图像,这不能以这种方式完成(它只有TYPE_4BYTE_ABGR)。

我找到了以下解决方案,该方法运行良好:

    WritableRaster raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, width, height, 4, null);
    ColorModel colorModel = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), new int[]{8,8,8,8}, true, false, ColorModel.TRANSLUCENT, DataBuffer.TYPE_BYTE);
    img = new BufferedImage(colorModel, raster, false, new Hashtable<>());

我不明白为什么会这样?

虽然 - 我知道WritableRaster是保存图片像素数据的数据结构,但过去我丢失了。这两个对象中的哪一个 - Raster或ColorModel - 确定像素数据的顺序是RGBA?我如何使用(int, int, int)构造函数模拟BufferedImage的(ColorModel, WritableRaster, boolean, HashTable)构造函数中的任何类型?

1 个答案:

答案 0 :(得分:3)

这是方法

Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, width, height, 4, null);

...指定字节顺序。它隐含地这样做,通过假设4个波段,您希望波段偏移为0, 1, 2, 3(对应于RGBA;有关详细信息,请参阅信号源)。对于RGB色彩空间,波段0 =红色,1 =绿色,2 =蓝色,3 =阿尔法。

如果您想要一个不同的订单,您可以使用不同的工厂方法,例如创建一个带有ARGB订单的栅格:

Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, width, height, 
                               width * 4, 4, new int[] {3, 0, 1, 2}, null);

这两种方法都会为您创建PixelInterleavedSampleModel的实例,而这个SampleModel可以真正控制样本订单。

关于BufferedImage(int, int, int)构造函数的工作方式以及如何执行类似的操作,我认为最好的方法就是自己查看源代码。它基本上是一个很大的switch语句,对于每个常量TYPE_*,它会创建一个WritableRaster和一个ColorModel,类似于您上面的操作。

例如:

ColorModel colorModel = ColorModel.getRGBdefault();
WritableRaster raster = colorModel.createCompatibleWritableRaster(width, height);

new BufferedImage(colorModel, raster, colorModel.isAlpahPremultiplied(), null); 

...将创建一个类型为TYPE_INT_ARGB的图像(这种反向查找实际工作的方式有点令人讨厌,但它有效...... :-))。如果BufferedImage中不存在相应类型,则类型将为TYPE_CUSTOM0)。