如何从 Java 中的 tiff 检索 16 位像素数据?

发布于 2024-09-06 11:29:17 字数 1428 浏览 9 评论 0原文

我正在编写一个程序,将对 16 位 tiff 图像(5 位红色、6 位绿色、5 位蓝色)进行图像处理,但不幸的是,我编写的代码将图像数据视为 8 位。

为了详细说明代码,我使用 ImageIO 实用程序类将图像读入内存,如下所示:

BufferedImage image = ImageIO.read(imageFile);

然后使用此循环检索像素信息:

Matrix imageMatrix = new Matrix(image.getHeight(), image.getWidth());
Raster raster = image.getData();
double[] pixelColor = new double[4];
for (int x = 0; x < image.getWidth(); x = x + 1) {
    for (int y = 0; y < image.getHeight(); y = y + 1) {
        raster.getPixel(x, y, pixelColor);
        double pixelColorAverage = (pixelColor[0] + pixelColor[1] + pixelColor[2]) / 3.0;
        imageMatrix.set(y, x, pixelColorAverage);
    }
}
return imageMatrix;

问题是raster.getPixel(x, y, PixelColor); 以 8 位形式返回每个 RGB 值(在我的测试图像中,0,0 像素值返回为 24,24,24 [8 位值]当它应该是 6168,6168,6168 [16 位值])。

我尝试将简单的 ImageIO.read(imageFile) 更改为基于另一个 堆栈溢出 tiff 问题

BufferedImage image = ImageIO.read(file);
BufferedImage convertedImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_USHORT_565_RGB);
convertedImage.createGraphics().drawRenderedImage(image, null);

但这一次,raster.getPixel(x, y, PixelColor); 返回 3,6, 3 这也不正确。

基于 ImageIO 支持 tiff 图像并且缓冲图像具有 5-6-5 样式 16 位图像格式的事实,我只能假设这是可能的,但我对我缺少的东西感到困惑。

I'm writing a program that will do image processing on a 16 bit tiff image (5 bit red, 6 bit green, 5 bit blue) but unfortunately the code I've written to do so treats the image data as 8 bit.

To elaborate with code, I read the image into memory with ImageIO utility class like so:

BufferedImage image = ImageIO.read(imageFile);

and later on use this loop to retrieve pixel information:

Matrix imageMatrix = new Matrix(image.getHeight(), image.getWidth());
Raster raster = image.getData();
double[] pixelColor = new double[4];
for (int x = 0; x < image.getWidth(); x = x + 1) {
    for (int y = 0; y < image.getHeight(); y = y + 1) {
        raster.getPixel(x, y, pixelColor);
        double pixelColorAverage = (pixelColor[0] + pixelColor[1] + pixelColor[2]) / 3.0;
        imageMatrix.set(y, x, pixelColorAverage);
    }
}
return imageMatrix;

The problem is that raster.getPixel(x, y, pixelColor); returns each RGB value in 8 bits (in my test image, the 0,0 pixel value is returned as 24,24,24 [8 bit values] when it should be 6168,6168,6168 [16 bit values]).

I've tried changing the simplistic ImageIO.read(imageFile) to the following lines of code based on another stack overflow tiff question:

BufferedImage image = ImageIO.read(file);
BufferedImage convertedImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_USHORT_565_RGB);
convertedImage.createGraphics().drawRenderedImage(image, null);

But this time, the raster.getPixel(x, y, pixelColor); returns 3,6,3 which isn't correct either.

Based on the fact that ImageIO has support for tiff images and buffered image has a 5-6-5 style 16 bit image format, I can only assume this is possible, but I'm stumped as to what I'm missing.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

甜味超标? 2024-09-13 11:29:17

<块引用>

问题是 raster.getPixel(x, y, PixelColor);以 8 位形式返回每个 RGB 值(在我的测试图像中,0,0 像素值返回为 24,24,24 [8 位值],而它应该是 6168,6168,6168 [16 位值])。 p>

这种说法是不正确的。

每像素 16 位并不意味着每个红色、绿色或蓝色值 16 位。这意味着 16 位代表 R、G 和 B 值的组合。

因此,16 位短值可以分解为表示一个 像素。

5 位代表红色值。
6 位代表绿色值。
5 位代表蓝色值。

Red   Green  Blue
----- ------ -----
10111 101010 11100

合并后得到 1011110101011100 二进制或 48476 十进制。

从来没有用 Java 编写过代码,我怀疑您需要使用不同的函数调用来获取您正在寻找的值。也许尝试 [getDataElements][1] 获取相关像素的 16 位值。

请记住,每个像素都是 16 位。您将其与 24 位(每个像素为 8 位)或 32 位(每个像素为 8 位加上 8 位 alpha 值)混淆。

MSDN 中的这篇文章应该可以帮助您从 16 位值中检索 RGB 值。

(您还必须更正您的平均代码。 )

[1]: http://java.sun.com/j2se/1.4.2/docs/api/java/awt/image/Raster.html#getDataElements(int, int, java.lang.Object)

The problem is that raster.getPixel(x, y, pixelColor); returns each RGB value in 8 bits (in my test image, the 0,0 pixel value is returned as 24,24,24 [8 bit values] when it should be 6168,6168,6168 [16 bit values]).

That statement is incorrect.

16 bits per pixel does not mean 16 bits per Red or Green or Blue value. It means 16 bits represents the combined R and G and B values.

So a 16 bit short value can be broken down to represent one pixel.

5 bits represent the Red value.
6 bits represent the Green value.
5 bits represent the Blue value.

Red   Green  Blue
----- ------ -----
10111 101010 11100

Combined you get 1011110101011100 binary or 48476 Decimal.

Never having coded in Java, I would suspect that you would need to use a different function call to get the value you are looking for. Perhaps try [getDataElements][1] to obtain the 16 bit value for the pixel in question.

Rememeber, each pixel is 16 bits. You are confusing that with 24 bit (each pixel is 8 bits) or 32 bit (each pixel is 8 bits plus an 8 bit alpha value.)

This article from MSDN should help you retreive the RGB values from the 16 bit value.

(You will also have to correct your averaging code.)

[1]: http://java.sun.com/j2se/1.4.2/docs/api/java/awt/image/Raster.html#getDataElements(int, int, java.lang.Object)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文