Использование JAI для поворота изображения в оттенках серого увеличивает контраст - PullRequest
2 голосов
/ 17 мая 2010

Я пытаюсь использовать JAI для выполнения задачи поворота изображения. Я могу заставить это работать без проблем. Однако на изображении наблюдается значительная потеря полутонов. Изображение можно повернуть в фотошопе без этого недостатка контраста.

Пожалуйста, посмотрите следующие 3 изображения, сложенные рядом друг с другом, чтобы понять, что я имею в виду;

http://imgur.com/SYPhZ.jpg

Верхнее изображение - оригинал, среднее повернуто в фотошопе, чтобы доказать, что это можно сделать, а нижнее - из результата моего кода.

Чтобы увидеть реальные изображения, пожалуйста, смотрите здесь;

Перед поворотом: http://imgur.com/eiAOO.jpg После поворота: http://imgur.com/TTUKS.jpg

Вы можете увидеть проблему наиболее четко, если загрузить изображения в две разные вкладки и пролистать их.

С точки зрения кода, я загружаю изображение следующим образом:

  public void testIt() throws Exception {

    File source = new File("c:\\STRIP.jpg");
    FileInputStream fis = new FileInputStream(source);
    BufferedImage sourceImage = ImageIO.read(fis);
    fis.close();

    BufferedImage rotatedImage = doRotate(sourceImage, 15);
    FileOutputStream output = new FileOutputStream("c:\\STRIP_ROTATED.jpg");
    ImageIO.write(rotatedImage, "JPEG", output);

}

и затем здесь функция поворота;

 public BufferedImage doRotate(BufferedImage input, int angle) {
    int width = input.getWidth();
    int height = input.getHeight();


    double radians = Math.toRadians(angle / 10.0);

    // Rotate about the input image's centre
    AffineTransform rotate = AffineTransform.getRotateInstance(radians, width / 2.0, height / 2.0);

    Shape rect = new Rectangle(width, height);

    // Work out how big the rotated image would be..
    Rectangle bounds = rotate.createTransformedShape(rect).getBounds();

    // Shift the rotated image into the centre of the new bounds
    rotate.preConcatenate(
            AffineTransform.getTranslateInstance((bounds.width - width) / 2.0, (bounds.height - height) / 2.0));

    BufferedImage output = new BufferedImage(bounds.width, bounds.height, input.getType());
    Graphics2D g2d = (Graphics2D) output.getGraphics();

    // Fill the background with white
    g2d.setColor(Color.WHITE);
    g2d.fill(new Rectangle(width, height));

    RenderingHints hints = new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
    hints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

    g2d.setRenderingHints(hints);
    g2d.drawImage(input, rotate, null);

    return output;
}

1 Ответ

1 голос
/ 17 мая 2010

Это, по-видимому, ошибка в JAI, существовавшая некоторое время:

Самое раннее упоминание о том, что мне удалось найти эту проблему , появляется здесь . Эта оригинальная статья указывает на старую проблему jai-core здесь . Прочитав это разрешение, кажется, что есть корневая ошибка, которая все еще открыта и описана здесь .

Независимо от того, относится ли вся эта детективная работа к вашему приложению, может быть возможно создать цветовое пространство, которое является более терпимым, чем стандартное значение, которое JAI использует для вашего тестового кода.

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

...