Android:复制位图
一个看似简单的问题,我有一个离屏位图,我对其执行一些转换(旋转、缩放等),并且我想在转换之前存储位图的副本,以便在我的视图的 中onDraw()
,我可以将转换后的离屏位图和未转换位图的较小缩放版本显示为缩略图。
在 onDraw()
中写入离屏位图没有问题,但复制的“保留”位图也会被转换。这是我制作位图副本的代码,其中 mCanvas 是通过 mCanvas = new Canvas(mBitmap); 创建的:
mPreservedBitmap = Bitmap.createBitmap(mBitmap);
// save the canvas
mCanvas.save();
// do some rotations, scaling
mCanvas.rotate(rotation, px, py);
mCanvas.scale(scaleFactor, scaleFactor, scaleFocusX, scaleFocusY);
// draw the bitmaps to the screen
invalidate();
// restore the bitmap
mCanvas.restore();
在 onDraw() 中,我有:
// draw the off-screen bitmap to the on-screen bitmap
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
// draw the preserved image, scaling it to a thumbnail first
canvas.drawBitmap(
Bitmap.createScaledBitmap(mPreservedBitmap, (int) thumbWidth, (int) thumbHeight, true),
null,
thumbnailRectF,
thumbCanvasPaint);
缩略图被缩放到适当的大小,但是被缩小到缩略图大小的位图也被旋转和缩放,与 mBitmap 完全相同,这是我不想要的。我也尝试过 Bitmap.copy() 方法,但结果相同。有什么指示/帮助/建议吗?
谢谢,
保罗
A seemingly simple issue, I have an off-screen bitmap that I perform some transformations to (rotation, scaling, etc) and I'd like to store a copy of the bitmap prior to the transformations, such that in my View's onDraw()
, I can display the transformed off-screen bitmap AND a smaller scaled version of the un-transformed bitmap as a thumbnail.
No problem writing the off-screen bitmap in onDraw()
, but the copied 'preserved' bitmap is also being transformed. Here is the code where I am making the copy of the bitmap, where mCanvas was created via mCanvas = new Canvas(mBitmap);
:
mPreservedBitmap = Bitmap.createBitmap(mBitmap);
// save the canvas
mCanvas.save();
// do some rotations, scaling
mCanvas.rotate(rotation, px, py);
mCanvas.scale(scaleFactor, scaleFactor, scaleFocusX, scaleFocusY);
// draw the bitmaps to the screen
invalidate();
// restore the bitmap
mCanvas.restore();
In onDraw()
, I have:
// draw the off-screen bitmap to the on-screen bitmap
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
// draw the preserved image, scaling it to a thumbnail first
canvas.drawBitmap(
Bitmap.createScaledBitmap(mPreservedBitmap, (int) thumbWidth, (int) thumbHeight, true),
null,
thumbnailRectF,
thumbCanvasPaint);
The thumbnail gets scaled to the appropriate size, but the bitmap that is being scaled down to thumbnail size is also rotated and scaled the exact same as mBitmap, which I don't want. I've also tried the Bitmap.copy() method, but with the same results. Any pointers/assitance/advice?
Thanks,
Paul
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你做错了:) 首先,你永远不应该在字段中保留对 Canvas 的引用。无法保证两次不同的 onDraw() 调用中 Canvas 实例是相同的。第二个问题是如何应用转换。您应该在 onDraw() 中应用它们:
invalidate() 不是同步操作,如果在 onDraw() 之外完成,您的 save()/restore() 不能保证正常工作。
另外,不要从 onDraw() 调用 createScaledBitmap(),它的开销非常大。
You are doing it wrong :) First of all you should never keep a reference to a Canvas in a field. There is no guarantee whatsoever that the Canvas instance will be the same in two different calls to onDraw(). Your second problem is how you apply the transformations. You should apply them in onDraw():
invalidate() is not a synchronous operation, your save()/restore() has no guarantee to work if done outside of onDraw().
Also do not call createScaledBitmap() from onDraw(), it is extremely expensive.
扩展我的评论:
Bitmap.createBitmap(Bitmap)
返回一个不可变的位图。文档实际上说它可能是相同的对象或使用相同的数据。如果您确实想修改它,则必须创建一个可变位图,例如:
在 onDraw 中:
To expand on my comment:
Bitmap.createBitmap(Bitmap)
returns an immutable bitmap. The documentation actually says that it might be the same object or use the same data.You have to create a mutable bitmap, if you actually want to modify it, for example:
And in onDraw:
我的最终解决方案是在缩放画布
Bitmap
之前通过以下方式生成画布的副本:然后,当缩放
Canvas
和主位图时,我可以绘制通过以下方式将未缩放的“保留”Bitmap
转换为onDraw()
中的Canvas
:根据上面 Romain 的评论,我缩放了保留的
位图
离屏以提高onDraw()
中的性能。My final solution to this was to generate a copy of the canvas
Bitmap
PRIOR to it being scaled via:Then, when the
Canvas
and the primary Bitmap is scaled, I can draw the non-scaled 'preserved'Bitmap
to theCanvas
inonDraw()
via:Per Romain's comments above, I scale the preserved
Bitmap
off-screen to improve performance inonDraw()
.