亚像素渲染

约翰·汉森

我正在尝试并且以失败告终,使用子像素定位在Java中渲染2D形状。以下是失败的尝试(暂时忽略scaleAffineTransform):

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;

public class TestFrame extends Frame {
    private static final int D = 64;

    public static void main(String args[]) {
        new TestFrame(D, D);
    }

    private final Insets ins;
    private final double scale = 1;

    TestFrame(int w, int h) {
        ins = getInsets();
        final Dimension dim = new Dimension(w + ins.left + ins.right, h + ins.top + ins.bottom);

        pack();

        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent we) {
                dispose();
            }
        });

        setSize(dim);
        setLocationRelativeTo(null);
        setBackground(Color.BLACK);
        setVisible(true);
        repaint();
    }

    @Override
    public void paint(Graphics gfx) {
        super.paint(gfx);
        final Graphics2D g2d = (Graphics2D)gfx;
        g2d.setTransform(new AffineTransform(1.0/scale, 0.0, 0.0, 1.0/scale, ins.left, ins.top));
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setStroke(new BasicStroke((float)scale));
        g2d.setColor(Color.WHITE);

        for (double deg = 0; deg < 90.0; deg += 2.0) {
            final double rad = deg / 180.0 * Math.PI;
            final double x1 = Math.cos(rad) * D * scale;
            final double y1 = Math.sin(rad) * D * scale;
            final double x2 = Math.cos(rad) * (D - 4.0) * scale;
            final double y2 = Math.sin(rad) * (D - 4.0) * scale;
            g2d.draw(new Line2D.Double(x1, y1, x2, y2));
        }
    }
}

这将产生以下输出:

渲染图

线应均匀分布,但如您所见,它们并不是均匀分布的。我的猜测是起点和终点都四舍五入到最接近的像素。

关于SO的建议解决方案提到使用Line2D.Double(我已经在做,显然是行不通的),或使用AffineTransform缩小比例。如果scale将代码示例中变量更改为100,则会以更高的比例绘制线条,然后根据建议使用变换将其缩小。这也对最终图像没有影响。

我究竟做错了什么?

约翰·汉森

解决方案设置为呈现提示之一:

g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);

引用Javadocs

笔划归一化控制提示值-几何应保持不变,并以亚像素精度呈现。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章