Android, fastest way to draw a bitmap to canvas
Just wondering what the fastest way is to draw a bitmap to canvas?
Currently I have a bitmap (and canvas for drawing) which i use to double buffer drawing calls, and then when i draw to canvas have a scrolling effect by applying a 1px canvas translation. This alone will reduce the framerate from 60+ FPS to ~40, quite a hit. Im not using surfaceView (or GLSurfaceView) at the moment but just wondering if im missing anything that would improve the speed. onDraw() code below
@Override
public void onDraw(Canvas canvas)
{
//update fps text
mFpsTracker.frameTouch();
if(mBufferedBitmap == null)
{
mBufferedBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Conf开发者_如何学Pythonig.ARGB_4444);
mBufferedCanvas = new Canvas(mBufferedBitmap);
}
paint.setColor(Color.BLUE);
mBufferedCanvas.drawLine(0, getHeight(), getWidth(), getHeight(), paint);
mBufferedCanvas.translate(0, -1);
canvas.drawBitmap(mBufferedBitmap, 0, 0, null);
//draw fps
mTextPaint.setColor(Color.WHITE);
canvas.drawText(mFpsTracker.getFPSString(), 40, 40, mTextPaint);
invalidate();
}
please see this blog post by Romain Guy.
A video version is available here.
Don't use ARGB_4444 anymore. It is deprecated. Each pixel is only allocated 4 bits per channel (hence the name). ARBG_8888 offers 16,777,216 colors instead of ARBG_4444's 4,096, but uses 4 bytes per pixel instead of 2.
In Gingerbread, Android made ARGB_8888 the standard format for Surface and increased memory allotment per process because of it.
It is more efficient to set your Window's and (assuming you are using streamlined SurfaceView) SurfaceHolder's format to RGBA_8888. This avoids format changes which are noticeably slower.
Other tips include:
- Limit alpha compositing, as this requires comparatively expensive blending from Skia.
- Request Bitmap Options that prefer the ARGB_8888 Config and disable dithering.
- Remove the Window background if possible.
- Enable hardware acceleration, but beware of unsupported operations.
On a 2.1 device, I am able to draw at least 300 bitmaps on-screen at 50 fps.
I got same problem as yours, please tell me when you found some thing new.
This is what I founded so far:
- For android version > 3 better not to use double buffer, because you are getting hardware acceleration(need to set true in manifest)
- set paint.setDither(true) it will work better on any device with different color then ARGB_4444, witch are most of the devices. Check this out for more info.
In onSizeChange you can resize or create bitmaps according to the canvas size, then the frame drawing will be much faster about 60fps, however using custom view in an endless loop slows down on some and becomes jumpy on some android devices hence I do not recommend it. Instead, it is better to use SurfaceView.
Check this example: How can I use the animation framework inside the canvas?
U need create your bitmap somewhere ( example onCreate or other place (constructor will be good)) because when u do scrolling effect you again and again created new bitmap. So just need create in constructor and than using this bitmap.
it's good solution for me when i have similar problems.
try created this mBufferedBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_4444);
in other place where no invalidate .
hope it's help you.
I think you can get good performance out of a canvas.. but it takes a lot of work..
if you start off with a good performance graphics library, then even if you get a lot of things wrong, you probably will still end up with good performance :) lol
there is a competition running for the fastest drawing library... libgdx is currently winning...
http://code.google.com/p/libgdx/wiki/SimpleApp#Project_Setup
精彩评论