Как я могу получить 16-битные данные пикселей из TIFF в Java? - PullRequest
0 голосов
/ 22 июня 2010

Я пишу программу, которая будет выполнять обработку изображений на 16-битном изображении (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); возвращает каждое значение RGB в 8 битах (в моем тестовом изображении значение 0,0 пикселя возвращается как 24,24,24 [8-битные значения], когда оно должно быть 6168,6168, 6168 [16-битные значения]).

Я пытался изменить упрощенный ImageIO.read(imageFile) на следующие строки кода на основе другого вопроса о переполнении стека :

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-изображения и буферизованное изображение имеет 16-битный формат изображения в стиле 5-6-5, я могу только предположить, что это возможно, но я озадачен тем, что мне не хватает .

1 Ответ

2 голосов
/ 22 июня 2010

Проблема в том, что raster.getPixel (x, y, pixelColor); возвращает каждое значение RGB в 8 битах (в моем тестовом изображении значение 0,0 пикселей возвращается как 24,24,24 [8-битные значения], когда оно должно составлять 6168,6168,6168 [16-битные значения]).

Это утверждение неверно.

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-битное альфа-значение.)

Эта статья из MSDN должна помочь вам получить значения RGB из 16-битного значения.

(Вам также придется исправить свой код усреднения.)

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

...