Canvas.drawBitmap() 忽略绘画的平铺模式

发布于 2024-12-29 21:37:10 字数 536 浏览 2 评论 0原文

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

我按如下方式设置所有变量:

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));

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

canvas.drawBitmap(b, srcRect, dstRect, p);

我做错了什么?我应该如何将 srcRect 绘制到 dstRect 以便位图的子部分平铺?

I want to draw subparts of a bitmap, but at a different size. If the size is bigger than the source rectangle in the bitmap, then I want that section of the bitmap to tile to fill the destination area. However, instead of getting tiled they are getting stretched.

I set up all the variables as follows:

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));

And then in the draw() method I draw as follows:

canvas.drawBitmap(b, srcRect, dstRect, p);

What am I doing wrong? How should I draw srcRect to dstRect such that my subpart of the bitmap gets tiled?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

红焚 2025-01-05 21:37:10

我发现了这个问题,简单地说:位图上的着色器不能那样工作。

要绘制使用特定 Bitmap 平铺的矩形,您必须使用 Canvas.drawRect(),以及具有 BitmapShader 的 Paint。然而,Android 开发绝不会那么简单。

首先,您必须将 srcRect 剪切为单独的位图(将其缓存在某处,因为我认为这不是一个廉价的操作),如下所示:

Bitmap t = Bitmap.createBitmap(b, srcRect.left, srcRect.top, srcRect.right-srcRect.left, srcRect.bottom-srcRect.top);

然后您必须创建 PaintBitmapShader

BitmapShader bs = new BitmapShader(t, TileMode.REPEAT, TileMode.REPEAT);
Paint p = new Paint();
p.setShader(bs);

然后你终于可以绘制到目标矩形,但首先你必须为着色器设置一个平移矩阵,否则它不会从正确的地方开始,如果您的平铺模式是CLAMP

Matrix m = new Matrix();
m.postTranslate(dstRect.left, dstRect.right);
p.getShader().setMatrix(m);
canvas.drawRect(dstRect, p);

I discovered the problem, put succinctly: shaders on bitmaps don't work that way.

To draw a rectangle tiled with a specific Bitmap you have to use Canvas.drawRect(), with a Paint that has a BitmapShader. However, Android dev can't ever be as simple as that.

First you have to cut out the srcRect to a separate Bitmap (caching this somewhere since I don't think this is a cheap operation), like so:

Bitmap t = Bitmap.createBitmap(b, srcRect.left, srcRect.top, srcRect.right-srcRect.left, srcRect.bottom-srcRect.top);

Then you have to create the Paint and the BitmapShader:

BitmapShader bs = new BitmapShader(t, TileMode.REPEAT, TileMode.REPEAT);
Paint p = new Paint();
p.setShader(bs);

Then you can finally draw to the destination rectangle, but first you have to set up a translation matrix for the shader or else it won't start from the correct place and might bugger up completely if your tile mode is CLAMP:

Matrix m = new Matrix();
m.postTranslate(dstRect.left, dstRect.right);
p.getShader().setMatrix(m);
canvas.drawRect(dstRect, p);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文