【问题标题】:Android DrawBitMap very slow when using ARGB_8888Android DrawBitMap 使用 ARGB_8888 时非常慢
【发布时间】:2022-05-06 08:31:56
【问题描述】:

我发现 DrawBitMap 仅绘制三个位图需要 50-60 毫秒,一个是占据全屏的矩形,一个是圆形,另一个是路径。我的位图是通过在空白位图上使用 Canvas.drawPath、drawRect 和 drawCircle 创建的,Bitmap.Config 为 ARGB_8888。 我正在使用 ARGB_8888 使背景可见以获得分层效果。 我很震惊地发现所花费的时间大约为 50 毫秒,因为我认为 drawBitmap 将是一个非常简单的操作。有人可以指导我是否犯了任何根本性错误。以下是我的代码

创建空白位图

Rectangle = Bitmap.createBitmap(320,480,Bitmap.Config.ARGB_8888);
Circle = Bitmap.createBitmap(70,70,Bitmap.Config.ARGB_8888);
Leaf1 = Bitmap.createBitmap(20,30,Bitmap.Config.ARGB_8888);

在适当的位图上绘制形状

Canvas c = new  Canvas(Rectangle);
Paint p = new Paint();
p.setAntiAlias(true);
p.setColor(0xff6e8b3e);
c.drawRect(0,0,320,480,p);

Canvas c = new Canvas(Circle);
Paint p = new Paint();
CirclePath = new Path();
p.setAntiAlias(true);
p.setColor(0xffcd661d);
System.out.println("x = "+x+" y = "+y);
CirclePath.addCircle(50,50,10,Path.Direction.CW);
c.drawPath(CirclePath,p);

Canvas c = new  Canvas(Leaf1);
Paint paint = new Paint();
Path path = new Path();
paint.setAntiAlias(true);
path.moveTo((float)184.37,(float)219.15);
path.cubicTo((float)188.32,(float)219.15,(float)192.88,(float)220.44,(float)195.62,(float)223.54);
path.cubicTo((float)197.84,(float)226.05,(float)203.2,(float)229.84,(float)198.18,(float)245.98);

在 OnDraw 中绘制位图

canvas.drawBitmap(Rectangle,0,0,p);
canvas.translate(x,y); // For animation effect
canvas.drawBitmap(Circle,0,0,p);
canvas.drawBitmap(Leaf1,0,0,p);

现在,当我记录这三个 drawBitMap 所用的时间时,我发现它大约需要 50 毫秒 代码中是否存在重大错误。将 Bitmap.Config 更改为 RGB_565 可以将时间缩短到 8 毫秒左右,但是背景不可见,并且路径周围出现了一个黑框

【问题讨论】:

    标签: android


    【解决方案1】:

    看起来很正常。 画布的透明度非常慢。

    您可以尝试切换到 OpenGL ES 或设计尽可能少的透明度的内容,以便尽可能频繁地使用 RGB_565。

    【讨论】:

    • +1。如果你做了很多重要的事情(旋转、缩放、alpha、抗锯齿等),请改用 OpenGL。如果不这样做,请务必将其关闭。
    • 您好 mibollma,仅在图像周围需要透明度,以便背景可见。图像是使用 drawPath 以编程方式创建的,并且由于 createBitmap 采用矩形大小,除非我指定透明度背景在图像外部但在图像框内不可见
    【解决方案2】:

    您应该始终匹配屏幕的格式。最近有一个非常相似的问题,Romain 提到如果格式匹配,blits 本质上会变成 memcpys。当然,请确保您没有使用深奥的 blit 模式。

    另外,如果你不缩放/旋转任何东西,为什么还要使用抗锯齿?

    至于 565 不起作用 - 我只是在浏览您的代码。你用的是alpha通道吗?你的位图到底是什么样的?

    【讨论】:

    • 是的 Alpha 通道正在使用,因为我希望背景在图像周围正确显示。是的,目标是旋转和缩放,所以我使用抗锯齿。基本上我正在设计一个 SVG 播放器,它执行矢量图形动画,因此位图是使用 drawPath 函数构造的,然后在屏幕上为每一帧绘制位图
    【解决方案3】:

    一位 Android 开发人员对此进行了解释 here。要快速绘制 ARGB_8888,您需要绘制到 32 位窗口。有关基准,请参阅文章底部。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-15
      • 1970-01-01
      • 2013-04-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-26
      • 1970-01-01
      相关资源
      最近更新 更多