繁体   English   中英

写入 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(...)方法是获取/设置单个或一组像素颜色的便捷方法,并且始终在打包的 32 位 ARGB 表示上运行,其中每个 A、R、 G和B样本使用8位(并且颜色模型始终为sRGB),就像您说的TYPE_INT_ARGB一样。 由于这种表示形式的差异,需要将 5 位样本“缩放”为 8 位(并返回)以进行检索/存储,这很慢并且可能会产生舍入/截断错误。

但是,如果您不喜欢,则不需要使用此表示。 相反,您可以直接通过Raster / DataBuffer访问“ ushort ”(Java没有无符号整数类型,因此它们存储为short s):

DataBufferUShort dataBuffer = (DataBufferUShort) image.getRaster().getDataBuffer();
short[] data = dataBuffer.getData(); // Get the backing array

对后备数组的任何更改都将反映在图像中(这是一个“实时”视图)。 此外,访问后备数组很可能会禁用硬件加速的任何机会,但这可能不是问题(它不在您发布的代码中,因为它只读取/写入图像,不显示)。


也就是说,你应该考虑@gpasch 的评论,看看你是否可以只使用TYPE_INT_RGBTYPE_INT_ARGB模型,因为它们通常更容易使用(特别是如果你不喜欢摆弄的话)。

最后一个警告:并非所有文件格式都支持TYPE_USHORT_555_RGB像素布局。 BMP 确实如此。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM