2011-06-21 16 views
9

हटाएं मैं बिटमैप बना रहा हूं, इसके बाद मैं इसके ऊपर दूसरा ठोस रंग बिटमैप खींच रहा हूं। और अब मैं पहले बिटमैप को बदलना चाहता हूं, इसलिए ठोस रंग जिसे मैंने आकर्षित किया वह पारदर्शी होगा।एंड्रॉइड बिटमैप मुखौटा रंग, रंग

या बस, मैं बिटमैप से एक रंग के सभी पिक्सल को हटाना चाहता हूं। मैंने हर रंगफिल्टर और xfermode को कोई किस्मत के साथ करने की कोशिश की है, क्या पिक्सेल द्वारा पिक्सेल कर रहे अन्य रंग को हटाने की कोई अन्य संभावना है?

उत्तर

0

पिक्सेल द्वारा पिक्सेल खराब विकल्प नहीं है। बस अपने लूप के अंदर setPixel को कॉल न करें। GetPixels के साथ argb ints की एक सरणी भरें, अगर आपको मूल को संरक्षित करने की आवश्यकता नहीं है, तो अंत में सेट पिक्सल को कॉल करें, और इसे अंत में सेट करें। यदि स्मृति चिंता का विषय है तो आप यह पंक्ति-दर-पंक्ति कर सकते हैं, या आप केवल एक शॉट में पूरी चीज कर सकते हैं। आपको अपने ओवरले रंग के लिए एक संपूर्ण बिटमैप भरने की आवश्यकता नहीं है क्योंकि आप बस एक साधारण प्रतिस्थापन कर रहे हैं (यदि वर्तमान पिक्सेल रंग 1 है, तो रंग 2 पर सेट करें)।

+0

धन्यवाद, लेकिन मुझे अंत में पता चला कि पोर्टरडफ, एक्सफर्मोड (xor) के साथ इसे कैसे किया जाए, लेकिन अन्य बिटमैप पर लागू किया गया, पहले मैंने मास्क और स्रोत विलय किया और इसे रंगफिल्टर के साथ कैनवास पर खींचने की कोशिश की, लेकिन आखिर में मैंने सोचा आउटपुट पर मास्क ड्रॉइंग करते समय मुझे xfermode का उपयोग करना चाहिए, कैनवास नहीं :) – ZZZ

12

यह बिटमैप से एक निश्चित रंग को हटाने के लिए काम करता है। मुख्य भाग AvoidXfermode का उपयोग है। एक रंग को दूसरे रंग में बदलने की कोशिश करते समय भी यह काम करना चाहिए।

मुझे यह जोड़ना चाहिए कि यह बिटमैप से रंग हटाने का प्रश्न शीर्षक का उत्तर देता है। ओपी की तरह पोर्टरडफ एक्सफर्मोड का उपयोग करके विशिष्ट प्रश्न शायद बेहतर हल हो गया है। एपीआई स्तर 16 (Jelly Bean) जब तक एक आकर्षण अप, जिसके बाद AvoidXfermode बिल्कुल काम नहीं लगता है जैसे

// start with a Bitmap bmp 

// make a mutable copy and a canvas from this mutable bitmap 
Bitmap mb = bmp.copy(Bitmap.Config.ARGB_8888, true); 
Canvas c = new Canvas(mb); 

// get the int for the colour which needs to be removed 
Paint p = new Paint(); 
p.setARGB(255, 255, 0, 0); // ARGB for the color, in this case red 
int removeColor = p.getColor(); // store this color's int for later use 

// Next, set the alpha of the paint to transparent so the color can be removed. 
// This could also be non-transparent and be used to turn one color into another color    
p.setAlpha(0); 

// then, set the Xfermode of the pain to AvoidXfermode 
// removeColor is the color that will be replaced with the pain't color 
// 0 is the tolerance (in this case, only the color to be removed is targetted) 
// Mode.TARGET means pixels with color the same as removeColor are drawn on 
p.setXfermode(new AvoidXfermode(removeColor, 0, AvoidXfermode.Mode.TARGET)); 

// draw transparent on the "brown" pixels 
c.drawPaint(p); 

// mb should now have transparent pixels where they were red before 
+1

यह एपीआई स्तर 16 में काम नहीं कर रहा है, और AvoidXferMode को स्पष्टीकरण के बिना बहिष्कृत कर दिया गया है। यह समाधान वास्तव में एपीआई स्तर 15 के माध्यम से सभी तरह से काम करता है, हालांकि। –

+1

@LeoAccend स्रोत कोड के लिए परिवर्तन इतिहास को देखते हुए, ऐसा लगता है कि यह हार्डवेयर त्वरण के साथ समर्थित नहीं है। –

2

user487252's solution काम करता है।

मेरे विशेष उपयोग मामले में, मैंने एक पीडीएफ (एपीवी पीडीएफ व्यू के माध्यम से) को एक पिक्सेल सरणी int[] में एक पृष्ठ प्रस्तुत किया है जिसे मैं Bitmap.createBitmap(int[], int, int, Bitmap.Config) में पास करने जा रहा हूं। इस पृष्ठ में एक सफेद पृष्ठभूमि पर खींची गई रेखा कला है, और एंटी-एलियासिंग को संरक्षित करते समय मुझे पृष्ठभूमि को हटाने की आवश्यकता है।

मुझे पोर्टर-डफ मोड नहीं मिला जो वास्तव में वही था, इसलिए मैंने पिक्सल के माध्यम से बकलिंग और पुनरावृत्ति समाप्त कर दिया और उन्हें एक-एक करके बदल दिया। परिणाम आश्चर्यजनक रूप से सरल और performant था:

int [] pixels = ...; 

for(int i = 0; i < pixels.length; i++) { 
    // Invert the red channel as an alpha bitmask for the desired color. 
    pixels[i] = ~(pixels[i] << 8 & 0xFF000000) & Color.BLACK; 
} 

Bitmap bitmap = Bitmap.createBitmap(pixels, width, height, Bitmap.Config.ARGB_8888); 

यह ड्राइंग लाइन कला के लिए एकदम सही है, किसी भी रंग विरोधी aliasing खोने के बिना लाइनों के लिए इस्तेमाल किया जा सकता के बाद से। मैं यहां लाल चैनल का उपयोग कर रहा हूं, लेकिन आप 8 के बजाय 16 बिट्स को स्थानांतरित करके हरे रंग का उपयोग कर सकते हैं, या 24 स्थानांतरित करके नीला कर सकते हैं।

+0

मैं आपके कोड का उपयोग करना चाहता हूं, लेकिन मुझे इसके साथ कोई कस्टम रंग का उपयोग करने के बारे में कोई जानकारी नहीं है। कृपया –

+0

सहायता करें आप अलग-अलग रंगीन रेखाएं प्राप्त करने के लिए उपरोक्त कोड में 'Color.BLACK' को प्रतिस्थापित कर सकते हैं (उदा:' रंग .RED', या '0xFF3399FF')। –

+0

बहुत बहुत धन्यवाद! बहुत अच्छा काम करता है –

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