• Advertisement
Sign in to follow this  

Allocating Bitmap in OnDraw( Canvas canvas )

This topic is 426 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

So in my Android game i need to fill the canvas with the background Image ...  ... Now canvas is local to OnDraw( Canvas canvas ), so I have get the canvas size at run time (since this would also vary from phone to phone), it is most important it is done at run time. And since canvas, as said is local to OnDraw(), there is no where else for me to allocate my scaled background sprite, I can only know the canvas size inside OnDraw( ... )

 

Now my code now runs/animates significantly slower, more so there is this warning flagging up

[attachment=34919:allocate.png]

 

BTW None of the provided methods allow me to pre-allocate bitmap with canvas size outside OnDraw 

 

So how do I solve this ... how do i allocate the canvas size and yet not do it in OnDraw( ... ) ?

protected void onDraw(Canvas canvas) {     
	canvasWidth  = canvas.getWidth();
	canvasHeight = canvas.getHeight();

	scaledSprite  =  Bitmap.createScaledBitmap( backgroundSprite, canvasWidth, canvasHeight, false );
        canvas.drawBitmap( scaledSpite, 0,  0, null);
     ....
     ....
}

Share this post


Link to post
Share on other sites
Advertisement

Caching the previously created bitmap for re-use might work.

class X {
    int scaledWidth = -1;
    int scaledHeight = -1;
    Sprite scaledSprite = null;

    ...
void onDraw(Canvas canvas) {
    if (scaledWidth != canvas.getWidth() || scaledHeight != canvas.getHeight()) {
        scaledWidth = canvas.getWidth() ;
        scaledHeight = canvas.getHeight();
        scaledSprite = Bitmap.createScaledBitmap(backgroundSprite, scaledWidth+300, scaledHeight+390, false);
    }
    canvas.drawBitmap( scaledSpite, -120, -70, null);
    ....
}

Assuming the canvas doesn't change size every frame, you do the expensive operation only a few times (or even just once).

 

Another option is to notice in onDraw you don't have a scaledsprite. You skip drawing (or use a single colour as background, or something else that is quick enough). Also, set the desired size in some variables. Outside the drawing code you check whether that size is set, and then create the scaled sprite of the requested size. When done, put the sprite at a spot where the draw code can find it.

This gives you a few frames of bad images, but you do create the scaled sprite outside the draw code.

Edited by Alberth

Share this post


Link to post
Share on other sites
The quickest solution with what you have now would be to cache the bitmap— only re–creating when the canvas changes:
private Bitmap scaledSprite = null;

@Override
protected void onDraw(Canvas canvas) {
	canvasWidth  = canvas.getWidth();
	canvasHeight = canvas.getHeight();

	if ( scaledSprite == null || scaledSprite.getWidth() != canvasWidth || scaledSprite.getHeight() ) {
		scaledSprite = Bitmap.createScaledBitmap(backgroundSprite, canvasWidth, canvasHeight, false);
	}

	canvas.drawBitmap(scaledSprite, 0, 0, null);

	…
	…
}
That aside, you should be able to listen to `onSize` events or use a placeholder `View` for the canvas and base the size of the canvas off the size of the view after a layout event.

Share this post


Link to post
Share on other sites

Thanks @[member='Alberth'], your first option works perfect

 

Yeah, canvas size - for a device - doesn't change every frame

 

Thanks @[member='fastcall22'], also works perfect for the other bitmaps that change size,   wish i'm as smart as you guys  :D

 

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement