Canvas is drawing too slowly

2019-07-31 10:22发布

问题:

I am working on an app that allows stepping through video frames (bitmaps). It also has the capability to play back the frames, one after another, as though you are actually viewing a video composed of the frames.

I have one ImageView that is showing one bitmap at a time. The problem I am having is that drawing the image to the ImageView (we're talking just a call to super.onDraw()) is taking roughly 30ms. Since the frames need to be playing back at their original framerate, this is a problem. There are other operations going on as well that are also slowing the process down, but the drawing certainly isn't helping.

I was looking into OpenGL ES, but it seems that not all devices support non-power-of-two images, so that won't work. The dimensions of the images are half of the device's recorded video resolution since I am sampling them at half-size, and that's pretty much guaranteed to never be a power-of-two image.

Is there some way I can speed things up so that the drawing is faster?

回答1:

OpenGL ES 2.0 imposes support of non-power of two textures, so you're safe with it. If you use OpenGL ES 1.0 and you don't have power of two support, it's very easy to work around it (just create a power of two texture big enough to contain your npot image.)

Note: you should profile your app to see whether you can improve the speed with Canvas. Maybe you are downscaling the image at draw time, maybe it's not in a compatible configuration and conversion happens at runtime (565 to 8888 for instance), etc.



回答2:

I found that ImageView never gave me the framerates I was looking for (the reason, I don't know). For something like this you should override SurfaceView instead. It's a bit more work, but you'll definitely see an improvement in the framerate and you'll have much more flexibility. Obviously you'll want to be aware of your clip and know that if any other view overlays this one, that will cause a significant slowdown as well (since the overlay will also need to be redrawn on each frame).