0

有没有在 Java 中使用 GradientPaint 的替代方法?

基本上此时,当我用纯色填充应用程序中的所有矩形时,我的代码速度可以接受。

但是,一旦我开始使用 GradientPaint,一个动作的性能就会下降 1 秒。

举个例子,一个动作是:点击一个图片,然后图片就弹出来很大。

我喜欢保持 GradientPaint 的外观,因为普通填充看起来很糟糕......但我不想失去性能。GradientPaint 有什么替代品吗?

我希望我的问题不是太含糊,但 GradientPaint 似乎太慢了。我尝试手动实现 GradientPaint 并且性能接近 Java 实现,因此可能表明 GradientPaint 根本无法更有效地完成。

使用 GradientPaint 的代码:

private void drawRectangle(final Graphics2D g2d, int width, int height, int x, int y, final int borderSize, final Color color) {        
    g2d.setColor(color);
    g2d.fillRect(x, y, width, height);

    //account for border distance
    x += borderSize;
    y += borderSize;
    width -= 2 * borderSize;
    height -= 2 * borderSize;

    int mx = (int)Math.round(x + (width / 2));
    int my = (int)Math.round(y + (height / 2));   

    Color colorEdge = alphaColor(color, 192);
    Color colorInside = alphaColor(color, 128);

    Composite oldComposite = g2d.getComposite();

    g2d.setComposite(AlphaComposite.SrcIn);
    g2d.setColor(color);
    GradientPaint paintQ1 = new GradientPaint(x, y, colorEdge, mx, my, colorInside);
    g2d.setPaint(paintQ1);
    g2d.fillRect(x, y, mx - x, my - y);

    GradientPaint paintQ2 = new GradientPaint(x + width - 1, y, colorEdge, mx, my, colorInside);
    g2d.setPaint(paintQ2);
    g2d.fillRect(mx, y, mx - x, my - y);

    GradientPaint paintQ3 = new GradientPaint(x, y + height - 1, colorEdge, mx, my, colorInside);
    g2d.setPaint(paintQ3);
    g2d.fillRect(x, my, mx - x, my - y);

    GradientPaint paintQ4 = new GradientPaint(x + width - 1, y + height - 1, colorEdge, mx, my, colorInside);
    g2d.setPaint(paintQ4);
    g2d.fillRect(mx, my, mx - x, my - y);
    g2d.setComposite(oldComposite);
}

private Color alphaColor(final Color c1, final int alpha) {
    return new Color(c1.getRed(), c1.getGreen(), c1.getBlue(), alpha);
}

每个图像仅调用 3 次,总面积约为 500 x 700 像素的两倍。

问候。

4

1 回答 1

1

回答晚了 6 年,但对于任何找到它的人:

一般来说,Java Paint 实例的工作方式是它们在后台分配非常大的栅格(int 或 byte 数组),然后这些栅格会很快被丢弃,并在下次绘制时重新创建。Java2D 以推动像素为导向,这在一定程度上使情况更加复杂,而现代图形管道的工作方式并非如此。

您可以在一些限制内解决此问题:如果您只是在进行水平或垂直渐变,将渐变绘制到与屏幕兼容的 BufferedImage 中会更高效(您可以制作一个相当小的图像并将其垂直或水平平铺); 根据我的需要,性能提高了大约 20 倍。这是一个使用这种方法的项目,可用作库: https ://github.com/timboudreau/visual-library-tabcontrol/tree/master/colors/src/main/java/com/mastfrog/colors

当然,如果你正在做复杂的 RadialGradientPaints,那将不会是 tilable。可能可以处理任意角度的平铺,但这并不重要 - 在图形上设置一个变换,以便平铺以所需的角度,并变换所有形状,使它们看起来正常定向。

于 2020-02-20T09:09:31.600 回答