简体   繁体   English

写入 5-5-5 RGB 并读取 RGBA, BufferedImage

[英]Write in 5-5-5 RGB and read in RGBA, BufferedImage

What I want to do can be explained shortly.我想做什么可以很快解释。 Let's consider a number "x".让我们考虑一个数字“x”。 I operate on an image with TYPE_USHORT_555_RGB.我使用 TYPE_USHORT_555_RGB 对图像进行操作。 I use setRGB(x), save the image.我使用 setRGB(x),保存图像。 Unfortunately Java obligates me to read the resulting image with TYPE_INT_ARGB through getRGB.不幸的是,Java 要求我通过 getRGB 读取带有 TYPE_INT_ARGB 的结果图像。 How can I find my initial x?我怎样才能找到我的初始 x? What worries me the most is that while some numbers read through getRGB are equal between them, this pattern of equivalence is not respected in the source, here's what I mean:最让我担心的是,虽然通过 getRGB 读取的一些数字在它们之间是相等的,但源代码中不尊重这种等价模式,这就是我的意思:

READ: -16777216 -16777216 -16777216 -16777183 -16777117 -16777101 -16777093 -16777101阅读:-16777216 -16777216 -16777216 -16777183 -16777117 -16777101 -16777093 -16777101

SOURCE: 00 00 00 20 66 74 79 70 (in HEX)来源:00 00 00 20 66 74 79 70(十六进制)

The numbers in position 6 and 8 are equal in the read file, but different in the source (74 != 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){}

The BufferedImage.TYPE_USHORT_555_RGB type uses a packed 15 bit (or 16 bit, but the 16th bit is not used) representation for pixels, where each R, G and B sample uses 5 bits. BufferedImage.TYPE_USHORT_555_RGB类型使用打包的 15 位(或 16 位,但未使用第 16 位)表示像素,其中每个 R、G 和 B 样本使用 5 位。

The BufferedImage.getRGB(...) methods on the other hand, are convenience methods for getting/setting the color of a single or a group of pixels, and always operates on a packed 32 bit ARGB representation, where each A, R, G and B sample uses 8 bits (and the color model is always sRGB), just like TYPE_INT_ARGB as you say.另一方面, BufferedImage.getRGB(...)方法是获取/设置单个或一组像素颜色的便捷方法,并且始终在打包的 32 位 ARGB 表示上运行,其中每个 A、R、 G和B样本使用8位(并且颜色模型始终为sRGB),就像您说的TYPE_INT_ARGB一样。 Because of this difference in representation, the 5 bit samples needs to be "scaled" to 8 bits (and back) for retrieval/storage, which is slow and may create rounding/truncating errors.由于这种表示形式的差异,需要将 5 位样本“缩放”为 8 位(并返回)以进行检索/存储,这很慢并且可能会产生舍入/截断错误。

However, you don't need to use this representation if you don't like to.但是,如果您不喜欢,则不需要使用此表示。 Instead, you can access the " ushort " (Java does not have unsigned integral types, so they are stored as short s) directly through the Raster / DataBuffer :相反,您可以直接通过Raster / DataBuffer访问“ ushort ”(Java没有无符号整数类型,因此它们存储为short s):

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

Any changes to the backing array will be reflected in the image (it's a "live" view).对后备数组的任何更改都将反映在图像中(这是一个“实时”视图)。 Also, accessing the backing array will most likely disable any chances of hardware acceleration, but that may not be an issue (it's not in the code you posted, as it only reads/writes the image, no display).此外,访问后备数组很可能会禁用硬件加速的任何机会,但这可能不是问题(它不在您发布的代码中,因为它只读取/写入图像,不显示)。


That said, you should consider @gpasch's comment, and see if you could just use the TYPE_INT_RGB or TYPE_INT_ARGB models, as they are usually easier to work with (especially if you don't like bit twiddling).也就是说,你应该考虑@gpasch 的评论,看看你是否可以只使用TYPE_INT_RGBTYPE_INT_ARGB模型,因为它们通常更容易使用(特别是如果你不喜欢摆弄的话)。

And a final warning: Not all file formats will support the TYPE_USHORT_555_RGB pixel layout.最后一个警告:并非所有文件格式都支持TYPE_USHORT_555_RGB像素布局。 BMP does though. BMP 确实如此。

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

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