尽快清除透明的BufferedImage

adr*_*rau 10 java bufferedimage awt graphics2d

我有一个透明的BufferedImage使用以下代码创建(不相关如何创建,我认为):

            GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
            GraphicsDevice gs = ge.getDefaultScreenDevice();
            GraphicsConfiguration gc = gs.getDefaultConfiguration();

            Rectangle screen = transformationContext.getScreen();

            // Create an image that supports transparent pixels
            return gc.createCompatibleImage((int) screen.getWidth(), (int) screen.getHeight(),
                    Transparency.BITMASK);
Run Code Online (Sandbox Code Playgroud)

如何在不重新创建图像的情况下以最快的方式清除图像(处于与创建状态相同的空图像)?重新创建映像会给GC带来负担,暂停VM并冻结UI.

adr*_*rau 18

得到它:)使用clearRect而不是填充透明颜色.

            graphics = (Graphics2D) offlineBuffer.getGraphics();
            graphics.setBackground(new Color(255, 255, 255, 0));
            Rectangle screen = transformationContext.getScreen();
            graphics.clearRect(0,0, (int)screen.getWidth(), (int)screen.getHeight());
Run Code Online (Sandbox Code Playgroud)

  • 据说`clearRect`在1.1以后被弃用了,虽然它没有被标记(可能是因为注释还不存在?).现在首选的方法是:`graphics.setComposite(AlphaComposite.Clear); graphics.fillRect(0,0,SIZE,SIZE); graphics.setComposite(AlphaComposite.SrcOver);`(假设SrcOver是您之前使用的复合,并且是默认的)这实际上接近于`clearRect`的实现. (5认同)

Syn*_*r0r 9

一个相对快速的方式,但我不知道它是否是最快的(我希望看到其他答案)是另一张你永远不会修改的图片,它总是"完全清除"/"完全透明"然后你做了一个光栅副本,比如说你将副本命名为CLEAR:

imageYouWantToClear.setData( CLEAR.getRaster() );
Run Code Online (Sandbox Code Playgroud)

请注意,使用图形在性能方面可能非常棘手,因为有许多记录不明确的行为.例如,您的图像(比如CLEAR)可能是硬件加速的,但是一旦您使用变异方法(比如说setRgb()),您就会失去硬件加速,并且它将很难实现你刚刚失去了硬件加速的好处.

我认为找到高性能BufferedImage主题的最佳位置将是Java游戏程序员和Java游戏-API程序员社区/论坛.

顺便说一下,确保你的BufferedImage都使用'兼容'模式:TYPE_INT_ARGB在Windows上可能没问题但在OS X上没有等等.所以你想要创建它们:

GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);
Run Code Online (Sandbox Code Playgroud)

哎呀,Demeter法则伤害了,谢谢Java;)