2013-06-21 5 views
5

मेरे पास दो बिटमैप्स हैं। यहाँएंड्रॉइड - एक अन्य बिटमैप का उपयोग करके बिटमैप मास्किंग

Bitmap 1: Background

और बिटमैप 2:: यहाँ बिटमैप 1 है

Bitmap 2: frame

अंतिम परिणाम क्या होगा:

Bitmap Final

मैं एक कोड की सराहना करेंगे हालांकि, मैं एक दस्तावेज़ीकरण या ट्यूटोरियल के संदर्भ में अधिक सराहना करता हूं। मैं पूरी तरह से कोड को समझना चाहता हूं और मैं बिना किसी किस्मत के डेवलपर.android.com पर खोज कर रहा हूं। धन्यवाद।

+0

यह किया जा सकता है, और मुझे यकीन है कि कोई अंतर्दृष्टि के साथ ड्रॉप करेगा। लेकिन क्या मैं पूछ सकता हूं कि आप अंतिम परिणाम के एक बिटमैप या .png का उपयोग क्यों नहीं करते हैं? –

+1

@ जेडबिफील्ड शायद वे गतिशील इनपुट और आउटपुट हैं, इस मामले में, आप – fge

+0

@fge आह, अच्छा बिंदु नहीं कर सकते हैं :) –

उत्तर

1

3 वर्षों से अधिक और कोई जवाब नहीं? मैं उसे ठीक कर सकता।

टिप्पणियों में कहा गया है कि बिटमैप 2 किनारों के चारों ओर पारदर्शी है और बीच में (केवल समोच्च है) तो पहला कदम केंद्र को सफेद से भरना है। बाढ़ भरने वाले एल्गोरिदम उपलब्ध हैं। मैंने https://stackoverflow.com/a/8925653/852795 का उपयोग किया क्योंकि यह आसान था, हालांकि कुछ ऐसे हैं जो निश्चित रूप से तेज़ हैं। यह आवश्यक है क्योंकि यह अगले चरण को सक्षम बनाता है।

दूसरा चरण Porter/Duff Composting का उपयोग करके बिटमैप 1 के साथ भरे बिटमैप 2 को गठबंधन करना है। 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

वहाँ प्रकट होता है 'fuzziness' का एक सा बस समोच्च के अंदर होने के लिए , लेकिन शायद यह है बाढ़ भरने का एक आर्टिफैक्ट, या शायद मूल बिटमैप 2. उन दोनों के साथ खेलना इसे साफ़ कर सकता है।

संबंधित मुद्दे