2011-03-23 38 views
2

一個看似簡單的問題,我有一個屏幕位圖,我執行一些轉換(旋轉,縮放等),我想在轉換之前存儲位圖的副本,這樣在我的視圖的onDraw()中,我可以將變換後的屏幕外位圖和未變換位圖的縮小版本顯示爲縮略圖。Android:複製位圖

編寫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

還有什麼你正在做的第一個片段與mCanvas?它似乎沒有做任何事情(旋轉等隻影響未來的操作,而不是圖像本身)。爲什麼你要在OnDraw中複製位圖?通過適當地修改畫布的矩陣,您應該能夠即時縮放縮略圖。 – 2011-03-23 17:05:11

+0

我在代碼中的其他位置使用mCanvas來添加用戶已經繪製到屏幕外位圖的完整形狀。我確實可以將onSampleLoad代碼移出onDraw,我只是在那裏測試了複製/縮放。 – 2011-03-23 19:05:55

回答

1

我這最後的解決辦法是生成的副本

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

然後,當Canvas和初級位圖被縮放,我可以得出非縮放「PRES:帆布Bitmap之前通過它被縮放通過在onDraw() erved」 BitmapCanvas

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

每羅曼的上述評論,我縮放保存Bitmap關屏在onDraw()提高性能。

3

你做錯了:)首先,你應該永遠保持在字段添加到畫布的引用。不能保證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); 

無效()不是同步操作,您的保存()/恢復()沒有保證,如果onDraw有外()完成工作。

也做不是從onDraw()調用createScaledBitmap(),它是非常昂貴的。

+0

謝謝羅曼。我會回覆兩個獨立的評論。如果不是用於訪問屏幕外mBitmap的Canvas的字段引用,我該如何重複寫入位圖?這是一個繪圖程序,當用戶完成它們時,將完成的形狀提交給離屏位圖;當用戶繪製一個正在進行的形狀時,我調用onDraw(),一旦形狀完成,它將通過mCanvas累積添加到mBitmap中。我應該創建新的Canvas引用,每次我想訪問mBitmap'Canvas canvas = new Canvas(mBitmap);'? – 2011-03-23 18:44:23

+0

在onDraw()中執行旋轉和縮放的方面,我原本是這樣設置的,但是因爲我正在調用onDraw,因爲用戶正在將當前形狀繪製到屏幕上,所以事情非常緩慢,不得不旋轉/隨時按照n個可能的x/y對縮放屏幕外位圖。我有它的設置,以便當用戶縮放時,整個屏幕外位圖在屏幕外重新繪製,然後在onDraw()中閃爍到畫布。但是,如果用戶已完成縮放並按比例繪製,則只需調用onDraw並使用已縮放的離屏位圖。 – 2011-03-23 18:55:44

+0

作爲另一個後續工作,我已將代碼切換回來,以便在onDraw()中進行旋轉和縮放...並且性能非常殘酷。當用戶處於畫布被旋轉的狀態時,它們被縮放,當它們繪製並且onDraw()被調用以顯示其進度時,滯後/性能是不可用的。我肯定錯過了什麼。 – 2011-03-23 20:55:54

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

嗯,試過這個,但mPreservedBitmap被設置爲縮放版本的mBitmap ... – 2011-04-27 01:44:03