Tiling a Bitmap on a Canvas

2019-02-06 11:33发布

问题:

I would like to create a 'graph paper' look to the Bitmap I am drawing via a Canvas, and trying to figure out the best way to do this.

I can't pass a source Bitmap containing the graph paper background to the Canvas constructor, as I am getting the Canvas in a SurfaceView via the .lockCanvas() call.

Some solutions I've tried:

  • I've tried implementing this solution in my SurfaceView's Thread.run(), but the issue I believe is when the BitmapDrawable is converted to a Bitmap... it loses the tiling properties.

    canvas = mSurfaceHolder.lockCanvas(null); BitmapDrawable TileMe = new BitmapDrawable(BitmapFactory.decodeResource(getResources(), R.drawable.editor_graph)); TileMe.setTileModeX(Shader.TileMode.REPEAT); TileMe.setTileModeY(Shader.TileMode.REPEAT);

    Bitmap b = TileMe.getBitmap(); canvas.drawBitmap(b, 0, 0, null);

  • If I use the Canvas.drawBitmap method that takes a destination RectF as a parameter, it looks like the bitmap will be tiled to fill the RectF... but how do I declare a RectF reliably that fills the entire view area?

  • Setting the Activities background to the desired graph paper look also doesn't work, as the bitmap/canvas layout is opaque and blocks that from being seen.

Any ideas how to achieve this?

回答1:

You have two easy solutions:

  • Either use a BitmapDrawable, but instead of extracting the Bitmap, just call BitmapDrawable.draw(Canvas). Don't forget to set the drawable's bounds to fill your drawing area.
  • Create a Paint with a BitmapShader and draw a rectangle with it (this is basically what BitmapDrawable does).


回答2:

I'm sure there is a way to get a tiled effect using a SurfaceView. Unfortunately, it looks like you can't use the BitmapDrawable with a canvas. So you would probably have to implement you own custom tiling method by creating your own series of Rect's on the Canvas and drawing a scaled bitmap to each one.

It honestly wouldn't be that hard. Just get the width/height of the view, and create an array of Rect's based on this data that you will draw the Bitmap to.

Alternatively, if you don't need to make modifications to the actual tiled background on the fly, just draw it as a background and draw the SurfaceView on top of it. That post you linked provided multiple solutions to tiling a BitmapDrawable that you could implement.