一个看似简单的问题,我有一个离屏位图,我执行一些转换(旋转,缩放等),我想在转换之前存储位图的副本,这样在我的View中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()方法,但结果相同。任何指针/协助/建议?
谢谢,
保
答案 0 :(得分:3)
你做错了:)首先你应该永远在一个字段中保持对Canvas的引用。无法保证Canvas实例在对onDraw()的两个不同调用中是相同的。您的第二个问题是如何应用转换。您应该在onDraw()中应用它们:
canvas.save();
canvas.rotate(rotation, px, py);
canvas.scale(scaleFactor, scaleFactor, scaleFocusX, scaleFocusY);
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
canvas.restore();
canvas.drawBitmap(
Bitmap.createScaledBitmap(mPreservedBitmap, (int) thumbWidth, (int) thumbHeight, true), null, thumbnailRectF, thumbCanvasPaint);
invalidate()不是同步操作,如果在onDraw()之外完成,则save()/ restore()无法保证工作。
另外不从onDraw()调用createScaledBitmap(),这是非常昂贵的。
答案 1 :(得分:1)
扩展我的评论:
Bitmap.createBitmap(Bitmap)
返回不可变位图。文档实际上说它可能是同一个对象或使用相同的数据。
如果您确实想要修改它,则必须创建可变位图,例如:
mPreservedBitmap = mBitmap;
// Create a new, empty bitmap with the original size.
// Since the image is going to be scaled, this might be to big or to small.
// Rotating might also require additional space (otherwise the corners will be cut off)
// Try calculating the proper size or play around with some other createBitmap Methods, just make sure to
// actually create a mutable bitmap, for example by using copy on an immutable bitmap.
mBitmap = Bitmap.createBitmap(mPreservedBitmap.getWidth(), mPreservedBitmap.getHeight(), mPreservedBitmap.getConfig());
mCanvas = new Canvas(mBitmap);
// do some rotations, scaling
mCanvas.rotate(rotation, px, py);
mCanvas.scale(scaleFactor, scaleFactor, scaleFocusX, scaleFocusY);
// draw the original image to the canvas, applying the matrix modifications
mCanvas.drawBitmap(mPreservedBitmap, 0, 0, null);
在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
canvas.drawBitmap(mPreservedBitmap, null, thumbnailRectF, thumbCanvasPaint);
答案 2 :(得分:1)
我对此的最终解决方案是在通过以下方式缩放之前生成画布Bitmap
的副本:
mPreservedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), null, true);
然后,当缩放Canvas
和主要位图时,我可以通过以下方式将未缩放的“保留”Bitmap
绘制到Canvas
中的onDraw()
: / p>
canvas.drawBitmap(mPreservedBitmap, null, thumbnailRectF, thumbCanvasPaint);
Per Romain上面的评论,我将保留的Bitmap
屏幕缩小,以提高onDraw()
的效果。