Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/346.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从BuffereImage Java获取RGBA字节数组_Java_Image_Png_Bufferedimage - Fatal编程技术网

从BuffereImage Java获取RGBA字节数组

从BuffereImage Java获取RGBA字节数组,java,image,png,bufferedimage,Java,Image,Png,Bufferedimage,我有一个BuffereImage,希望得到一个字节数组,格式为R G B a,每个字节一个通道。如何执行此操作?从BufferedImagegetRGB开始,它返回ARGB值,无论imgage的颜色模型如何-检查其颜色 然后使用ColorModel的默认实例获取组件getRed、getGreen、。。。或者获取组件的int数组,例如getComponents。或者只拆分getRGB返回的值,格式在ColorModelgetRGBdefault中描述 最终,图像或其光栅数据可以转换为类型_4BYT

我有一个BuffereImage,希望得到一个字节数组,格式为R G B a,每个字节一个通道。如何执行此操作?

从BufferedImagegetRGB开始,它返回ARGB值,无论imgage的颜色模型如何-检查其颜色

然后使用ColorModel的默认实例获取组件getRed、getGreen、。。。或者获取组件的int数组,例如getComponents。或者只拆分getRGB返回的值,格式在ColorModelgetRGBdefault中描述

最终,图像或其光栅数据可以转换为类型_4BYTE_ABGR,因此光栅数据可以直接使用只是猜测,我从未这样做过

从BufferedImagegetRGB开始,它返回ARGB值,无论图像的颜色模型如何-检查其颜色

然后使用ColorModel的默认实例获取组件getRed、getGreen、。。。或者获取组件的int数组,例如getComponents。或者只拆分getRGB返回的值,格式在ColorModelgetRGBdefault中描述

最终,图像或其光栅数据可以转换为类型_4BYTE_ABGR,因此光栅数据可以直接使用只是一个猜测,我从来没有这样做过。简单的方法是使用BufferedImage.getRGB,尽管它的名称为ARGB值,但它可以将压缩的int[]转换为byte[]四倍长。输入可以是ImageIO可以读取的任何文件,PNG可以正常工作

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;
}
上面哪一个例子更适合使用,取决于用例

如果您只需要一次转换,那么第一次转换可能更容易推理,而且效果很好

如果需要多次更新缓冲区,第二种方法可能会产生更好的性能

PS:对于我所有的测试输入,我使用两种方法得到完全相同的结果,除了那些使用ColorSpace.CS\u GRAY的原始结果是灰度的。我相信这是一个困扰Java2D用户多年的已知问题…

简单的方法是使用BufferedImage.getRGB,尽管它的名称为ARGB值,但它会将压缩的int[]转换为字节[]四倍长。输入可以是ImageIO可以读取的任何文件,PNG可以正常工作

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;
}
上面哪一个例子更适合使用,取决于用例

如果您只需要一次转换,那么第一次转换可能更容易推理,而且效果很好

如果需要多次更新缓冲区,第二种方法可能会产生更好的性能


PS:对于我所有的测试输入,我使用两种方法得到完全相同的结果,除了那些使用ColorSpace.CS\u GRAY的原始结果是灰度的。我相信这是一个困扰Java2D用户多年的已知问题…

最终我只是使用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;

最后,我只是使用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;

这只是获取png文件中的字节我想知道,这是你需要的吗?不,我只想得到RGBA数据,别的什么都不想。我需要以这种格式从光栅中获取像素,但是对于不同的图像,像素格式都是不同的。我只需要一种方法,可以在一个抽象中实现这一点。这是LWJGL吗?这是我几年前的回答。应该直接插入代码。MadProgrammer,从2014年开始->这只是获取png文件中的字节我想知道,这是你需要的吗?不,我只想得到RGBA数据,别的什么都不想。我需要以这种格式从光栅中获取像素,但是对于不同的图像,像素格式都是不同的。我只需要一种方法,可以在一个抽象中实现这一点。这是LWJGL吗?这是我几年前的回答。应该直接插入代码。MadProgrammer,从2014年开始->我加载了一个PNG文件,但是颜色模型根据文件的不同而不同,并且像素格式并不总是32位/像素r g b a,因此会产生错误。我更新了代码示例,使用ImageIO.read。。。而不是新的BuffereImage,以澄清用法。您应该能够使用PNG或任何其他文件格式,只要ImageIO.read。。。我能看懂它。图像的颜色模型对BuffereImage.getRGB不重要。。。它总是在sRGB颜色空间中返回压缩的32位ARGB值。您的方法有效,但我在某些图像上仍遇到一些错误,因此我决定尝试另一个png库pngj,该库有效,但谢谢!我不知道你说的是什么错误,你从来没有发布过它,也没有导致问题的示例文件。这听起来像是一个与int ARGB->4字节RGBA转换完全无关的问题。。。我加载了一个PNG文件,但是颜色模型根据文件的不同而不同,而且像素格式并不总是32位/像素r g b a,所以会出现错误。我更新了代码示例,使用ImageIO.read。。。而不是新的BuffereImage,以澄清用法。你是谁
应该能够使用PNG或任何其他文件格式,只要ImageIO.read。。。我能看懂它。图像的颜色模型对BuffereImage.getRGB不重要。。。它总是在sRGB颜色空间中返回压缩的32位ARGB值。您的方法有效,但我在某些图像上仍遇到一些错误,因此我决定尝试另一个png库pngj,该库有效,但谢谢!我不知道你说的是什么错误,你从来没有发布过它,也没有导致问题的示例文件。这听起来像是一个与int ARGB->4字节RGBA转换完全无关的问题。。。但是我很高兴它能为你工作。但是BuffereImage不是那种颜色模式。我更新了答案-图像模式不重要。重要的是用于返回值的模型。我试过了,它有时会说“每个像素有多个组件”非法参数?你应该显示你在问题中尝试了什么,这有点含糊不清,但BuffereImage不在该颜色模型中。我更新了答案-图像模型不重要。重要的是用于返回值的模型。我试过了,它有时会说“每像素有多个组件”非法参数?你应该展示你在问题中尝试了什么,这有点含糊不清