2012-08-22 5 views
34

के लिए लुमा कुंजी (छवि से अल्फा मास्क बनाएं) मैं एक ऐप बना रहा हूं जो लोगों को एक सफेद पृष्ठभूमि के खिलाफ स्वयं की छवि अपलोड करने की अनुमति देता है और ऐप व्यक्ति का सिल्हूट बना देगा।आईओएस

मुझे पृष्ठभूमि को बाहर करने में कठिनाई हो रही है। मैं GPUImage ढांचे का उपयोग कर रहा हूं और GPUImageChromaKeyBlendFilter रंगों के लिए बहुत अच्छा काम करता है, लेकिन यदि आप सफेद/काले हो जाते हैं तो उन रंगों में से एक को बाहर करना वाकई मुश्किल है। अगर मैं कुंजी को सफेद या काले रंग में सेट करता हूं तो यह दोनों एक ही है।

कोई सलाह?

+1

@ [ब्रैड लार्सन] (http://stackoverflow.com/users/19679/brad-larson) कहां है जब आपको उसकी ज़रूरत है! –

+0

GPUImageAlphaBlendFilter के आधार पर एक कस्टम फ़िल्टर बनाने का प्रयास करें, केवल लाल चैनल ('textureColor.r') के साथ अंतिम मिश्रण ऑपरेशन में अल्फा चैनल (' textureColor.a') को प्रतिस्थापित करें। यदि आपने इस छवि को खिलाने से पहले अपनी छवि को चमक में परिवर्तित कर दिया है, तो मेरा मानना ​​है कि पहली छवि के चमक के आधार पर चुनिंदा मिश्रण होना चाहिए। आप जिस प्रभाव को चाहते हैं उसे प्राप्त करने के लिए आपको मिश्रण आदेश को ट्विक करने की आवश्यकता हो सकती है। –

+0

आपके समय के लिए बहुत बहुत धन्यवाद! दुर्भाग्य से, ऐप अब क्रैश हो रहा है। स्पष्ट होने के लिए, क्या यह रेखा आप का जिक्र कर रही है: gl_FragColor = vec4 (मिश्रण (textureColor.rgb, textureColor2.rgb, textureColor2.a * mixPercent), textureColor.a); मैं केवल लाल रंग में कैसे पास करूं? मैंने जो कुछ भी कोशिश की, वह एक दुर्घटनाग्रस्त हो गया: में सम्मिलन विफलता - [GPUImageAlphaBlendFilter initWithVertexShaderFromString: fragmentShaderFromString:] –

उत्तर

0

तो, पारदर्शी करने के लिए एक सफेद को बदलने के लिए हम इस विधि का उपयोग कर सकते हैं:

-(UIImage *)changeWhiteColorTransparent: (UIImage *)image { 
    CGImageRef rawImageRef=image.CGImage; 

    const float colorMasking[6] = {222, 255, 222, 255, 222, 255}; 

    UIGraphicsBeginImageContext(image.size); 
    CGImageRef maskedImageRef=CGImageCreateWithMaskingColors(rawImageRef, colorMasking); 
    { 
     //if in iphone 
     CGContextTranslateCTM(UIGraphicsGetCurrentContext(), 0.0, image.size.height); 
     CGContextScaleCTM(UIGraphicsGetCurrentContext(), 1.0, -1.0); 
    } 

    CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, image.size.width, image.size.height), maskedImageRef); 
    UIImage *result = UIGraphicsGetImageFromCurrentImageContext(); 
    CGImageRelease(maskedImageRef); 
    UIGraphicsEndImageContext();  
    return result; 
} 

और काले के साथ गैर पारदर्शी पिक्सेल को बदलने के लिए, हम उपयोग कर सकते हैं:

- (UIImage *) changeColor: (UIImage *)image { 
    UIGraphicsBeginImageContext(image.size); 

    CGRect contextRect; 
    contextRect.origin.x = 0.0f; 
    contextRect.origin.y = 0.0f; 
    contextRect.size = [image size]; 
    // Retrieve source image and begin image context 
    CGSize itemImageSize = [image size]; 
    CGPoint itemImagePosition; 
    itemImagePosition.x = ceilf((contextRect.size.width - itemImageSize.width)/2); 
    itemImagePosition.y = ceilf((contextRect.size.height - itemImageSize.height)); 

    UIGraphicsBeginImageContext(contextRect.size); 

    CGContextRef c = UIGraphicsGetCurrentContext(); 
    // Setup shadow 
    // Setup transparency layer and clip to mask 
    CGContextBeginTransparencyLayer(c, NULL); 
    CGContextScaleCTM(c, 1.0, -1.0); 
    CGContextClipToMask(c, CGRectMake(itemImagePosition.x, -itemImagePosition.y, itemImageSize.width, -itemImageSize.height), [image CGImage]); 

    CGContextSetFillColorWithColor(c, [UIColor blackColor].CGColor); 


    contextRect.size.height = -contextRect.size.height; 
    contextRect.size.height -= 15; 
    // Fill and end the transparency layer 
    CGContextFillRect(c, contextRect); 
    CGContextEndTransparencyLayer(c); 

    UIImage *img = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    return img; 
} 

इतना अभ्यास इस में होगा:

-(UIImage *)silhouetteForImage:(UIImage *)img { 
    return [self changeColour:[self changeWhiteColorTransparent:img]]; 
} 

स्पष्ट रूप से आप इसे सब कुछ चलाने के लिए पृष्ठभूमि थ्रेड में कॉल करेंगे जी सुचारू रूप से।

0

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

- (CGImageRef)silhouetteOfImage:(UIImage *)input 
{ 
    CIContext *ciContext = [CIContext contextWithOptions:nil]; 
    CIImage *ciInput = [CIImage imageWithCGImage:[input CGImage]]; 
    CIFilter *filter = [CIFilter filterWithName:@"CIFalseColor"]; 
    [filter setValue:[CIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:1.0] forKey:@"inputColor0"]; 
    [filter setValue:[CIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.0] [email protected]"inputColor1"]; 
    [filter setValue:ciInput forKey:kCIInputImageKey]; 
    CIImage *outImage = [filter valueForKey:kCIOutputImageKey]; 
    CGImageRef result = [ciContext createCGImage:outImage fromRect:[ciInput extent]]; 
    return result; 
} 
0

कभी कभी क्या आप को प्राप्त करने के समझने मतभेद मदद कर सकता है की कोशिश कर रहे हैं और फिर से एक स्पष्टीकरण। आप पारदर्शिता बनाम पारदर्शिता को इकट्ठा करने के बारे में बात कर रहे हैं।

पारदर्शिता छवि पिक्सेल के लिए अल्फा मान और पृष्ठभूमि बफर पर किए गए मूल्यांकन के आधार पर पृष्ठभूमि को अग्रभूमि के साथ मिश्रित करने की अनुमति देने में अल्फा लेती है।

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

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

आपका छवि स्वरूप डेटाप्रकार या अल्फा मूल्यों के लिए pixelformat का समर्थन करता है, तो यह गणना करने के लिए काफी तुच्छ है:

अल्फा चमक के आधार पर = (आर + जी + बी)/3;

अल्फा चैनल प्रेसिडेंस = मैक्स (आर, जी, बी) पर आधारित अल्फा;

127 के अल्फा थ्रेसहोल्ड के साथ मिश्रित पारदर्शिता का मतलब यह होगा कि 127 या उससे कम के मूल्य वाले अल्फा परीक्षण को पार करने वाले प्रत्येक पिक्सेल को मिश्रित किया जाएगा और 127 से ऊपर वाले लोगों को हार्ड मास्क किया जाएगा।

मुझे आशा है कि थोड़ा स्पष्ट करने में मदद मिलेगी, बस अगर यह स्पष्ट नहीं है। बहुत बढ़िया कोड दोस्तों।

1

एक कारण है कि सफेद रंग की बजाय क्रोमो कीइंग के लिए फिल्म उत्पादन में आम तौर पर नीली या हरे रंग की स्क्रीन का उपयोग किया जाता है।किसी भी तस्वीर में सफेद या पर्याप्त रूप से सफेद हो सकता है, विशेष रूप से आंखों या हाइलाइट्स या त्वचा के कुछ हिस्सों में। इसके अलावा, छाया के बिना एक समान सफेद दीवार को खोजने में काफी मुश्किल होती है, कम से कम अपने विषय द्वारा डाली जाती है। मैं एक हिस्टोग्राम बनाने की सिफारिश करता हूं, सबसे चमकीले लोगों के बीच सबसे अधिक इस्तेमाल किया जाने वाला रंग ढूंढता हूं, फिर कुछ थ्रेसहोल्ड का उपयोग करके उस रंग के सबसे बड़े क्षेत्र की खोज करता हूं। फिर उस क्षेत्र से बाढ़ भरें जब तक कि पर्याप्त रूप से अलग-अलग रंग न हों। जब तक आप रीयलटाइम वीडियो स्ट्रीम नहीं चाहते हैं, तब तक यह सब सॉफ्टवेयर में काफी आसानी से किया जा सकता है।