Рисование изображения в Java с точностью до субпикселя - PullRequest
0 голосов
/ 28 апреля 2020

Как я могу нарисовать изображение в java с точностью до субпикселя?

Я нашел похожие вопросы здесь:

Рисование изображения с использованием точности субпиксельного уровня с использованием Graphics2D

Субпиксельное рендеринг изображений

К сожалению, решения, представленные в ответах, не работают для меня.

public void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D) g;
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
    g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
    g2.translate(50.5, 50.5);
    g2.fillRect(0, 0, 15, 25);
}

Использование g2.translate(50.5, 50.5); заполнение простого прямоугольника с точностью до субпикселя работает хорошо.

public void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D) g;
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
    g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
    g2.translate(50.5, 50.5);
    g2.drawImage(image, 0, 0, null);
}

Однако, когда я использую g2.translate(double x, double y) для рисования изображения с точностью до субпикселя, это не работает. Это точно такой же результат, как и рисование с целыми позициями.

Почему это не работает? Я перевел графику с двойными значениями, но я не вижу никакой интерполяции между пикселями.

1 Ответ

1 голос
/ 28 апреля 2020

Это может зависеть от версии ОС или Java, но для меня * использование TexturePaint (что я считаю хаком) работает:

protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D) g;
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
    g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
    g2.translate(50.5, 50.5);
    // g2.drawImage(image, 0, 0, null); // Original code
    g2.setPaint(new TexturePaint(image, new Rectangle(image.getWidth(), image.getHeight())));
    g2.fillRect(0, 0, image.getWidth(), image.getHeight());

    // Added orange rect for reference, as the difference is hard to spot...
    g2.setPaint(Color.ORANGE);
    g2.fillRect(0, 0, 15, 25);
}

*) на MacOS 10.15, протестировано с Java 8 и 11.

Возможно, вам придется увеличить масштаб, чтобы увидеть разницу, так как она довольно тонкая ... Но на первом изображении (drawImage) вы увидите оранжевый прямоугольник не полностью перекрывается, а края изображения solid. На втором изображении (TexturePaint и fillRect) вы увидите, что края изображения полупрозрачны, а оранжевый прямоугольник идеально перекрывается.

screenshot of running program

Вот то же приложение, работающее на моем внутреннем экране «Retina» в MacBook:

screenshot of running program on high res screen

...