写入5-5-5 RGB,读入RGBA,BufferedImage
Write in 5-5-5 RGB and read in RGBA, BufferedImage
我想做的事情可以很快解释。让我们考虑一个数字 "x"。我用 TYPE_USHORT_555_RGB 对图像进行操作。我使用 setRGB(x),保存图像。不幸的是 Java 迫使我通过 getRGB 使用 TYPE_INT_ARGB 读取生成的图像。我怎样才能找到我的初始 x?
最让我担心的是,虽然通过 getRGB 读取的一些数字在它们之间是相等的,但这种等价模式在源代码中没有得到尊重,这就是我的意思:
阅读:
-16777216
-16777216
-16777216
-16777183
-16777117
-16777101
-16777093
-16777101
来源:
00 00 00 20 66 74 79 70(十六进制)
读取文件中第6位和第8位的数字相等,但源文件中不同(74 != 70)
//Write part:
BufferedImage img=new BufferedImage(8, 1, BufferedImage.TYPE_USHORT_555_RGB);
for(int q=0;q<8;q++)
img.setRGB(q,0,realVal[q]);//realVal contains the hex values
File f= new File("randomfile.bmp");
ImageIO.write(img, "bmp", f);
//Read part:
BufferedImage img;
try{
img=ImageIO.read(new File("randomfile.bmp"));
for(int q=0;q<8;q++)
System.out.println(img.getRGB(q,0));
}catch(Exception e){}
BufferedImage.TYPE_USHORT_555_RGB
类型使用打包的 15 位(或 16 位,但未使用第 16 位)表示像素,其中每个 R、G 和 B 样本使用 5 位。
另一方面,BufferedImage.getRGB(...)
方法是便捷方法,用于getting/setting单个或一组像素的颜色,并且始终运行在打包的 32 位 ARGB 表示中,每个 A、R、G 和 B 样本使用 8 位(并且颜色模型始终是 sRGB),就像你说的 TYPE_INT_ARGB
一样。由于这种表示上的差异,对于 retrieval/storage,5 位样本需要 "scaled" 到 8 位(并返回),这很慢并且可能会产生 rounding/truncating 错误。
但是,如果您不喜欢,则不需要使用此表示。相反,您可以直接通过 Raster
/[=17 访问“ushort
”(Java 没有无符号整数类型,因此它们存储为 short
s) =]:
DataBufferUShort dataBuffer = (DataBufferUShort) image.getRaster().getDataBuffer();
short[] data = dataBuffer.getData(); // Get the backing array
对支持阵列的任何更改都将反映在图像中(这是一个 "live" 视图)。此外,访问支持数组很可能会禁用任何硬件加速的机会,但这可能不是问题(它不在您发布的代码中,因为它只 reads/writes 图像,没有显示)。
也就是说,您应该考虑@gpasch 的评论,看看是否可以只使用 TYPE_INT_RGB
或 TYPE_INT_ARGB
模型,因为它们通常更容易使用(尤其是如果您不我不喜欢玩弄)。
最后警告:并非所有文件格式都支持 TYPE_USHORT_555_RGB
像素布局。 BMP 确实如此。
我想做的事情可以很快解释。让我们考虑一个数字 "x"。我用 TYPE_USHORT_555_RGB 对图像进行操作。我使用 setRGB(x),保存图像。不幸的是 Java 迫使我通过 getRGB 使用 TYPE_INT_ARGB 读取生成的图像。我怎样才能找到我的初始 x? 最让我担心的是,虽然通过 getRGB 读取的一些数字在它们之间是相等的,但这种等价模式在源代码中没有得到尊重,这就是我的意思:
阅读: -16777216 -16777216 -16777216 -16777183 -16777117 -16777101 -16777093 -16777101
来源: 00 00 00 20 66 74 79 70(十六进制)
读取文件中第6位和第8位的数字相等,但源文件中不同(74 != 70)
//Write part:
BufferedImage img=new BufferedImage(8, 1, BufferedImage.TYPE_USHORT_555_RGB);
for(int q=0;q<8;q++)
img.setRGB(q,0,realVal[q]);//realVal contains the hex values
File f= new File("randomfile.bmp");
ImageIO.write(img, "bmp", f);
//Read part:
BufferedImage img;
try{
img=ImageIO.read(new File("randomfile.bmp"));
for(int q=0;q<8;q++)
System.out.println(img.getRGB(q,0));
}catch(Exception e){}
BufferedImage.TYPE_USHORT_555_RGB
类型使用打包的 15 位(或 16 位,但未使用第 16 位)表示像素,其中每个 R、G 和 B 样本使用 5 位。
另一方面,BufferedImage.getRGB(...)
方法是便捷方法,用于getting/setting单个或一组像素的颜色,并且始终运行在打包的 32 位 ARGB 表示中,每个 A、R、G 和 B 样本使用 8 位(并且颜色模型始终是 sRGB),就像你说的 TYPE_INT_ARGB
一样。由于这种表示上的差异,对于 retrieval/storage,5 位样本需要 "scaled" 到 8 位(并返回),这很慢并且可能会产生 rounding/truncating 错误。
但是,如果您不喜欢,则不需要使用此表示。相反,您可以直接通过 Raster
/[=17 访问“ushort
”(Java 没有无符号整数类型,因此它们存储为 short
s) =]:
DataBufferUShort dataBuffer = (DataBufferUShort) image.getRaster().getDataBuffer();
short[] data = dataBuffer.getData(); // Get the backing array
对支持阵列的任何更改都将反映在图像中(这是一个 "live" 视图)。此外,访问支持数组很可能会禁用任何硬件加速的机会,但这可能不是问题(它不在您发布的代码中,因为它只 reads/writes 图像,没有显示)。
也就是说,您应该考虑@gpasch 的评论,看看是否可以只使用 TYPE_INT_RGB
或 TYPE_INT_ARGB
模型,因为它们通常更容易使用(尤其是如果您不我不喜欢玩弄)。
最后警告:并非所有文件格式都支持 TYPE_USHORT_555_RGB
像素布局。 BMP 确实如此。