如何从 Java 中的 tiff 检索 16 位像素数据?
我正在编写一个程序,将对 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这种说法是不正确的。
每像素 16 位并不意味着每个红色、绿色或蓝色值 16 位。这意味着 16 位代表 R、G 和 B 值的组合。
因此,16 位短值可以分解为表示一个 像素。
5 位代表红色值。
6 位代表绿色值。
5 位代表蓝色值。
合并后得到 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)
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.
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)