我有一个bufferedimage,并希望得到一个字节数组的格式r g b a(一个通道每字节)。我该怎么做?
rpppsulh1#
最后,我只是使用java库pngj来加载它,并以rgba格式相应地加载每一行:
for(int j = 0; j < reader.imgInfo.rows;j++) { IImageLine row = reader.readRow(); for(int b = 0; b < reader.imgInfo.cols; b++) { int argb = ch == 3 ? ImageLineHelper.getPixelRGB8(row, b) : ch == 4 ? ImageLineHelper.getPixelARGB8(row, b) : 0xFF000000;
然后我转入rgba:
pixels.write((argb & 0x00FF0000) >> 16); pixels.write((argb & 0x0000FF00) >> 8 ); pixels.write((argb & 0x000000FF) >> 0 );//neatness lol pixels.write((argb & 0xFF000000) >> 24);
euoag5mw2#
从…开始 BufferedImage#getRGB 它回来了 ARGB 价值观 ColorModel 检查imgage的文档。然后使用 ColorModel 要么得到组件( getRed() , getGreen() ,…)或获得 int 组件阵列(例如。 getComponents() ). 或者只是将 getRGB() ,格式如中所述 ColorModel#getRGBdefault .最终,图像(或其光栅数据)可以转换为类型4byte\u abgr,因此光栅数据可以直接使用(只是猜测,我从来没有做过)
BufferedImage#getRGB
ARGB
ColorModel
getRed()
getGreen()
int
getComponents()
getRGB()
ColorModel#getRGBdefault
1dkrff033#
简单的方法是使用 BufferedImage.getRGB (尽管它的名称为rgba值),并转换压缩的 int[] 至 byte[] 四倍长。输入可以是任何文件 ImageIO 可以阅读,一个png就可以了。
BufferedImage.getRGB
int[]
byte[]
ImageIO
public static void main(String[] args) throws IOException { BufferedImage image = ImageIO.read(new File(args[0])); int[] argb = image.getRGB(0, 0, image.getWidth(), image.getHeight(), null, 0, image.getWidth()); byte[] rgba = intARGBtoByteRGBA(argb); } private static byte[] intARGBtoByteRGBA(int[] argb) { byte[] rgba = new byte[argb.length * 4]; for (int i = 0; i < argb.length; i++) { rgba[4 * i ] = (byte) ((argb[i] >> 16) & 0xff); // R rgba[4 * i + 1] = (byte) ((argb[i] >> 8) & 0xff); // G rgba[4 * i + 2] = (byte) ((argb[i] ) & 0xff); // B rgba[4 * i + 3] = (byte) ((argb[i] >> 24) & 0xff); // A } return rgba; }
一个稍微有趣一点的方法,是创建一个 BufferedImage 这是由一个 byte[] 已经是rgba格式,如下所示:
BufferedImage
public static void main(String[] args) throws IOException { BufferedImage image = ImageIO.read(new File(args[0])); ComponentColorModel colorModel = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), true, false, Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE); WritableRaster raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, image.getWidth(), image.getHeight(), image.getWidth() * 4, 4, new int[] {0, 1, 2, 3}, null); // R, G, B, A order BufferedImage imageToo = new BufferedImage(colorModel, raster, colorModel.isAlphaPremultiplied(), null); // This array will be in the same R, G, B, A order byte[] rgbaToo = ((DataBufferByte) raster.getDataBuffer()).getData(); // Draw the image onto the RGBA buffer, which will be updated immediately Graphics2D g = imageToo.createGraphics(); try { g.setComposite(AlphaComposite.Src); g.drawImage(image, 0, 0, null); } finally { g.dispose(); } }
上面哪一个例子更适合使用,取决于用例。如果你只需要一次转换,第一次可能更容易推理和工作得很好。如果需要多次更新缓冲区,第二种方法可能会产生更好的性能。ps:我对所有的测试输入都使用两种方法得到完全相同的结果,除了那些原始输入是灰度的(使用 ColorSpace.CS_GRAY ). 我相信这是一个困扰java2d用户多年的已知问题。。。
ColorSpace.CS_GRAY
3条答案
按热度按时间rpppsulh1#
最后,我只是使用java库pngj来加载它,并以rgba格式相应地加载每一行:
然后我转入rgba:
euoag5mw2#
从…开始
BufferedImage#getRGB
它回来了ARGB
价值观ColorModel
检查imgage的文档。然后使用
ColorModel
要么得到组件(getRed()
,getGreen()
,…)或获得int
组件阵列(例如。getComponents()
). 或者只是将getRGB()
,格式如中所述ColorModel#getRGBdefault
.最终,图像(或其光栅数据)可以转换为类型4byte\u abgr,因此光栅数据可以直接使用(只是猜测,我从来没有做过)
1dkrff033#
简单的方法是使用
BufferedImage.getRGB
(尽管它的名称为rgba值),并转换压缩的int[]
至byte[]
四倍长。输入可以是任何文件ImageIO
可以阅读,一个png就可以了。一个稍微有趣一点的方法,是创建一个
BufferedImage
这是由一个byte[]
已经是rgba格式,如下所示:上面哪一个例子更适合使用,取决于用例。
如果你只需要一次转换,第一次可能更容易推理和工作得很好。
如果需要多次更新缓冲区,第二种方法可能会产生更好的性能。
ps:我对所有的测试输入都使用两种方法得到完全相同的结果,除了那些原始输入是灰度的(使用
ColorSpace.CS_GRAY
). 我相信这是一个困扰java2d用户多年的已知问题。。。