通过 paintComponent 和 Buffered Image 在 JPanel 上绘图的区别

Difference between drawing on JPanel via paintComponent and Buffered Image

我尝试了两种不同的绘制相同形状的方法,第一个图像是通过覆盖 JPanel 的 paintComponent(Graphics g) 方法并使用 g.drawOval(..) 等绘制的, 第二幅图像是通过创建缓冲图像并使用缓冲图像的图形在其上绘制来绘制的。如何在两种方法上实现相同的渲染质量?我尝试过使用许多不同的渲染提示,但其中 none 给出了相同的质量。我也尝试过使用内核和过滤来锐化,仍然不能。

private void createImage() {
        image = new BufferedImage(IMG_SIZE, IMG_SIZE, BufferedImage.TYPE_INT_ARGB);
        Graphics2D gr = image.createGraphics();

        gr.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        gr.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        gr.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
        //something along the way
        gr.drawOval(.....);
        gr.drawLine(.....);
        gr.drawOval(.....);

        panel.repaint();
        gr.dispose();
}



public void paintComponent(Graphics g) {
    super.paintComponent(g);
    setBackground(backgroundColor);
    if (USE_BUFFERED_IMAGE) {
        g.drawImage(image, startX, startY, null);
    } else {
        //something along the way
        g.drawOval(.....);
        g.drawLine(.....);
        g.drawOval(.....);
    }
}

Drawing using JPanel paintComponent graphics

Drawing using Buffered Image graphics then it is drawn on Jpanel via drawimage

编辑

我通过获取面板图形的几乎所有设置并将它们应用于缓冲图像图形找到了我的解决方案。而不是仅使用相同的渲染提示或“最小可重现示例”方法。在这里,导入的是面板的图形将所有内容缩放 1.25,然后在显示在面板上之前缩小到原始大小。

这里有一个例子,-这不是我的代码,这只是一个给你一个想法的例子-

private void createImages(Paint paint, RenderingHints hints,
                         AffineTransform transform, Stroke stroke,
                        Composite composite, GraphicsConfiguration config ){

        image = config.createCompatibleImage(IMG_SIZE, IMG_SIZE, 
                BufferedImage.TYPE_INT_ARGB);
        Graphics2D gr = image.createGraphics();
        // same options
        gr.setPaint(paint);
        gr.setRenderingHints(hints);
        gr.setTransform(transform);
        gr.setStroke(stroke);
        gr.setComposite(composite);

        //something along the way
        gr.drawOval(.....);
        gr.drawLine(.....);
        gr.drawOval(.....);

        panel.repaint();
        gr.dispose();
}



public void paintComponent(Graphics g) {
    super.paintComponent(g);
    setBackground(backgroundColor);
    if (USE_BUFFERED_IMAGE) {
       
        Graphics2D g2 = (Graphics2D)g;
        createImages(g2.getPaint(), g2.getRenderingHints(),g2.getTransform(),
                     g2.getStroke(),g2.getComposite(), g2.getDeviceConfiguration());
         //scaling down is important because your drawings get scaled to 1.25
         // by panels graphics' transformation
         g.drawImage(image, startX, startY,(int)(IMG_SIZE*0.8),(int)(IMG_SIZE*0.8),  null);
    } else {
        //something along the way
        g.drawOval(.....);
        g.drawLine(.....);
        g.drawOval(.....);
    }
}

我通过获取面板图形的几乎所有设置并将它们应用于缓冲图像图形找到了我的解决方案。在这里,导入的是面板的图形按 1.25 缩放所有内容,然后在显示在面板上之前缩小到原始大小。

这里有一个例子,-这不是我的代码,这只是一个给你一个想法的例子-

private void createImages(Paint paint, RenderingHints hints,
                         AffineTransform transform, Stroke stroke,
                        Composite composite, GraphicsConfiguration config ){

        image = config.createCompatibleImage(IMG_SIZE, IMG_SIZE, 
                BufferedImage.TYPE_INT_ARGB);
        Graphics2D gr = image.createGraphics();
        // same options
        gr.setPaint(paint);
        gr.setRenderingHints(hints);
        gr.setTransform(transform);
        gr.setStroke(stroke);
        gr.setComposite(composite);

        //something along the way
        gr.drawOval(.....);
        gr.drawLine(.....);
        gr.drawOval(.....);

        panel.repaint();
        gr.dispose();
}



public void paintComponent(Graphics g) {
    super.paintComponent(g);
    setBackground(backgroundColor);
    if (USE_BUFFERED_IMAGE) {
       
        Graphics2D g2 = (Graphics2D)g;
        createImages(g2.getPaint(), g2.getRenderingHints(),g2.getTransform(),
                     g2.getStroke(),g2.getComposite(), g2.getDeviceConfiguration());
         //scaling down is important because your drawings get scaled to 1.25
         // by panels graphics' transformation
         g.drawImage(image, startX, startY,(int)(IMG_SIZE*0.8),(int)(IMG_SIZE*0.8),  null);
    } else {
        //something along the way
        g.drawOval(.....);
        g.drawLine(.....);
        g.drawOval(.....);
    }
}