Программа не может отображать определенные изображения в градациях серого? - PullRequest
0 голосов
/ 09 мая 2018

Я пытаюсь создать программу, которая применяет фильтр оттенков серого к выбранному изображению для моего урока информатики.Я нашел следующий код в руководстве, он демонстрирует алгоритм оттенков серого, в котором значения R, G и B каждого пикселя в изображении заменяются средним значением RGB.

import java.io.File;
import java.io.IOException;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;

public class Grayscale{
public static void main(String args[])throws IOException{
BufferedImage img = null;
File f = null;

//read image
try{
  f = new File("D:\\Image\\Taj.jpg");
  img = ImageIO.read(f);
}catch(IOException e){
  System.out.println(e);
}

//get image width and height
int width = img.getWidth();
int height = img.getHeight();

//convert to grayscale
for(int y = 0; y < height; y++){
  for(int x = 0; x < width; x++){
    int p = img.getRGB(x,y);

    int a = (p>>24)&0xff;
    int r = (p>>16)&0xff;
    int g = (p>>8)&0xff;
    int b = p&0xff;

    //calculate average
    int avg = (r+g+b)/3;

    //replace RGB value with avg
    p = (a<<24) | (avg<<16) | (avg<<8) | avg;

    img.setRGB(x, y, p);
  }
}

//write image
try{
  f = new File("D:\\Image\\Output.jpg");
  ImageIO.write(img, "jpg", f);
}catch(IOException e){
  System.out.println(e);
}
}//main() ends here
}//class ends here

ПроблемаЭто означает, что программа не применяет фильтр градаций серого к определенным изображениям.Например, код может правильно применить фильтр к этому изображению, создав изображение в градациях серого .Но следующее изображение радуги выглядит как это с примененным к нему фильтром оттенков серого.

Почему красный, зеленый, синий и розовый цвета отображаются с фильтромнад ним?Насколько я понимаю, когда значения R, G и B пикселя совпадают, должен быть создан серый цвет?

1 Ответ

0 голосов
/ 09 мая 2018

Из JavaDoc BufferedImage.setRGB()

"Устанавливает для пикселя в этом BufferedImage указанное значение RGB. Предполагается, что пиксель находится в цветовой модели RGB по умолчанию, TYPE_INT_ARGB и цветовом пространстве sRGB по умолчанию. Для изображений с IndexColorModel индекс с индексом выбран ближайший цвет. "

Чтобы решить эту проблему, создайте новый BufferedImage с требуемым цветовым пространством, такими же размерами, что и исходное изображение, и запишите в него пиксели, а не обратно в исходный BufferedImage.

BufferedImage targetImage = new BufferedImage(img.getWidth(),
        img.getHeight(),  BufferedImage.TYPE_3BYTE_BGR);

вместо этого запишите пиксели к этому изображению ...

targetImage.setRGB(x, y, p);

затем сохраните это новое изображение ..

ImageIO.write(targetImage, "jpg", f);

Как примечание, более точный способ преобразования цветного изображения в шкалу серого состоит в преобразовании пикселей RGB в цветовое пространство YUV и последующем использовании значения яркости, а не среднего значения RGB. Это потому, что яркость R G и B взвешены по-разному.

...