You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java Graphics2D使用fillRect绘制1x1像素时出现异常尺寸方块问题

问题解决:Graphics2D绘制1x1像素矩形出现尺寸不一致的问题

核心原因

问题出在Graphics2D的坐标对齐逻辑和默认渲染规则上:

  • 默认状态下,Graphics2D的坐标是以像素边界为基准,而非像素中心。调用fillRect(x, y, 1, 1)时,实际绘制的是从(x,y)到(x+1,y+1)的矩形,如果这个边界刚好落在两个物理像素之间,渲染器会自动做抗锯齿处理,导致出现看起来像1x2、2x2的模糊矩形。
  • 哪怕关闭抗锯齿,只要坐标没对齐到整数像素的中心,也会出现绘制偏差。

不需要换工具,调整代码就能解决

直接用Graphics2D就能搞定,给你三个可行方案:

方案1:把坐标偏移到像素中心

给x、y坐标各加0.5,让矩形严格对齐到单个像素的中心位置:

g2d.fillRect(x + 0.5f, y + 0.5f, 1, 1);

方案2:关闭抗锯齿并锁定渲染规则

绘制前先设置渲染提示,强制关闭抗锯齿并使用纯 stroke 模式,再用整数坐标绘制:

// 绘制前配置渲染参数
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
// 用原整数坐标绘制
g2d.fillRect(x, y, 1, 1);

方案3:用BufferedImage的setRGB(最可靠的逐像素方式)

如果只是单纯画单个像素,直接用BufferedImage的setRGB方法最稳妥,完全避开Graphics2D的渲染偏差:

// 提前创建对应尺寸的BufferedImage作为画布
BufferedImage image = new BufferedImage(面板宽度, 面板高度, BufferedImage.TYPE_INT_ARGB);
// 给指定坐标的像素设置颜色
image.setRGB(x, y, Color.BLACK.getRGB());
// 最后把整个图像画到JPanel上
g2d.drawImage(image, 0, 0, null);

修改后的最小可复现代码

import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;

public class PixelDrawPanel extends JPanel {
    private BufferedImage pixelBuffer;

    public PixelDrawPanel() {
        setPreferredSize(new Dimension(200, 200));
        pixelBuffer = new BufferedImage(200, 200, BufferedImage.TYPE_INT_RGB);
        // 测试:每隔一个像素画黑色点
        for (int x = 0; x < 200; x += 2) {
            for (int y = 0; y < 200; y += 2) {
                pixelBuffer.setRGB(x, y, Color.BLACK.getRGB());
            }
        }
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g.create();
        // 把缓存的像素图像画到面板上
        g2d.drawImage(pixelBuffer, 0, 0, getWidth(), getHeight(), null);
        g2d.dispose();
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame("逐像素绘制测试");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new PixelDrawPanel());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

内容的提问来源于stack exchange,提问作者Matthew Wright

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 02:53:19