如何无间隙地逐像素绘制? Java 摇摆
How do I render pixel by pixel drawing without gaps? Java Swing
在 Java 中,我正在使用 JFrame
逐个像素地绘制一些分形,但是 drawLine
采用 int
个参数并且有些像素我不能抵达。例如,如果我画一条线:
g.drawLine(0,100,500,100);
然后它画了一条实线。如果我将它绘制为一系列像素:
for (int i=0; i<500;i++) g.drawLine(i,100,i,100);
然后画一条虚线:两个像素,跳过一个,两个像素,跳过一个,
等等
如何修复它,使我的分形花边看起来不像是隔着纱门看到的? (4/9 像素填充)。
我真的很希望框架放弃 1.5 倍的缩放比例,并像我被引导相信的那样绘制整数,但我也会采取一些其他解决方案,包括新的图形包,甚至学习一门具有更好图形控制的新语言。
Java 版本是我上个月下载的最新版本,运行 在 Windows 10 计算机上通过命令行下载。
示例输出,您可以看到 'screen door':
最小工作示例:
import java.util.*;
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
public class Example extends JPanel{
public void paint(Graphics g){
g.setColor(new Color(0,0,0));
for(int i=0;i<100;i++)
for(int j=0;j<100;j++)
g.drawLine(i,j,i,j);
}
public static void main(String[] args) {
JFrame f = new JFrame("Inversion");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(new Example());
f.setSize(200, 200);
f.setLocation(350, 25);
f.setVisible(true);
}
}
输出:
我建议不要使用 Graphics#drawLine
进行像素完美绘画。您提供的坐标被解释为位于您定位的“像素”的左上角(引号中的像素,因为 ui 在 gui space 中缩放单个像素可能实际上是一个 2x2 的屏幕像素网格或更多)。
笔划宽度为 1
时,假设您绘制的是水平线或垂直线,则您绘制的线条将位于两个像素“之间”。这将根据屏幕分辨率和抗锯齿设置产生不同的结果。
而是使用 Graphics#fillRect
例如而不是
g.drawLine(x1, y, x2, y);
使用:
g.fillRect(x1, y, x2 - x1, 1);
绘制单个像素
g.drawLine(x, y, x, y);
绝对是不正确的做法。对于 Graphics
对象,这看起来像一条没有长度的线。如果它实际绘制它完全依赖于 platform/screen/etc 中可能不一致的实现。
而是绘制一个具有 width
和 height
的 1
:
的矩形
g.fillRect(x, y, 1, 1);
在 Java 中,我正在使用 JFrame
逐个像素地绘制一些分形,但是 drawLine
采用 int
个参数并且有些像素我不能抵达。例如,如果我画一条线:
g.drawLine(0,100,500,100);
然后它画了一条实线。如果我将它绘制为一系列像素:
for (int i=0; i<500;i++) g.drawLine(i,100,i,100);
然后画一条虚线:两个像素,跳过一个,两个像素,跳过一个, 等等
如何修复它,使我的分形花边看起来不像是隔着纱门看到的? (4/9 像素填充)。
我真的很希望框架放弃 1.5 倍的缩放比例,并像我被引导相信的那样绘制整数,但我也会采取一些其他解决方案,包括新的图形包,甚至学习一门具有更好图形控制的新语言。
Java 版本是我上个月下载的最新版本,运行 在 Windows 10 计算机上通过命令行下载。
示例输出,您可以看到 'screen door':
最小工作示例:
import java.util.*;
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
public class Example extends JPanel{
public void paint(Graphics g){
g.setColor(new Color(0,0,0));
for(int i=0;i<100;i++)
for(int j=0;j<100;j++)
g.drawLine(i,j,i,j);
}
public static void main(String[] args) {
JFrame f = new JFrame("Inversion");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(new Example());
f.setSize(200, 200);
f.setLocation(350, 25);
f.setVisible(true);
}
}
输出:
我建议不要使用 Graphics#drawLine
进行像素完美绘画。您提供的坐标被解释为位于您定位的“像素”的左上角(引号中的像素,因为 ui 在 gui space 中缩放单个像素可能实际上是一个 2x2 的屏幕像素网格或更多)。
笔划宽度为 1
时,假设您绘制的是水平线或垂直线,则您绘制的线条将位于两个像素“之间”。这将根据屏幕分辨率和抗锯齿设置产生不同的结果。
而是使用 Graphics#fillRect
例如而不是
g.drawLine(x1, y, x2, y);
使用:
g.fillRect(x1, y, x2 - x1, 1);
绘制单个像素
g.drawLine(x, y, x, y);
绝对是不正确的做法。对于 Graphics
对象,这看起来像一条没有长度的线。如果它实际绘制它完全依赖于 platform/screen/etc 中可能不一致的实现。
而是绘制一个具有 width
和 height
的 1
:
g.fillRect(x, y, 1, 1);