2013-06-21 3 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을 사용했는데, 분명히 빠 른 다른 것들도 있었지만 쉽습니다. 이것은 다음 단계를 가능하게하기 때문에 필요합니다.

두 번째 단계는 채워진 비트 맵 2를 Porter/Duff Composting을 사용하여 비트 맵 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)의 최종 조합 및 비트 맵 1 인 : 거기 표시

enter image description here

단지 윤곽 내부 "번짐"의 비트 될 ,하지만 아마 그럴거야. 홍수 채우기의 아티팩트, 또는 아마도 원래의 비트 맵 2. 그것들을 가지고 노는 것은 그것을 분명히 해줄 것입니다.

관련 문제