2013-02-10 26 views
29

इसलिए मैंने यहां से कोड का प्रयास किया: Creating an ImageView with a mask। मैं मूल और मुखौटा के रूप में निम्न छवियाँ उपयोग कर रहा हूँ:एंड्रॉइड छवि दृश्य पर मुखौटा कैसे लागू करें?

enter image description here

ध्यान दें कि विंडो पृष्ठभूमि काला नहीं है, लेकिन:

enter image description hereenter image description here

हालांकि, परिणाम मैं यह है होलो लाइट (जो आकाशगंगा नेक्सस पर एक बहुत पीला भूरा दिखता है, पूरी तरह से सफेद नहीं)। दूसरी छवि परिणाम है जब मुझे सूची दृश्य पर कोई आइटम चुना जाता है।

, तो इसके बजाय मैं एक ही एल्गोरिथ्म और उसके बाद का उपयोग कर एक नया बिटमैप बनाने के बजाय OnDraw() अधिभावी की छवि को देखने के लिए इसे पारित, इसे सही ढंग से ड्रॉ:

:

Canvas canvas = new Canvas(); 
Bitmap mainImage = //get original image 
Bitmap maskImage = //get mask image 
Bitmap result = Bitmap.createBitmap(mainImage.getWidth(), mainImage.getHeight(), Bitmap.Config.ARGB_8888); 

canvas.setBitmap(result); 
Paint paint = new Paint(); 
paint.setFilterBitmap(false); 

canvas.drawBitmap(mainImage, 0, 0, paint); 
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); 
canvas.drawBitmap(maskImage, 0, 0, paint); 
paint.setXfermode(null); 

imageView.setImageBitmap(result); 

मैं उम्मीद परिणाम प्राप्त

enter image description here

नोट करें कि फीका सही तरीके से लागू है। जब चयन किया जाता है तो यह अधिक स्पष्ट होता है।

तो विंडो पृष्ठभूमि को दिखाने के बजाए इस काले पृष्ठभूमि को बनाने के लिए ImageView की ऑनड्रा विधि पर क्या चल रहा है? दिलचस्प बात यह है कि यदि मूल छवि ही कुछ पारदर्शिता है, कि पारदर्शिता सम्मान दिया जाता है उदाहरण के लिए, है:

enter image description here

मैं अपने आप को द्वारा यह पता लगा नहीं कर सकता। मैं इसे बिटमैप को पूर्व-निर्माण करने के बजाय ऑन ड्रा पर करने में सक्षम हूं क्योंकि यह केवल स्रोत और मुखौटा के रूप में बिटमैप्स के लिए काम करता है। मैं इसे अन्य ड्रैबल्स जैसे ग्रेडियेंट्स और ठोस रंगों के साथ करने में सक्षम होना चाहता हूं लेकिन उन मामलों पर चौड़ाई और ऊंचाई सेट नहीं है।

+1

यहाँ एक अद्यतन है। Http://stackoverflow.com/questions/3467334/erase-bitmap-parts-using-porterduff-mode पढ़ने के बाद मैं कामकाजी उदाहरण पर उसी काले व्यवहार को पुन: उत्पन्न कर सकता हूं अगर मैं बिटमैप कॉन्फ़िगरेशन को ARGB_8888 के बजाय RGB_565 पर सेट करता हूं। मैं इस मुद्दे को डाउन विधि पर पारित कैनवास को भी सीमित कर सकता हूं। अगर मैं ऑनड्रा कैनवास का उपयोग करता हूं, तो काला सीमा दिखाई देती है।चूंकि कैनवास को पास करने के लिए पास किया गया है, जिसमें बिटमैप जुड़ा हुआ नहीं है, शायद मूल रूप से पारदर्शिता का समर्थन नहीं करता है? एक और चीज जो मैंने पाया वह यह है कि सूची दृश्य स्क्रॉल होने पर काला सीमा गायब हो जाती है। – AngraX

+1

ठीक है। इसे पढ़ने के बाद http://stackoverflow.com/questions/5231260/android-shader-behave- अलग-in-ondrawcanvas-and-new-canvasbitmap ऐसा लगता है कि बग वास्तव में है कि मैं विंडो कैनवास पारदर्शी के पिक्सल बना रहा हूं अगर मैं उस पर लागू कैनवास पर लागू करता हूं()। और खिड़की के पीछे एक काला पृष्ठभूमि है। ऐसा लगता है कि मेरे पास अस्थायी बिटमैप का उपयोग करने और इसमें प्रस्तुत करने के अलावा कोई विकल्प नहीं है, जब तक कि मैं एक और डीएसटी मोड नहीं ढूंढ पाता। – AngraX

+0

मैं एक समान कार्यक्षमता को लागू करने की कोशिश कर रहा हूं जहां मेरे पास छवि के साथ एक छविदृश्य है और दूसरा विह ब्लैक मास्क, स्पर्श पर इसे सर्कल में पीछे दिखाए गए चित्र दृश्य को दिखाना चाहिए, क्या आप यहां मेरी मदद कर सकते हैं? – ViVekH

उत्तर

25

मुझे सभी स्टैक ओवरफ्लो पोस्ट के माध्यम से शोध करने के बाद काले सीमा के बिना मास्किंग बनाने के लिए एकदम सही संयोजन मिला है। यह मेरे उद्देश्य को काफी अच्छी तरह से उपयुक्त बनाता है।

वर्तमान में मैं एक सामान्य छवि और एक मास्किंग छवि (पारदर्शिता वाला एक पीएनजी) का उपयोग करके एक खींचने योग्य दृश्य बना रहा हूं, इसलिए मुझे ऑन ड्रा कार्य को ओवरराइड करना होगा।

private Bitmap mImage = ...; 
private Bitmap mMask = ...; // png mask with transparency 
private int mPosX = 0; 
private int mPosY = 0; 

private final Paint maskPaint; 
private final Paint imagePaint; 

public CustomView (final Context context) { 
    maskPaint = new Paint(); 
    maskPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); 

    imagePaint = new Paint(); 
    imagePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OVER)); 
} 

/* TODO 
if you have more constructors, make sure you initialize maskPaint and imagePaint 
Declaring these as final means that all your constructors have to initialize them. 
Failure to do so = your code won't compile. 
*/ 

@Override 
public void onDraw(Canvas canvas) { 
    super.onDraw(canvas); 

    canvas.save();  
    canvas.drawBitmap(mMask, 0, 0, maskPaint); 
    canvas.drawBitmap(mImage, mPosX, mPosY, imagePaint); 
    canvas.restore(); 
} 
+1

हे। मैंने एक्सफर मोड के बारे में कुछ लेख पढ़ने के बाद तर्क की जांच की और मेरा मानना ​​है कि आपका समाधान बहुत अच्छी तरह से काम करता है। इसे आधिकारिक उत्तर के रूप में स्वीकार करना। एक्सफर मोड के बारे में अधिक जानकारी के लिए, देखें: http://www.piwai.info/transparent-jpegs-done-right/ और http://ssp.impulsetrain.com/2013-03-17_Porter_Duff_Compositing_and_Blend_Modes.html – AngraX

+0

एल्गोरिदम के मामले में ऊपर काम नहीं किया है, मास्कपेंट के setXfermode को PorterDuff.Mode.DST_OUT में बदलें। – morph85

+0

यह दोनों मोड के साथ काम करता है: साफ़ और DST_OUT। प्रलेखन से, मैंने एक्सफर मोड के बारे में पढ़ा है, क्लियर को पूरी चीज को साफ़ करना चाहिए, लेकिन एंड्रॉइड पर यह वास्तव में एक DST_OUT के रूप में काम करता है। बीटीडब्लू, मैं अब एक्सफर मोड के बजाय शेडर्स का उपयोग कर रहा हूं, इसलिए मैं 1 कम ड्राइंग पास करता हूं, जिससे मेरी ओवरड्रा ड्रॉप रेड से ग्रीन्स तक हो जाती है :)। – AngraX

2

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

इसे ठीक से करने के लिए, वास्तव में अल्फा मास्क के परिणाम को पकड़ने के लिए एक नया बिटमैप बनाया जाना है। मैंने सभी प्रकार के खाता ड्रॉबल्स को ध्यान में रखने के लिए कोड अपडेट किया।

0

इस संहिता में लागू करें:

mask_over = BitmapFactory.decodeResource(
      getResources(), mask_over1[0]); 
    icon = Bitmap.createScaledBitmap(icon, screenwidth, screenwidth, false); 
    mask_over = Bitmap.createScaledBitmap(mask_over, screenwidth, screenwidth, false); 
      back_img=createBitmap_ScriptIntrinsicBlur(Bitmap.createScaledBitmap(cropview.croppedImage, screenwidth, screenwidth, false),25.0f); 
    LinearLayout.LayoutParams layoutParams111 = new LinearLayout.LayoutParams(screenwidth, screenwidth);