Android: копирование растрового изображения - PullRequest
2 голосов
/ 23 марта 2011

Кажущаяся простой проблема, у меня есть закадровое растровое изображение, в которое я выполняю некоторые преобразования (вращение, масштабирование и т. Д.), И я хотел бы сохранить копию растрового изображения до преобразований, например, в моем представлении 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 (), но с теми же результатами. Любые указатели / помощь / совет?

Спасибо

Пол

Ответы [ 3 ]

3 голосов
/ 23 марта 2011

Вы делаете это неправильно :) Прежде всего вы должны никогда хранить ссылку на холст в поле.Нет никакой гарантии, что экземпляр 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 () не является синхронной операцией, ваш save () / restore () не гарантирует работу, если выполняется вне onDraw ().

Также не вызовите createScaledBitmap () из onDraw (), это очень дорого.

1 голос
/ 23 декабря 2011

Мое окончательное решение было создать копию холста Bitmap ДО того, чтобы он масштабировался с помощью:

mPreservedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), null, true);

Затем, когда масштабируется Canvas и первичный битмап, яможно нарисовать немасштабированный «сохраненный» Bitmap в Canvas в onDraw() с помощью:

canvas.drawBitmap(mPreservedBitmap, null, thumbnailRectF, thumbCanvasPaint);

Согласно комментариям Ромен выше, я масштабирую сохраненный Bitmap за кадром для повышения производительностив onDraw().

1 голос
/ 23 марта 2011

Чтобы расширить мой комментарий:

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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...