首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android 合成兩張圖片:Canvas 繪製 Bitmap 正確姿勢

     編輯:程式設計綜合問答

錯誤代碼分析

Bitmap pic = BitmapFactory.decodeResource(getResources(), R.drawable.me);
Bitmap map = BitmapFactory.decodeResource(getResources(), R.drawable.static);
Canvas comboImage = new Canvas(map); // 錯誤1:直接用原圖作畫布,會修改原圖且不可變可能崩潰
Bitmap out1 = null;
comboImage.setBitmap(out1);          // 錯誤2:setBitmap(null) 導致 NPE
comboImage.drawBitmap(pic, 600, 350, null);

核心問題

  1. Canvas 構造函數需傳入可變 Bitmap:new Canvas(srcBitmap) 要求 srcBitmap isMutable() == true,資源解碼得到的 Bitmap 預設不可變
  2. 必須先創建目標 Bitmap:Bitmap.createBitmap(width, height, Config.ARGB_8888) 創建可變畫布
  3. 繪製順序決定層級:先畫背景,再畫前景

正確完整代碼

public Bitmap mergeBitmaps(Bitmap background, Bitmap foreground, int x, int y) {
    // 1. 創建可變目標 Bitmap(尺寸取背景圖或自定義)
    int width = background.getWidth();
    int height = background.getHeight();
    Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);

    // 2. 建立 Canvas 繪製到 result
    Canvas canvas = new Canvas(result);

    // 3. 先畫背景
    canvas.drawBitmap(background, 0, 0, null);

    // 4. 再畫前景(指定座標)
    canvas.drawBitmap(foreground, x, y, null);

    // 5. 可選:釋放原圖記憶體(若不再使用)
    // background.recycle(); foreground.recycle();

    return result;
}

// 使用示例
Bitmap pic = BitmapFactory.decodeResource(getResources(), R.drawable.me);
Bitmap map = BitmapFactory.decodeResource(getResources(), R.drawable.static);
Bitmap merged = mergeBitmaps(map, pic, 600, 350);
imageView.setImageBitmap(merged);

進階:支援縮放、旋轉、透明度

Paint paint = new Paint();
paint.setAlpha(128); // 50% 透明度

Matrix matrix = new Matrix();
matrix.postScale(0.5f, 0.5f); // 縮放 0.5x
matrix.postRotate(45);        // 旋轉 45 度
matrix.postTranslate(x, y);   // 平移

canvas.drawBitmap(foreground, matrix, paint);

記憶體管理關鍵點

  • 及時 recycle():大圖合成後釋放原 Bitmap,避免 OOM
  • 使用 inBitmap (API 19+):重用記憶體塊,減少 GC
  • 考慮用 Glide/Coil 進行圖片合成:現代圖片庫提供 RequestBuilder<Bitmap> 鏈式合成,自動管理生命周期

常見坑點

錯誤後果修正
Canvas(map) 直接用資源圖IllegalStateException: immutable bitmapcreateBitmap 創建可變副本
setBitmap(null)NullPointerException構造 Canvas 時直接傳入目標 Bitmap
忽略背景透明通道合成結果黑底/異常Config.ARGB_8888 保留 Alpha
未檢查座標越界前景繪製在可見區域外clamp x/y 到 [0, width/height]
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved