在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)
构造函数中的任何类型?
答案 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_CUSTOM
(0
)。