【问题标题】:Drawing an Image in Java with Sub Pixel Accuracy在 Java 中以亚像素精度绘制图像
【发布时间】:2020-04-29 09:46:25
【问题描述】:

如何在java中以亚像素精度绘制图像?

我在这里发现了类似的问题:

Drawing an image using sub-pixel level accuracy using Graphics2D

Sub-pixel Image rendering

很遗憾,答案中提供的解决方案对我不起作用。

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)以亚像素精度绘制图像时,它不起作用。这与使用整数位置绘制的结果完全相同。

为什么这不起作用?我用双精度值翻译了图形,但没有看到像素之间的任何插值。

【问题讨论】:

  • 我不确定您使用的是哪个版本的 Java。 drawImage 的签名应该是 drawImage(BufferedImage img, BufferedImageOp op, int x, int y) afaik。 - 更正:两个签名似乎存在于不同的版本中。你用的是什么JDK?
  • 我使用的是 Java 13。我也尝试了drawImage(BufferedImage img, BufferedImageOp op, int x, int y),但我仍然看不到像素之间的任何插值。
  • 一种可行的方法是使用您的图像设置TexturePaint,并使用它来填充与原始图像相同大小的矩形(并使用半像素偏移,如您的第一个代码示例)。
  • 对不起,我还是没有看到任何插值 =(
  • 嗯,对我有用.. MacOS 上的 Java 8u181。不确定您希望看到什么样的插值...

标签: java image graphics2d subpixel


【解决方案1】:

这可能取决于操作系统或 Java 版本,但对我来说*,使用 TexturePaint(我认为这有点 hack)是可行的:

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) 中,您会看到橙色矩形没有完美重叠,并且边缘图像是坚实的。在第二张图片(TexturePaintfillRect)中,您会看到图片的边缘是半透明的,橙色矩形完全重叠。

这是在我的 MacBook 内部“视网膜”屏幕上运行的相同应用程序:

【讨论】:

  • 它可以工作 AAAAAAA 非常感谢,当我最初从您的评论中尝试它时,我仍然非常不确定为什么它不起作用,但它现在可以在 Java 8 和 Java 13 上运行,谢谢!
猜你喜欢
  • 2012-01-30
  • 1970-01-01
  • 1970-01-01
  • 2016-04-22
  • 2011-10-26
  • 1970-01-01
  • 2014-11-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多