2012-02-02 17 views
7

मेरे पास एक ऐसा एप्लिकेशन है जिसके लिए एक ठोस ब्लैक रूपरेखा आंशिक रूप से पारदर्शी UIImage के आसपास खींची जाए। छवि के फ्रेम के चारों ओर नहीं, बल्कि छवि के सभी अपारदर्शी हिस्सों के आसपास। यानी, एक पारदर्शी पीएनजी के बारे में सोचें जिसमें एक अपारदर्शी सफेद "एक्स" है - मुझे काले रंग में "एक्स" की रूपरेखा की आवश्यकता है।आईओएस: आंशिक रूप से पारदर्शी छवि के अपारदर्शी हिस्सों को रेखांकित करना

मामलों जटिल बनाने के लिए, के बाद रूपरेखा, तैयार की है मूल छवि की अस्पष्टता समायोजित किया जाएगा, लेकिन रूपरेखा अपारदर्शी रहना चाहिए - तो रूपरेखा मैं उत्पन्न केवल रूपरेखा, और नहीं शामिल करने के लिए है मूल छवि।

  • एक नया UIView जो मूल छवि के आयाम बनाएं:

    मेरे वर्तमान तकनीक यह है।

  • UIImage डुप्लिकेट करें UIView के उप-दृश्यों के रूप में डुप्लिकेट जोड़ें, प्रत्येक UIImage दो पिक्सेल द्वारा मूल स्थान से तिरछे ऑफसेट करें।
  • UIView को एक छवि में बदलें (सामान्य UIGraphicsGetImageFromCurrentImageContext विधि के माध्यम से)।
  • CGImageMaskCreate और CGImageCreateWithMask का उपयोग करके, इस नई छवि से मूल छवि घटाएं, इसलिए केवल रूपरेखा बनी हुई है।

यह काम करता है। यहां तक ​​कि केवल 4 ऑफ़सेट छवियों के साथ, परिणाम काफी अच्छा लगता है। हालांकि, यह बेहद अक्षम है, और आईफोन 4 पर एक अच्छी ठोस 4-सेकंड देरी का कारण बनता है।

तो मुझे एक ही चीज़ प्राप्त करने के लिए एक अच्छा, तेज़, कुशल तरीका है, जो आईओएस 4.0 द्वारा पूरी तरह से समर्थित है।

कोई भी महान विचार? :)

+0

आपको यूआई/सीजी सामान का उपयोग कर सीधे छवि डेटा में हेरफेर करने में सक्षम होना चाहिए। तो कदम काफी तेजी से होना चाहिए। छवि प्रारूप को समझना बहुत मुश्किल नहीं है। मुख्य चाल यह है कि जब आप छवियों को एक साथ जोड़ते हैं तो आपको प्रत्येक पिक्सेल को 4 (शिफ्ट दाएं 2) को विभाजित करने की आवश्यकता होती है ताकि यह सुनिश्चित किया जा सके कि कोई अतिप्रवाह नहीं होता है। –

+0

आप अपने लक्ष्य को प्राप्त करने के लिए अन्य योजनाओं के लिए "एज डिटेक्शन" पर भी अध्ययन करना चाहेंगे। –

+0

[यह धागा] (http://stackoverflow.com/questions/6052188/high-quality-scaling-of-uiimage) आपको UIImage को "क्रैक" करने के बारे में कुछ विचार दे सकता है। –

उत्तर

3

मैं यह इंगित करना चाहता हूं कि कुछ लोगों ने किनारे का पता लगाने का सुझाव दिया है, यह उचित समाधान नहीं है। एज डिटेक्शन छवि डेटा के भीतर किनारों को ढूंढने के लिए है जहां डेटा में कोई स्पष्ट सटीक किनारा प्रतिनिधित्व नहीं है।

आपके लिए, किनारों को अच्छी तरह से परिभाषित किया गया है, आप अच्छी तरह से परिभाषित रूपरेखा की तलाश में हैं। आपके मामले में एक किनारा कोई पिक्सेल है जो पूरी तरह पारदर्शी पिक्सेल पर है और एक पिक्सेल के बगल में है जो पूरी तरह से पारदर्शी नहीं है, उतना आसान है! छवि में प्रत्येक पिक्सेल के माध्यम से पुनरावृत्त करें और यदि वे इन शर्तों को पूरा करते हैं तो उन्हें काले रंग में सेट करें।

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

चीयर्स, उम्मीद है कि इससे मदद मिलती है।

+0

यह सबसे सरल दृष्टिकोण की तरह लगता है। अगर यह काम करता है तो वापस टिप्पणी करेगा। धन्यवाद! – DanM

+0

मुझे उम्मीद है कि यह करता है :)! –

+0

मैंने छोटे उत्तर वाले सर्कल कर्नेल की बजाय इस उत्तर के साथ एक छोटी गलती की है, यह एक छोटे एंटी-एलाइज्ड सर्कल कर्नेल का उपयोग करने के लिए अधिक उपयुक्त होगा। एक महत्वपूर्ण भेद, क्षमा करें! शुक्रवार को 5:35 बजे के बाद जब मैंने इसे पोस्ट किया, और मैं 5:30 बजे काम छोड़ देता हूं;)। –

1

आपको केवल edge detection एल्गोरिदम लागू करने की आवश्यकता है, लेकिन किनारों के किनारे निर्धारित करने के लिए चमक या रंग का उपयोग करने की बजाय, अस्पष्टता का उपयोग करें। इसके बारे में जाने के कई तरीके हैं। उदाहरण के लिए, आप प्रत्येक पिक्सेल और पड़ोसियों को ऐसे क्षेत्रों की पहचान करने के लिए देख सकते हैं जहां अस्पष्टता आपके द्वारा सेट की गई सीमा को पार करती है। जब भी आपको MacOS X या iOS में किसी छवि के प्रत्येक पिक्सेल को देखने की आवश्यकता होती है, तो Core Image सोचें। ब्लॉग पोस्ट starting with this one की एक सहायक श्रृंखला है जो कस्टम कोर छवि फ़िल्टर को कार्यान्वित करने पर लगती है - मैं किनारे का पता लगाने फ़िल्टर बनाने के लिए वहां से शुरू करूंगा।

+1

आम तौर पर अच्छी सलाह है लेकिन मुझे नहीं लगता कि वर्तमान में कोर छवि के आईओएस कार्यान्वयन पर कस्टम फ़िल्टर समर्थित हैं। इसलिए लेखक को सीपीयू बिटमैप संदर्भ में सामग्री को सीपीयू एक्सेस प्राप्त करने के उद्देश्य से वहां फ़िल्टर को चलाने की आवश्यकता होगी और वहां फ़िल्टर चलाएं (उम्मीद है कि जीसीडी से सहायता के साथ)। – Tommy

+0

यह जाने के लिए एक व्यवहार्य तरीका प्रतीत होता है - और मुझे लगता है कि 1px से मोटा किनारा खींचने के लिए एल्गोरिदम समायोजित करना संभव है। हालांकि, इससे पहले कि मैं इसे लागू करने में काफी समय बिताता हूं (यह तुच्छ नहीं लगता है) अब आप जिस विधि का उपयोग कर रहे हैं उसकी तुलना में आप कितनी कुशलता से उम्मीद करेंगे? – DanM

+0

@ टॉमी दोह! [ऐसा लगता है कि आप कस्टम फ़िल्टर के बारे में सही हैं] (http://www.raywenderlich.com/5689/beginning-core-image-in-ios-5) आईओएस पर समर्थित नहीं है। बहुत बुरा। – Caleb

2

नए विचारों योगदान की खातिर:

अपने वर्तमान कार्यान्वयन छाया के लिए CALayer के समर्थन है, जो यह वास्तविक पिक्सेल के बजाय केवल उसके सीमांकन आयत परत की सामग्री से गणना करता है का प्रयोग करेंगे का एक और प्रकार है, और जिसके लिए यह जीपीयू का उपयोग करता है। पंख को खत्म करने की कोशिश करने के लिए आप कुछ बड़े पैमाने पर shadowOpacity को अपनाने का प्रयास कर सकते हैं; यह असफल हो रहा है कि आप एक उपयुक्त CGContext को प्रस्तुत कर सकते हैं, केवल अल्फा परत लें और इसे अल्फा मानों पर थ्रेसहोल्ड परीक्षण लागू करने के लिए मैन्युअल रूप से संसाधित करें, जिससे उन्हें पूरी तरह से अपारदर्शी या पूरी तरह से पारदर्शी बना दिया जा सके।

आप विभिन्न तरीकों से ईएस 1 के तहत भी जीपीयू पर अंतिम प्रसंस्करण चरण प्राप्त कर सकते हैं। आप वास्तविक दहलीज को लागू करने के लिए अल्फा परीक्षण का उपयोग करेंगे, फिर आप कह सकते हैं, गहराई बफर 1.0 को प्राथमिकता दें, रंग आउटपुट और गहराई परीक्षण अक्षम करें, संस्करण को 0.5 की गहराई पर छाया के साथ खींचें, बिना संस्करण को खींचें 1.0 की गहराई पर छाया फिर रंग आउटपुट और गहराई परीक्षण सक्षम करती है और 0.75 की गहराई पर एक ठोस काला पूर्ण-स्क्रीन ट्रैक्टर खींचती है।तो यह स्टैंसिल का अनुकरण करने के लिए गहराई बफर का उपयोग करना है (चूंकि ईएस 2 सक्षम डिवाइस से पहले इस्तेमाल होने वाले जीपीयू ऐप्पल को स्टैंसिल बफर का समर्थन नहीं किया गया था)।

यह निश्चित रूप से मानता है कि CALayer छाया कंपोजिटर के बाहर दिखाई देती है, जिसे मैंने चेक नहीं किया है।

वैकल्पिक रूप से, यदि आप ईएस 2 उपकरणों (सब कुछ 3 जीएस +) में अपना समर्थन सीमित करने के इच्छुक हैं तो आप अपनी छवि को बनावट के रूप में अपलोड कर सकते हैं और पूरी प्रक्रिया को GPU पर कर सकते हैं। लेकिन यह तकनीकी रूप से कुछ आईओएस 4 सक्षम डिवाइसों को असमर्थित छोड़ देगा, इसलिए मुझे लगता है कि यह विकल्प नहीं है।

+0

असल में, इस मामले में, जब तक मैं उपयोगकर्ता के डिवाइस का परीक्षण कर सकता हूं (यानी, सुनिश्चित करें कि यह कम से कम 3 जीएस है, आदि), और पुराने उपकरणों के लिए वैकल्पिक विधि का उपयोग करें, यह ठीक होगा। क्या सीखने के लिए कोई अच्छा स्रोत है कि मैं उस तकनीक का उपयोग करने के बारे में कैसे जाऊंगा? – DanM

0

बजाय UIView का उपयोग कर, मैं सिर्फ निम्नलिखित की तरह एक संदर्भ धक्का सलाह देते हैं:

UIGraphicsBeginImageContextWithOptions(image.size,NO,0.0); 
//draw your image 4 times and mask it whatever you like, you can just copy & paste 
//current drawing code here. 
.... 
outlinedimage = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 

यह आपके UIView की तुलना में बहुत तेजी से किया जाएगा।

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