GradientPaint / GradientPaint的Java替代品很慢

时间:2013-04-08 19:32:18

标签: java

是否有在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乘700像素的两倍。

问候。

1 个答案:

答案 0 :(得分:1)

回答迟到6年,但对于发现它的人:

通常,Java Paint实例的工作方式是在后台分配非常大的栅格(int或字节数组),然后很快将其丢弃并在下次绘制时重新创建。 Java2D围绕着推动像素而不是现代图形管道的工作原理,在某种程度上使情况更加复杂。

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

当然,如果您正在执行复杂的RadialGradientPaints,那将不是平铺的。 可能可以以任意角度处理平铺,但这并非不平凡-在图形上设置变换以使平铺以所需的角度进行,并变换所有形状,以使它们以正常方向显示