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

问题描述

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

declare @Course table (CourseID nvarchar(4))
declare @CourseStudent table 
                       (
                           CourseID nvarchar(4),Student nvarchar(50)
                       )

insert into @Course values ('SOS1')
insert into @Course values ('MAT3')
insert into @Course values ('FEN2')

insert into @CourseStudent values ('MAT3','Mehmet')
insert into @CourseStudent values ('SOS1','Ahmet')
insert into @CourseStudent values ('MAT3','Ahmet')
insert into @CourseStudent values ('FEN2','Ahmet')
insert into @CourseStudent values ('SOS1','Ali')
insert into @CourseStudent values ('FEN2','Ayse')

select * from @Course

select * from @CourseStudent

Drawing using JPanel paintComponent graphics

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

编辑

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

这是一个例子,-这与我的代码不完全一样,这只是一个给你一个想法的例子-

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(.....);
    }
}

解决方法

通过获取几乎所有面板图形设置并将它们应用于缓冲图像图形,我找到了我的解决方案。在这里,导入的是面板的图形将所有内容按 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),null);
    } else {
        //something along the way
        g.drawOval(.....);
        g.drawLine(.....);
        g.drawOval(.....);
    }
}