通過一個View建立Bitmap
阿新 • • 發佈:2018-11-27
public class BitmapUtil {
//節省每次建立時產生的開銷,但要注意多執行緒操作synchronized
private static final Canvas sCanvas = new Canvas();
/**
* 從一個view建立Bitmap:
* 注意點:繪製之前要清掉 View 的焦點,因為焦點可能會改變一個 View 的 UI 狀態
* 來源:https://github.com/tyrantgit/ExplosionField
*/
public static Bitmap createBitmapFromView (View view, float scale) {
if (view instanceof ImageView) {
Drawable drawable = ((ImageView) view).getDrawable();
if (drawable != null && drawable instanceof BitmapDrawable) {
return ((BitmapDrawable) drawable).getBitmap();
}
}
view.clearFocus();
Bitmap bitmap = createBitmapSafely((int ) (view.getWidth() * scale),
(int) (view.getHeight() * scale), Bitmap.Config.ARGB_8888, 1);
if (bitmap != null) {
synchronized (sCanvas) {
Canvas canvas = sCanvas;
canvas.setBitmap(bitmap);
canvas.save();
// 防止 View 上面有些區域空白導致最終 Bitmap 上有些區域變黑
canvas.drawColor(Color.WHITE);
canvas.scale(scale, scale);
view.draw(canvas);
canvas.restore();
canvas.setBitmap(null);
}
}
return bitmap;
}
//安全的建立bitmap;如果新建 Bitmap 時產生了 OOM,可以主動進行一次 GC - System.gc(),然後再次嘗試建立
private static Bitmap createBitmapSafely(int width, int height, Bitmap.Config config, int retryCount) {
try {
return Bitmap.createBitmap(width, height, config);
} catch (OutOfMemoryError e) {
e.printStackTrace();
if (retryCount > 0) {
System.gc();
return createBitmapSafely(width, height, config, retryCount - 1);
}
return null;
}
}
}