2013-06-21 45 views
5

我有兩個位圖。下面是位圖1:Android - 使用另一個位圖掩蓋位圖

Bitmap 1: Background

這裏是位圖2:

Bitmap 2: frame

什麼的最終結果應爲:

Bitmap Final

我將不勝感激代碼但是,我希望更多地參考文檔或教程。我想完全理解代碼,並且我一直在搜索developer.android.com很長時間沒有運氣。謝謝。

+0

這可以完成,我相信有人會有一些洞察力。但是,我可以問爲什麼你不只是使用你想要的最終結果的單個位圖或.png? –

+1

@JadeByfield也許這些是動態的輸入和輸出,在這種情況下,你不能這樣做 – fge

+0

@fge啊,好點:) –

回答

1

3年多沒有回答?我可以解決這個問題。

正如評論中所述,位圖2在邊緣和中間是透明的(只有輪廓在那裏),所以第一步是用白色填充中心。有很多洪水填充算法可用。我用https://stackoverflow.com/a/8925653/852795,因爲它很容易,但也有其他人肯定更快。這是必要的,因爲它可以啓動下一步。

第二步是使用Porter/Duff Composting將填充的位圖2與位圖1相結合。 PorterDuff.Mode.SRC_ATOP將有效地將位圖1繪製到位圖2的現在白色區域,同時使輪廓在輪廓外部保持透明。

下面是代碼:

package test.testapplication; 

import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.Point; 
import android.graphics.PorterDuff; 
import android.graphics.PorterDuffXfermode; 
import android.os.Bundle; 
import android.support.v7.app.AppCompatActivity; 
import android.view.View; 
import android.graphics.Bitmap.Config; 

import java.util.LinkedList; 
import java.util.Queue; 

public class MainActivity extends AppCompatActivity { 

    Bitmap mask, background, filledMask, overlay; 
    Canvas c; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     mask = BitmapFactory.decodeResource(getResources(), R.drawable.mask); 
     background = BitmapFactory.decodeResource(getResources(), R.drawable.background); 

     // get the mask, copy it to filledMask and then flood from the center with CYAN 
     filledMask = Bitmap.createBitmap(mask.getWidth(), mask.getHeight(), Config.ARGB_8888); 
     c = new Canvas(filledMask); 
     c.drawBitmap(mask, 0, 0, new Paint()); 
     Point center = new Point(filledMask.getWidth()/2, filledMask.getHeight()/2); 
     floodFill(filledMask, center, Color.TRANSPARENT, Color.WHITE); 


     // create new overlay Bitmap, draw the filledMask and then add the background using PorterDuff 
     overlay = Bitmap.createBitmap(filledMask.getWidth(), filledMask.getHeight(), Config.ARGB_8888); 
     c = new Canvas(overlay); 
     Paint p = new Paint(); 
     p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP)); 
     c.drawBitmap(filledMask, 0, 0, new Paint()); 
     c.drawBitmap(background, 0, 0, p); 

     DrawView drawView = new DrawView(this); 
     // set background to light blue in order to see transparent areas 
     drawView.setBackgroundColor(0xffd2d7fe); 
     setContentView(drawView); 
     drawView.requestFocus(); 
    } 

    public class DrawView extends View { 
     Paint p = new Paint(); 
     int top = 0; 

     public DrawView(Context context) { 
      super(context); 
     } 

     protected void onDraw(Canvas canvas) { 
      super.onDraw(canvas); 
      canvas.drawBitmap(mask, 0, 0, p); 
      top += mask.getHeight(); 

      canvas.drawBitmap(filledMask, 0, top, p); 
      top += filledMask.getHeight(); 

      canvas.drawBitmap(background, 0, top, p); 
      top += background.getHeight(); 

      canvas.drawBitmap(overlay, 0, top, p); 
     } 
    } 

    // method from https://stackoverflow.com/a/8925653/852795 
    public void floodFill(Bitmap bmp, Point pt, int targetColor, int replacementColor) { 

     Queue<Point> q = new LinkedList<>(); 
     q.add(pt); 
     while (q.size() > 0) { 
      Point n = q.poll(); 
      if (bmp.getPixel(n.x, n.y) != targetColor) continue; 

      Point w = n, e = new Point(n.x + 1, n.y); 
      while ((w.x > 0) && (bmp.getPixel(w.x, w.y) == targetColor)) { 
       bmp.setPixel(w.x, w.y, replacementColor); 
       if ((w.y > 0) && (bmp.getPixel(w.x, w.y - 1) == targetColor)) q.add(new Point(w.x, w.y - 1)); 
       if ((w.y < bmp.getHeight() - 1) && (bmp.getPixel(w.x, w.y + 1) == targetColor)) q.add(new Point(w.x, w.y + 1)); 
       w.x--; 
      } 
      while ((e.x < bmp.getWidth() - 1) && (bmp.getPixel(e.x, e.y) == targetColor)) { 
       bmp.setPixel(e.x, e.y, replacementColor); 

       if ((e.y > 0) && (bmp.getPixel(e.x, e.y - 1) == targetColor)) q.add(new Point(e.x, e.y - 1)); 
       if ((e.y < bmp.getHeight() - 1) && (bmp.getPixel(e.x, e.y + 1) == targetColor)) q.add(new Point(e.x, e.y + 1)); 
       e.x++; 
      } 
     } 
    } 
} 

運行時,將輸出(在順序添加淺藍色色調的背景「看見」的圖像的透明區域之後)應該是這樣的,以圖像分別是位圖2,填充位圖2,位圖1和位圖2填充的最後的組合和Bitmap 1:

enter image description here

似乎有一個比特的「模糊性」只是在輪廓內部,但那很可能一個洪水填充的神器,或者也許是原始的位圖2.與這兩個玩弄可能會清除。