如何使渐变背景颜色更平滑

时间:2012-09-03 18:12:32

标签: java swing background gradient java-2d

将GradientPaint用于渐变背景颜色并不总是令人满意,尤其是在某些尺寸下。例如这段代码:

public class TestPanel extends JPanel {

    protected void paintComponent( Graphics g ) {
        Graphics2D g2d = (Graphics2D) g;
        int w = getWidth();
        int h = getHeight();
        Color color1 = Color.BLACK;
        Color color2 = Color.GRAY;
        GradientPaint gp = new GradientPaint(0, 0, color1, 0, h, color2);
        g2d.setPaint(gp);
        g2d.fillRect(0, 0, w, h);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame frame = new JFrame();
                TestPanel panel = new TestPanel();
                frame.add(panel);
                frame.setSize(200,200);
                frame.setLocationRelativeTo(null);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setVisible(true);
            }
        });
    }
}

产生以下内容:

non-cyclic

循环版看起来比这更糟糕:

cyclic

如何使渐变看起来更平滑(在两种情况下)?

编辑:

似乎(至少部分地)是监视器问题。我的上网本(1024 x 600,真彩色32位)的渐变色看起来很糟糕,而我的台式机(1280 x 1024,真彩色32位)看起来好多了。但即使使用桌面显示器,结果仍然不是那么顺利。

两者都在使用Java Version 6 Update 33。

这是否意味着应用程序在使用更高分辨率查看时只应使用渐变背景?

编辑2:

无论如何,对于那些面临类似问题或者只是对此感兴趣的人,我认为渐变颜色看起来更平滑的唯一解决方案就是更高的分辨率(假设显示器已经设置为真彩色) - 其中不是一个真正的解决方案。就像我在评论中所说的那样,我认为1024 x 600分辨率对于简单的黑到灰渐变色就足够了,但似乎我错了。当在具有支持更高分辨率的显示器的计算机上运行相同的代码时,渐变看起来更好,例如通过我的桌面显示器,1280 x 1024.不幸的是,我没有更好的分辨率选项,但我相信它看起来会更平滑。我还注意到我上传的两张图片(从我的上网本中拍摄)当通过更好的显示器观看时,这些相同的图像看起来更平滑......所以它必须只是分辨率。

由于没有解决方案,我认为使用特定渐变步骤的唯一方法总是看起来很流畅(比如黑色到灰色,即使在较低分辨率下看起来看起来很糟糕)也是要进行gui程序测试对于启动时的解决方案,并选择显示适当的渐变,但我不确定它是否值得。使用较少的梯度步骤只是一种妥协。

由于缺乏更多/更好的回应,我接受了使用预先抖动的图像作为答案。

2 个答案:

答案 0 :(得分:2)

我看到你的图像,但无法重现条带。你的显示器是否设置为TrueColor?您使用的是最新的Java版本吗?无论如何,以下行可能会有所帮助:

g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);

编辑:似乎Java中的TrueColor渐变不支持抖动,即使你没有足够的灰色阴影......一些想法:

  • 使用一些颜色
  • 使用预抖动的图像文件

http://en.wikipedia.org/wiki/Colour_banding

答案 1 :(得分:2)

我可以看到它。我认为这是因为面板的尺寸和颜色数量不匹配。使其更平滑的一种方法是使面板的大小成为渐变中颜色数量的偶数倍。这不是完美的,但我不知道更好的方式。

enter image description here

public class TestPanel extends JPanel {

    private static final int scale = 2;
    private static final Color c1 = Color.BLACK;
    private static final Color c2 = Color.GRAY;
    private static final int size = (c2.getRed() - c1.getRed()) * scale;

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(size, size);
    }

    @Override
    protected void paintComponent( Graphics g ) {
        Graphics2D g2d = (Graphics2D) g;
        int w = getWidth();
        int h = getHeight();
        GradientPaint gp = new GradientPaint(0, 0, c1, 0, h, c2);
        g2d.setPaint(gp);
        g2d.fillRect(0, 0, w, h);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPanel());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}