2012-07-05 24 views
27

का एक अनुभाग साफ़ करें लक्ष्य केवल बिटमैप खींचने के लिए है और इसके शीर्ष पर आकार को आकर्षित करता है जो बिटमैप के अंतर्निहित क्षेत्र को मिटा देता है।पोर्टरडफैक्सफर्मोड: बिटमैप

मैंने अवधारणा कोड का सरल सबूत बनाया है और यह समझने के लिए कि मुझे इसके बारे में वास्तव में क्या जाना चाहिए। विभिन्न धागे यहाँ मैं का उपयोग कर के बारे में कई संकेत मिल गया है:

android.graphics.PorterDuff.Mode.CLEAR 

नीचे कोड बस एक नीले रंग की पृष्ठभूमि के साथ एक स्क्रीन बनाता है और एक कस्टम दृश्य कहते हैं। यह दृश्य अपने कैनवास को गुलाबी पृष्ठभूमि, बिटमैप छवि (गुलाबी पृष्ठभूमि दिखाने के लिए थोड़ी सी सीमा के साथ) पर खींचता है, और पीले ओवरलेइंग सर्किल प्रत्येक पोर्टरडफैक्सफर्मोड का प्रतिनिधित्व करता है।

enter image description here

साफ़ मोड ऊपरी बाएँ, जो काले के रूप में दिखाता है:

import android.app.Activity; 
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.PorterDuffXfermode; 
import android.graphics.Paint.Style; 
import android.graphics.PorterDuff.Mode; 
import android.graphics.RectF; 
import android.os.Bundle; 
import android.view.View; 
import android.view.Window; 
import android.widget.RelativeLayout; 

public class Test extends Activity { 
    Drawing d = null; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     requestWindowFeature(Window.FEATURE_NO_TITLE); 

     RelativeLayout.LayoutParams rlp = null; 

     // Create the view for the xfermode test 
     d = new Drawing(this); 
     rlp = new RelativeLayout.LayoutParams(600, 900); 
     rlp.addRule(RelativeLayout.CENTER_IN_PARENT); 
     d.setLayoutParams(rlp); 

     RelativeLayout rl = new RelativeLayout(this); 
     rl.setBackgroundColor(Color.rgb(0, 0, 255)); 
     rl.addView(d); 

     // Show the layout with the test view 
     setContentView(rl); 
    } 

    public class Drawing extends View { 
     Paint[] pDraw = null; 
     Bitmap bm = null; 

     public Drawing(Context ct) { 
      super(ct); 

      // Generate bitmap used for background 
      bm = BitmapFactory.decodeFile("mnt/sdcard/Pictures/test.jpg"); 

      // Generate array of paints 
      pDraw = new Paint[16]; 

      for (int i = 0; i<pDraw.length; i++) { 
       pDraw[i] = new Paint(); 
       pDraw[i].setARGB(255, 255, 255, 0); 
       pDraw[i].setStrokeWidth(20); 
       pDraw[i].setStyle(Style.FILL); 
      } 

      // Set all transfer modes 
      pDraw[0].setXfermode(new PorterDuffXfermode(Mode.CLEAR)); 
      pDraw[1].setXfermode(new PorterDuffXfermode(Mode.DARKEN)); 
      pDraw[2].setXfermode(new PorterDuffXfermode(Mode.DST)); 
      pDraw[3].setXfermode(new PorterDuffXfermode(Mode.DST_ATOP)); 
      pDraw[4].setXfermode(new PorterDuffXfermode(Mode.DST_IN)); 
      pDraw[5].setXfermode(new PorterDuffXfermode(Mode.DST_OUT)); 
      pDraw[6].setXfermode(new PorterDuffXfermode(Mode.DST_OVER)); 
      pDraw[7].setXfermode(new PorterDuffXfermode(Mode.LIGHTEN)); 
      pDraw[8].setXfermode(new PorterDuffXfermode(Mode.MULTIPLY)); 
      pDraw[9].setXfermode(new PorterDuffXfermode(Mode.SCREEN)); 
      pDraw[10].setXfermode(new PorterDuffXfermode(Mode.SRC)); 
      pDraw[11].setXfermode(new PorterDuffXfermode(Mode.SRC_ATOP)); 
      pDraw[12].setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); 
      pDraw[13].setXfermode(new PorterDuffXfermode(Mode.SRC_OUT)); 
      pDraw[14].setXfermode(new PorterDuffXfermode(Mode.SRC_OVER)); 
      pDraw[15].setXfermode(new PorterDuffXfermode(Mode.XOR)); 
     } 

     @Override 
     public void onDraw(Canvas canv) { 
      // Background colour for canvas 
      canv.drawColor(Color.argb(255, 255, 0, 255)); 

      // Draw the bitmap leaving small outside border to see background 
      canv.drawBitmap(bm, null, new RectF(15, 15, getMeasuredWidth() - 15, getMeasuredHeight() - 15), null); 

      float w, h; 
      w = getMeasuredWidth(); 
      h = getMeasuredHeight(); 

      // Loop, draws 4 circles per row, in 4 rows on top of bitmap 
      // Drawn in the order of pDraw (alphabetical) 
      for(int i = 0; i<4; i++) { 
       for(int ii = 0; ii<4; ii++) { 
        canv.drawCircle((w/8) * (ii * 2 + 1), (h/8) * (i * 2 + 1), w/8 * 0.8f, pDraw[i*4 + ii]); 
       } 
      } 
     } 
    } 

} 

इस परीक्षा का परिणाम है।

एक और उदाहरण में जहां मैं इसका उपयोग करने की कोशिश कर रहा था, मेरे पास एक डायलॉग फ्रैगमेंट था जहां क्लीन मोड ने पूरे डायलॉग फ्रैगमेंट को मिटा दिया ताकि नीचे की गतिविधि देखी जा सके। इसलिए इस परीक्षण में मैंने कई अलग-अलग पृष्ठभूमि रंगों का उपयोग किया।

क्या यह संभवतः पूरे गतिविधि के पिक्सल को साफ़ कर सकता है जैसे कि अन्य उदाहरण ने मुझे विश्वास किया? मैंने सोचा होगा कि दृश्य से संबंधित कैनवास के केवल पिक्सेल मिटा दिए जा सकते हैं, लेकिन मेरे दूसरे उदाहरण में कस्टम व्यू के पिक्सल, अंतर्निहित छवि दृश्य और संवाद फ़्रेम पृष्ठभूमि को सभी साफ़ कर दिया गया था।

क्या कोई मुझे यह समझने में मदद कर सकता है कि वास्तव में क्या चल रहा है और मैं इतनी गलत क्यों जा रहा हूं?

धन्यवाद।

संपादित करें: मैंने एक उदाहरण दोहराया है जो मेरे संदेह की पुष्टि करता है। इस सटीक कस्टम व्यू को जोड़ते समय, लेकिन डायलॉग फ्रैगमेंट में, अंतर्निहित गतिविधि दिखाई देती है।

enter image description here

यह है कि किसी भी तरह Mode.CLEAR नीचे रूप में अच्छी तरह के विचारों का कैनवास मिटा रहा है मेरे लिए एक बहुत स्पष्ट सूचक है? मेरा अनुमान है कि पहले उदाहरण में काला शीर्ष स्तर के दृश्य का है?

मैं मैं कुछ बहुत गलत कर रहा हूँ कहीं सोच रहा हूँ: एस

उत्तर

34

समस्या हार्डवेयर त्वरण है। इसे विशेष दृश्य के लिए बंद करें जिसे आप साफ़ कर रहे हैं।आप एक कस्टम दृश्य का उपयोग कर रहे हैं, तो निर्माताओं में ऐसा करते हैं:

if (android.os.Build.VERSION.SDK_INT >= 11) 
{ 
    setLayerType(View.LAYER_TYPE_SOFTWARE, null); 
} 

तुम भी एक दृश्य के संदर्भ पर setLayerType कॉल कर सकते हैं।

+2

धन्यवाद ... मेरा दिन बना दिया! –

+1

क्या यह ड्राइंग धीमा कर देगा, है ना? – sandrstar

+0

यह स्वीकार्य उत्तर होना चाहिए। सुपर सहायक धन्यवाद! –

14

मैं कुछ भी अप्रत्याशित नहीं दिख रहा। Mode.CLEAR के विशेष मामले में, गंतव्य के रंग और अल्फा दोनों को साफ़ कर दिया गया है, जो काले रंग की पृष्ठभूमि को दिखाने की अनुमति देता है। यह utility एक को विभिन्न मोड, रंग और अल्फा मानों के साथ प्रयोग करने की अनुमति देता है, और स्रोत कुछ अंतर्दृष्टि प्रदान कर सकता है। नीचे (कुछ हद तक दिनांकित) छवि में, CLEAR क्षेत्रों में प्लेटफॉर्म के PanelUI प्रतिनिधि द्वारा प्रदान की गई बेहोशी पेंस्रिप-ग्रे प्रकट होती है।

image

+0

धन्यवाद, यह बहुत समझ में आता है। हालांकि मेरी समस्या को लागू करना। जैसा कि आप कहते हैं, आप स्पष्ट क्षेत्र में अंतर्निहित पृष्ठभूमि को सही ढंग से देखते हैं। मुझे नीली क्यों दिखाई नहीं दे रही है (मैं समझ सकता हूं कि गुलाबी क्यों नहीं) पृष्ठभूमि? नीला एक अलग दृश्य है, तो पिक्सेल कस्टम व्यू कैनवास में पारदर्शी क्यों नहीं हैं? (उपरोक्त छवि की तरह)। अगर मैं इसके पीछे एक छवि दृश्य डालता हूं, या कुछ और, मैं अभी भी इसे नहीं देखता, केवल काला। डायलॉगफ्रैगमेंट में ऐसा करने पर, इस विधि ने सचमुच मेरे पूरे संवाद (साथ ही दृश्य) में एक छेद खींचा। तो क्या यह किसी भी कारण से सभी परतों को साफ़ कर रहा है? –

+0

उर्फ, मैं आपकी छवि की तरह बिल्कुल कैसे करूं (चित्र के क्षेत्र को साफ़ करके पृष्ठभूमि दिखाएं? –

+1

प्रभाव देखने के लिए 'SrcOver' मोड में 'Src' रंग के अल्फा को समायोजित करने का प्रयास करें। [स्रोत कोड ] (https://sites.google.com/site/drjohnbmatthews/composite/source-code) कुछ अंतर्दृष्टि भी प्रदान कर सकता है, और एक संबंधित उदाहरण है [यहां] (http://stackoverflow.com/a/7824225/230513) – trashgod

0

जैसा कि रोमैन गाय यहां इंगित करता है: google stuff आपको बिटमैप पर लिखने की जरूरत है, न कि मंडलियों के साथ कैनवास जिन्हें आप साफ़ करने की कोशिश कर रहे हैं, फिर इसे अपने दृश्य में मुख्य कैनवास पर सेट करें। तो, कुछ ऐसा करें:

// Generate bitmap used for background 
      bm = BitmapFactory.decodeFile("mnt/sdcard/Pictures/test.jpg"); 

// Create the paint and set the bitmap 
Canvas temp = new Canvas(bm.getHeight(), bm.getWidth, Config.ARGB_8888); 

// in onDraw() 
temp.drawCircle((w/8) * (ii * 2 + 1), (h/8) * (i * 2 + 1), w/8 * 0.8f, pDraw[i*4 + ii]); 

// After loop 
canvas.drawBitmap(....); 

आशा है कि इससे मदद मिलती है।