Canvas.drawBitmap()忽略了paint的tile模式

JPv*_*rwe 3 android bitmap android-canvas

我想绘制位图的子部分,但大小不同.如果大小比位图中的源矩形大,那么我希望位图的该部分平铺以填充目标区域.然而,他们没有得到平铺,而是被拉伸了.

我设置了所有变量如下:

Bitmap b = BitmapFactory.decodeResource(getResources(), R.drawable.image);
Rect srcRect = ...
Rect dstRect = ...
Paint p = new Paint();
p.setShader(new BitmapShader(b, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT));
Run Code Online (Sandbox Code Playgroud)

然后在draw()方法中我绘制如下:

canvas.drawBitmap(b, srcRect, dstRect, p);
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?我该如何绘制srcRectdstRect使位图的子部分得到平铺?

JPv*_*rwe 7

我发现了这个问题,简洁明了:位图上的着色器不能那样工作.

要绘制一个用Bitmap您必须使用的特定方块平铺的矩形Canvas.drawRect(),其中Paint包含一个BitmapShader.但是,Android开发者不可能那么简单.

首先,你必须切断srcRect一个单独的Bitmap(缓存这个,因为我不认为这是一个廉价的操作),像这样:

Bitmap t = Bitmap.createBitmap(b, srcRect.left, srcRect.top, srcRect.right-srcRect.left, srcRect.bottom-srcRect.top);
Run Code Online (Sandbox Code Playgroud)

然后你必须创建PaintBitmapShader:

BitmapShader bs = new BitmapShader(t, TileMode.REPEAT, TileMode.REPEAT);
Paint p = new Paint();
p.setShader(bs);
Run Code Online (Sandbox Code Playgroud)

然后你最终可以绘制到目标矩形,但首先你必须为着色器设置一个平移矩阵,否则它将无法从正确的位置开始,如果你的平铺模式是CLAMP:

Matrix m = new Matrix();
m.postTranslate(dstRect.left, dstRect.right);
p.getShader().setMatrix(m);
canvas.drawRect(dstRect, p);
Run Code Online (Sandbox Code Playgroud)