Bryan
Bryan

Reputation: 15155

Android SurfaceView Canvas Layers

I am trying to make an application in which you can take an image and apply 'stickers' (multiple bitmap images) to the image. Then allow the user to transform (translate, scale and rotate) each individual 'sticker'. I am currently using a SurfaceView and Canvas to draw each bitmap to that Canvas. It allows the user to directly transform the bitmap, and that bitmap is drawn to the Canvas on in the onDraw() function. Though currently, I can only effectively manipulate the last 'sticker' that was drawn.

I would like to make it so the user can directly manipulate each individual 'sticker'. So my current thought is that I would have to create multiple layers (i.e. Photoshop Layers) of stickers, and determine during onTouchEvent() which sticker is being touched, bring that layer to the front of the stack and manipulate that layer. To do this I think I would have to create multiple Canvas objects to use as layers, then draw each 'sticker' to a single Canvas. Then onTouchEvent would call getDrawingCache() on each Canvas to detect which sticker is being touched by calling getPixel() on that drawing cache, and determining if the pixel is transparent or not.

My question is essentially how would I go about drawing all of these Canvas objects to the SurfaceView? And is this the best way of getting my desired effect?

I know that SurfaceView takes only one Canvas, therefore I would have to draw each Canvas to a single Canvas beforehand? And if that is the case, would each of these Canvas objects keep their transformations in tact when I merge them? Or would I have to manipulate the bitmap within each Canvas object instead of the Canvas itself?

Upvotes: 2

Views: 1179

Answers (1)

fadden
fadden

Reputation: 52313

SurfaceView doesn't take a Canvas, it provides a Canvas -- note the Canvas is a return value from lockCanvas(), not an argument. (It's an argument to unlockCanvasAndPost(), which is somewhat unfortunate.)

I think the best way to do what you want is to use off-screen Bitmaps, for which you create your own Canvas. Do all of your rendering off screen, then blit the composed Bitmap onto the SurfaceView with a single bitmap draw call.

I should also point out that, if you're using onDraw(), you're at risk of rendering onto the View part rather than the Surface part. I recommend against sub-classing SurfaceView unless you intend to draw on both. If you think that onDraw() is what you actually want, then you should consider using a custom View and avoid the unnecessary Surface overhead.

Upvotes: 2

Related Questions