java - 在 Java 中以亚像素精度绘制图像

标签 java image graphics2d subpixel

如何在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 版本,但对我来说*,使用 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) 中,您会看到橙色矩形没有完美重叠,并且图像的边缘是实心的。在第二个图像(TexturePaintfillRect)中,您将看到图像的边缘是半透明的,并且橙色矩形完美重叠。

screenshot of running program

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

screenshot of running program on high res screen

关于java - 在 Java 中以亚像素精度绘制图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61480719/

相关文章:

jquery - 如何在鼠标悬停时在两个图像之间滑动?

java - 从java应用程序到elasticsearch的并发输出

java - 如何获取传递给 JNI 的枚举的值

html - CSS图像和文本同时悬停

Java应用程序: drawing a large number of polygons(path2d) taking too long

java - 如何使用 x、y 坐标列表绘制曲线(峰)

java - 我向形状 Arraylist 添加了一个矩形,但该形状不会显示在面板上

java - 我们应该对控制台输出进行单元测试吗?

java - 动态规划-最大切割的杆切割问题和实际解决方案

php - PHP.getimagesize 实际返回什么