मैं iOS 7 कलंक दृश्य के समान प्रभाव कैसे उत्पन्न कर सकता हूं?


219

मैं Apple की सार्वजनिक रूप से जारी iOS 7 उदाहरण स्क्रीन से इस धुंधली पृष्ठभूमि को दोहराने की कोशिश कर रहा हूं:

iOS 7 कंट्रोल सेंटर स्क्रीनशॉट

यह प्रश्न नीचे दी गई सामग्री में CI फ़िल्टर लागू करने का सुझाव देता है, लेकिन यह एक पूरी तरह से अलग दृष्टिकोण है। यह स्पष्ट है कि iOS 7 नीचे दिए गए विचारों की सामग्री को कई कारणों से कैप्चर नहीं करता है:

  1. कुछ मोटे परीक्षण करते हुए, नीचे दिए गए दृश्यों के स्क्रीनशॉट को कैप्चर करना और iOS 7 7 की कलंक शैली की नकल करने के लिए एक बड़े पर्याप्त त्रिज्या के साथ CIGaussianBlur फ़िल्टर को लागू करना, एक सिम्युलेटर पर भी 1-2 सेकंड लगते हैं।
  2. आईओएस 7 ब्लर दृश्य गतिशील विचारों जैसे कि वीडियो या एनिमेशन के साथ, ध्यान देने योग्य अंतराल के साथ धुंधला करने में सक्षम है।

क्या कोई भी इस प्रभाव को बनाने के लिए वे किन रूपरेखाओं का उपयोग कर सकता है, और यदि वर्तमान सार्वजनिक एपीआई के साथ इसी तरह का प्रभाव पैदा करना संभव है?

संपादित करें: (टिप्पणी से) हम बिल्कुल नहीं जानते कि एप्पल यह कैसे कर रहा है, लेकिन क्या हम कोई बुनियादी धारणा बना सकते हैं? हम मान सकते हैं कि वे हार्डवेयर का उपयोग कर रहे हैं, है ना?

क्या प्रभाव प्रत्येक दृष्टिकोण में आत्म-निहित है, जैसे कि प्रभाव वास्तव में नहीं जानता कि इसके पीछे क्या है? या, ब्लर कैसे काम करता है, इसके आधार पर, ब्लर के पीछे की सामग्री को ध्यान में रखा जाना चाहिए?

यदि प्रभाव के पीछे की सामग्री प्रासंगिक है, तो क्या हम मान सकते हैं कि Apple को नीचे दी गई सामग्री का "फ़ीड" प्राप्त हो रहा है और लगातार उन्हें एक धब्बा के साथ प्रदान कर रहा है?


(मुझे लगता है कि हम मान सकते हैं कि ऐप्पल जीएल का उपयोग शुद्ध स्क्रीन को वैसे भी रेंडर करने के लिए कर रहा है। मुझे संदेह है कि वे इसे यूआईवीवाई और अन्य चीजों के साथ अमूर्त कर रहे हैं जो प्रदर्शन को नीचा दिखा देंगे, क्योंकि यह ओएस का इतना महत्वपूर्ण हिस्सा है)
डेव

जैसा कि मैंने यहां अपने जवाब में टिप्पणियों में संकेत दिया है: stackoverflow.com/a/17048668/19679 उन्होंने OS लिखा, इसलिए निश्चित रूप से वे वर्तमान दृश्य के नीचे संयोजित परतों की सामग्री तक त्वरित पहुंच बनाने जा रहे हैं। हम कुछ देख सकते हैं कि वे निजी IOSurface API: stackoverflow.com/questions/14135215/… में क्या उपयोग कर रहे हैं । यदि एक निश्चित त्रिज्या है, या यहां तक ​​कि अभिन्न छवियों की तरह दिलचस्प अनुकूलन का उपयोग करते हैं, तो सामान्यीकृत गाऊसी धुंधला मामलों की तुलना में गाऊसी ब्लर्स को बहुत तेजी से बनाया जा सकता है।
ब्रैड लार्सन

@BradLarson - जेसिका सिम्पसन को पैराशूट करने के लिए ... मुझे नहीं पता कि इसका क्या मतलब है, लेकिन यह बिल्ली के रूप में अच्छा लगता है! लेकिन गंभीरता से, क्या आप कह रहे हैं कि आप आ ब्लर फिल्टर के साथ आंशिक रूप से पारदर्शी दृश्य का उपयोग कर सकते हैं और इस प्रभाव को प्राप्त करने के लिए इसे किसी अन्य दृश्य पर रख सकते हैं?
संगी

stackoverflow.com/a/25706250/2308190 ने पहली बार मेरे लिए पूरी तरह से काम किया, मैंने इसे आजमाया, और संक्षिप्त था
बेन व्हीलर

जवाबों:


134

प्रभाव को दोहराते हुए परेशान क्यों? बस अपने विचार के पीछे एक UIToolbar ड्रा करें।

myView.backgroundColor = [UIColor clearColor];
UIToolbar* bgToolbar = [[UIToolbar alloc] initWithFrame:myView.frame];
bgToolbar.barStyle = UIBarStyleDefault;
[myView.superview insertSubview:bgToolbar belowSubview:myView];

8
मैं crizzwald से असहमत हूं। मुझे नहीं लगता कि APple क्या करेगा, इसकी अपेक्षा के नियमों की एक अच्छी व्याख्या है।
एंड्रयू जॉनसन

117
मैं इस हफ्ते एक Apple UIKit इंजीनियर द्वारा उनके टेक टॉक्स लैब में इस दृष्टिकोण से भागा। हालांकि वह निश्चित रूप से इस दृष्टिकोण का समर्थन नहीं करेंगे, उन्होंने इसके लिए प्रभाव और वास्तविक सार्वजनिक एपीआई की कमी की आवश्यकता को पहचाना, और कहा कि यह दृष्टिकोण अभी के लिए "कम से कम बुराई" विकल्प था और लिखित रूप में काफी सुरक्षित है। विशेष रूप से उन्होंने कहा की किसी भी एनिमेशन करने की कोशिश नहीं करते हैं frameया transformइस टूलबार / दृश्य या ऐसा कुछ है, या खराब चीज़ें होंगी की। उन्होंने इस पर रडार बग रिपोर्ट दर्ज करने का भी दृढ़ता से सुझाव दिया, ताकि आंतरिक रूप से मामला बनाया जा सके ताकि हम इस आशय के लिए एक वास्तविक सार्वजनिक एपीआई प्राप्त कर सकें!
स्माइबॉर्ग

44
दिलचस्प ... ऐसा लगता है कि खाता @ user2342340 केवल इस प्रश्न का उत्तर देने के लिए बनाया गया था। आपको आश्चर्य होता है कि क्या यह किसी के द्वारा अनौपचारिक पोस्ट नहीं है जो इन चीजों के बारे में हम में से बाकी लोगों से अधिक जानता है :)
5

4
आईओएस 4 पर चलने वाले आईफोन 4 पर यह काम नहीं करता है। यह शायद इसलिए है क्योंकि आईफोन 4 में, चूंकि जीपीयू की शक्ति बहुत कम है, इसलिए सिस्टम UITabBarस्वयं के लिए सामान्य ब्लर प्रभाव को नहीं जोड़ता है।
आयुष गोयल

2
मैं इसे गैर-सफेद कैसे बनाऊं? यदि मैं टूलबार के लिए पृष्ठभूमि का रंग बदलता हूं, तो यह धब्बा नहीं दिखाता है।
निकिता पी।

64

Apple ने WWDC में UIImage पर एक श्रेणी के रूप में कोड जारी किया, जिसमें यह कार्यक्षमता शामिल है, यदि आपके पास एक डेवलपर खाता है तो आप इस लिंक पर जाकर UIImage श्रेणी (और बाकी नमूना कोड) हड़प सकते हैं: https://developer.apple। com / wwdc / schedule / और धारा 226 के लिए ब्राउज़िंग और विवरण पर क्लिक करें। मैंने अभी तक इसके साथ नहीं खेला है, लेकिन मुझे लगता है कि प्रभाव आईओएस 6 पर बहुत धीमा होगा, आईओएस 7 के लिए कुछ संवर्द्धन हैं जो प्रारंभिक स्क्रीन शॉट को हथियाने का काम करते हैं जो धब्बा के इनपुट के रूप में बहुत तेजी से उपयोग किया जाता है।

सीधा लिंक: https://developer.apple.com/downloads/download.action?path=wwdc_2013/wwdc_2013_sample_code/ios_uiimageeffects.zip


1
मैं वीडियो देखता हूं, मैं इसे देख सकता हूं, लेकिन यह पता नहीं लगा सकता कि नमूना कोड कहां डाउनलोड करना है!
नाथन एच।

मुझे एक साधारण पृष्ठभूमि अल्फा परिवर्तन की तुलना में बहुत अंतर नहीं दिखाई दिया; शायद यह इसलिए है क्योंकि मैं वीडियो प्रदर्शित कर रहा हूं और उन्हें सिर्फ और अधिक कलंक चाहिए ...
Jackck

37

वास्तव में मुझे यकीन है कि यह हासिल करना सरल होगा। यह शायद संचालित नहीं होगा या बिल्कुल वैसा ही दिखेगा जैसा कि Apple पर चल रहा है लेकिन वह बहुत करीब हो सकता है।

सबसे पहले, आपको UIVIV के CGRect को निर्धारित करना होगा जिसे आप प्रस्तुत कर रहे हैं। एक बार जब आप यह निर्धारित कर लेते हैं कि आपको बस यूआई के हिस्से की एक छवि को हथियाने की आवश्यकता होगी ताकि इसे धुंधला किया जा सके। कुछ इस तरह...

- (UIImage*)getBlurredImage {
    // You will want to calculate this in code based on the view you will be presenting.
    CGSize size = CGSizeMake(200,200);

    UIGraphicsBeginImageContext(size);
    [view drawViewHierarchyInRect:(CGRect){CGPointZero, w, h} afterScreenUpdates:YES]; // view is the view you are grabbing the screen shot of. The view that is to be blurred.
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    // Gaussian Blur
    image = [image applyLightEffect];

    // Box Blur
    // image = [image boxblurImageWithBlur:0.2f];

    return image;
}

गाऊसी ब्लर - अनुशंसित

यहां दिएUIImage+ImageEffects गए श्रेणी Apple के उपयोग से , आपको एक गाऊसी धब्बा मिलेगा जो iOS 7 में धब्बा की तरह दिखता है।

बॉक्स ब्लर

आप निम्नलिखित boxBlurImageWithBlur:UIImage श्रेणी का उपयोग करके एक बॉक्स ब्लर का उपयोग भी कर सकते हैं । यह एक अल्गोरिथम पर आधारित है जिसे आप यहां पा सकते हैं ।

@implementation UIImage (Blur)

-(UIImage *)boxblurImageWithBlur:(CGFloat)blur {
    if (blur < 0.f || blur > 1.f) {
        blur = 0.5f;
    }
    int boxSize = (int)(blur * 50);
    boxSize = boxSize - (boxSize % 2) + 1;

    CGImageRef img = self.CGImage;

    vImage_Buffer inBuffer, outBuffer;

    vImage_Error error;

    void *pixelBuffer;

    CGDataProviderRef inProvider = CGImageGetDataProvider(img);
    CFDataRef inBitmapData = CGDataProviderCopyData(inProvider);

    inBuffer.width = CGImageGetWidth(img);
    inBuffer.height = CGImageGetHeight(img);
    inBuffer.rowBytes = CGImageGetBytesPerRow(img);

    inBuffer.data = (void*)CFDataGetBytePtr(inBitmapData);

    pixelBuffer = malloc(CGImageGetBytesPerRow(img) * CGImageGetHeight(img));

    if(pixelBuffer == NULL)
        NSLog(@"No pixelbuffer");

    outBuffer.data = pixelBuffer;
    outBuffer.width = CGImageGetWidth(img);
    outBuffer.height = CGImageGetHeight(img);
    outBuffer.rowBytes = CGImageGetBytesPerRow(img);

    error = vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer, NULL, 0, 0, boxSize, boxSize, NULL, kvImageEdgeExtend);

    if (error) {
        NSLog(@"JFDepthView: error from convolution %ld", error);
    }

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef ctx = CGBitmapContextCreate(outBuffer.data,
                                         outBuffer.width,
                                         outBuffer.height,
                                         8,
                                         outBuffer.rowBytes,
                                         colorSpace,
                                         kCGImageAlphaNoneSkipLast);
    CGImageRef imageRef = CGBitmapContextCreateImage (ctx);
    UIImage *returnImage = [UIImage imageWithCGImage:imageRef];

    //clean up
    CGContextRelease(ctx);
    CGColorSpaceRelease(colorSpace);

    free(pixelBuffer);
    CFRelease(inBitmapData);

    CGImageRelease(imageRef);

    return returnImage;
}

@end

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

आशा करता हूँ की ये काम करेगा।


ऐसा लगता है कि धुंधली छवि का नीला रंग और लाल रंग स्वाहा हो गया है।
हेनरी

ऐसा लगता है कि किसी ने इस प्रोजेक्ट को बनाने के लिए आपके कोड का उपयोग किया है: github.com/alexdrone/ios-realtimeblur/blob/master/RealTimeBlur/… लेकिन दुर्भाग्य से कोई अटेंशन नहीं है, और उन्होंने "ऑल राइट्स रिजर्व्ड" कॉपीराइट स्टेटमेंट जोड़ा है शीर्ष पर।
मार्क एर्दमान

@ मर्क, सिर के लिए धन्यवाद। हालाँकि, यह धुंधला एल्गोरिथ्म मेरा अपना नहीं है। मैंने पहले ही उल्लेख कर दिया है कि मुझे अपने पोस्ट में यह कहां से मिला है। जैसा कि मेरी पोस्ट में कहा गया है "यह एक अल्गोरिथम पर आधारित है जिसे आप यहां पा सकते हैं।" indieambitions.com/idevblogaday/… के लिंक के साथ मैं निश्चित रूप से इस व्यक्ति को एक संदेश भेजूंगा और उन्हें बता दूंगा कि वे लापता हैं। साभार
जेरेमी फॉक्स

@MarkErdmann अपनी खुद की फ़ाइलों को xcode पर देखें। इसमें "सर्वाधिकार सुरक्षित" है। इसकी एक सामान्य बात है कि एक्सकोड जोड़ता है। इसके अलावा लेखक ने सिर्फ एक लाइसेंस जोड़ा। जो कहते हैं कि मिट लिज़नेस के तहत इसका लाइसेन्स
सांता क्लॉस

उपयोग न करें renderInContext, नए का उपयोग करें drawViewHierarchyInRect:या snapshotView:। WWDC की बात करें तो 216 "iOS7 पर यूआई को लागू करना" 5-15x प्रदर्शन सुधार का दावा करता है।
bcattle

25

iOS8 ने इन सवालों के जवाब दिए।

UIVisualEffect

- (instancetype)initWithEffect:(UIVisualEffect *)effect

या स्विफ्ट:

init(effect effect: UIVisualEffect)


मुझे लगता है कि यह समाधान ज्यादातर बेकार है जब तक कि iOS 9 बाहर नहीं है। अधिकांश एप्लिकेशन अभी भी iOS 7 का समर्थन करते हैं, और यह समाधान वहां समर्थित नहीं है।
दिमित्री सोबोलेव

सच सच, आप इस तरह की चीज़ों के लिए अभी उपयोग कर सकते हैं: github.com/nicklockwood/FXBlurView
एडम वेट

मैंने इसे iOS8 के साथ Xcode 6 टूलचैन के साथ लागू किया, और यह बहुत अच्छा काम करता है। मैंने सीपीयू का उपयोग करके कार्यान्वित करने की कोशिश की, लेकिन इस पद्धति की तुलना में काफी धीमी गति से काम करता है।
जॉन

कोड क्यों जब स्टोरीबोर्ड में Xcode प्रदान करता है !!!!! धन्यवाद @AdamWaite
मिहिर ओझा

20

मैंने अभी-अभी UIVIV का अपना छोटा उपवर्ग लिखा है, जिसमें किसी भी कस्टम दृश्य पर देशी iOS 7 कलंक का उत्पादन करने की क्षमता है। यह UIToolbar का उपयोग करता है, लेकिन यह वास्तविक समय के एनीमेशन के साथ फ्रेम, सीमा, रंग और अल्फा को बदलने के लिए एक सुरक्षित तरीके से उपयोग करता है।

यदि आपको कोई समस्या है तो कृपया मुझे बताएँ।

https://github.com/ivoleko/ILTranslucentView

ILTranslucentView उदाहरण


मैंने कुछ अन्य दृष्टिकोणों की कोशिश की है (जैसे कि खुद UIToolbar जोड़ना, या Apple का UIImage + ImageEffects.h श्रेणी); आपका सबसे अच्छा और आसान उपाय था। धन्यवाद!
यूनुस नेदिम मेहेल

4
नए iOS 7.0.3 डाउनलोड पर यह कितनी अच्छी प्रतिक्रिया देता है? इस तकनीक का उपयोग करने वाले अन्य वर्ग अब सही ढंग से प्रस्तुत नहीं करते हैं: [
achi

@ यूची, मुझे iOS 7.0.3 के साथ कोई समस्या नज़र नहीं आई।
इवो ​​लेको

क्या आपको पता है कि कोई भी ऐप जो आपके दृष्टिकोण का उपयोग कर रहा है और Apple द्वारा स्वीकार किया गया है?
ब्रैड गॉस

हाय दोस्तों। हां, इस वर्ग का उपयोग करने वाले ऐप को ऐप्पल द्वारा अनुमोदित किया जाएगा!
इवो ​​लेको

10

एक अफवाह है कि Apple इंजीनियरों ने दावा किया, इस प्रदर्शन को बनाने के लिए वे सीधे gpu बफर से बाहर पढ़ रहे हैं जो सुरक्षा के मुद्दों को उठाता है यही कारण है कि अभी तक ऐसा करने के लिए कोई सार्वजनिक एपीआई नहीं है।


6
अगर यह सच है, तो यह है - अब तक - सबसे खराब समाधान।
elslooo

2
Aaaaaand धब्बा iOS 7 से हटा दिया जाता है
कोड गुरु

3
यह केवल उन उपकरणों पर हटा दिया गया था जो प्रदर्शन के मुद्दों को देख रहे थे।
कोडी सी।

24
क्या यह पोस्ट अफवाह का स्रोत है? :)
जनेऊ

11
वह अफवाह शायद चारपाई है। IOS पर OpenGL ES 2.0 आपको बिना किसी सुरक्षा जोखिम के फ्रेमबायर्स को पढ़ने और लिखने की अनुमति देता है। धुंधला GLSL शेड्स का उपयोग करके किया जाता है, यही वजह है कि यह तेजी से चलता है।
बेंटफोर्ड

7

यह एक ऐसा समाधान है जिसे आप WWDC के vidios में देख सकते हैं। आपको एक गौसियन ब्लर करना है, इसलिए पहली चीज जो आपको करनी है वह है एक नया .m और .h फ़ाइल जो कि मैं यहाँ लिख रहा हूँ, उसके बाद आपको बनाना है और स्क्रीन शूट करना है, वांछित प्रभाव का उपयोग करना है। इसे अपने दृश्य में जोड़ें, फिर आपका UIVable UIView या जिसे कभी भी पारदर्शी होना है, आप वांछित प्रभाव को संग्रहित करने के लिए applyBlurWithRadius के साथ खेल सकते हैं, यह कॉल किसी भी UIImage के साथ काम करता है।

अंत में ब्लर इमेज बैकग्राउंड होगी और ऊपर दिए गए बाकी कंट्रोल पारदर्शी होने चाहिए।

इसके लिए आपको अगले पुस्तकालयों को जोड़ना होगा:

Acelerate.framework, UIKit.framework, CoreGraphics.framework

मुझे उम्मीद है आप इसे पसंद करेंगे।

खुश कोडिंग।

    //Screen capture.
    UIGraphicsBeginImageContext(self.view.bounds.size);

    CGContextRef c = UIGraphicsGetCurrentContext();
    CGContextTranslateCTM(c, 0, 0);
    [self.view.layer renderInContext:c];

    UIImage* viewImage = UIGraphicsGetImageFromCurrentImageContext();
    viewImage = [viewImage applyLightEffect];

    UIGraphicsEndImageContext();

    //.h FILE
    #import <UIKit/UIKit.h>

    @interface UIImage (ImageEffects)

   - (UIImage *)applyLightEffect;
   - (UIImage *)applyExtraLightEffect;
   - (UIImage *)applyDarkEffect;
   - (UIImage *)applyTintEffectWithColor:(UIColor *)tintColor;

   - (UIImage *)applyBlurWithRadius:(CGFloat)blurRadius tintColor:(UIColor *)tintColor saturationDeltaFactor:(CGFloat)saturationDeltaFactor maskImage:(UIImage *)maskImage;

   @end

    //.m FILE
    #import "cGaussianEffect.h"
    #import <Accelerate/Accelerate.h>
    #import <float.h>


     @implementation UIImage (ImageEffects)


    - (UIImage *)applyLightEffect
    {
        UIColor *tintColor = [UIColor colorWithWhite:1.0 alpha:0.3];
        return [self applyBlurWithRadius:1 tintColor:tintColor saturationDeltaFactor:1.8 maskImage:nil];
    }


    - (UIImage *)applyExtraLightEffect
    {
        UIColor *tintColor = [UIColor colorWithWhite:0.97 alpha:0.82];
        return [self applyBlurWithRadius:1 tintColor:tintColor saturationDeltaFactor:1.8 maskImage:nil];
    }


    - (UIImage *)applyDarkEffect
    {
        UIColor *tintColor = [UIColor colorWithWhite:0.11 alpha:0.73];
        return [self applyBlurWithRadius:1 tintColor:tintColor saturationDeltaFactor:1.8 maskImage:nil];
    }


    - (UIImage *)applyTintEffectWithColor:(UIColor *)tintColor
    {
        const CGFloat EffectColorAlpha = 0.6;
        UIColor *effectColor = tintColor;
        int componentCount = CGColorGetNumberOfComponents(tintColor.CGColor);
        if (componentCount == 2) {
            CGFloat b;
            if ([tintColor getWhite:&b alpha:NULL]) {
                effectColor = [UIColor colorWithWhite:b alpha:EffectColorAlpha];
            }
        }
        else {
            CGFloat r, g, b;
            if ([tintColor getRed:&r green:&g blue:&b alpha:NULL]) {
                effectColor = [UIColor colorWithRed:r green:g blue:b alpha:EffectColorAlpha];
            }
        }
        return [self applyBlurWithRadius:10 tintColor:effectColor saturationDeltaFactor:-1.0 maskImage:nil];
    }


    - (UIImage *)applyBlurWithRadius:(CGFloat)blurRadius tintColor:(UIColor *)tintColor saturationDeltaFactor:(CGFloat)saturationDeltaFactor maskImage:(UIImage *)maskImage
    {
        if (self.size.width < 1 || self.size.height < 1) {
            NSLog (@"*** error: invalid size: (%.2f x %.2f). Both dimensions must be >= 1: %@", self.size.width, self.size.height, self);
            return nil;
        }
        if (!self.CGImage) {
            NSLog (@"*** error: image must be backed by a CGImage: %@", self);
            return nil;
        }
        if (maskImage && !maskImage.CGImage) {
            NSLog (@"*** error: maskImage must be backed by a CGImage: %@", maskImage);
            return nil;
        }

        CGRect imageRect = { CGPointZero, self.size };
        UIImage *effectImage = self;

        BOOL hasBlur = blurRadius > __FLT_EPSILON__;
        BOOL hasSaturationChange = fabs(saturationDeltaFactor - 1.) > __FLT_EPSILON__;
        if (hasBlur || hasSaturationChange) {
            UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]);
            CGContextRef effectInContext = UIGraphicsGetCurrentContext();
            CGContextScaleCTM(effectInContext, 1.0, -1.0);
            CGContextTranslateCTM(effectInContext, 0, -self.size.height);
            CGContextDrawImage(effectInContext, imageRect, self.CGImage);

            vImage_Buffer effectInBuffer;
            effectInBuffer.data     = CGBitmapContextGetData(effectInContext);
            effectInBuffer.width    = CGBitmapContextGetWidth(effectInContext);
            effectInBuffer.height   = CGBitmapContextGetHeight(effectInContext);
            effectInBuffer.rowBytes = CGBitmapContextGetBytesPerRow(effectInContext);

            UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]);
            CGContextRef effectOutContext = UIGraphicsGetCurrentContext();
            vImage_Buffer effectOutBuffer;
            effectOutBuffer.data     = CGBitmapContextGetData(effectOutContext);
            effectOutBuffer.width    = CGBitmapContextGetWidth(effectOutContext);
            effectOutBuffer.height   = CGBitmapContextGetHeight(effectOutContext);
            effectOutBuffer.rowBytes = CGBitmapContextGetBytesPerRow(effectOutContext);

            if (hasBlur) {
                CGFloat inputRadius = blurRadius * [[UIScreen mainScreen] scale];
                NSUInteger radius = floor(inputRadius * 3. * sqrt(2 * M_PI) / 4 + 0.5);
                if (radius % 2 != 1) {
                    radius += 1;
                }
                vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, NULL, 0, 0, radius, radius, 0, kvImageEdgeExtend);
                vImageBoxConvolve_ARGB8888(&effectOutBuffer, &effectInBuffer, NULL, 0, 0, radius, radius, 0, kvImageEdgeExtend);
                vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, NULL, 0, 0, radius, radius, 0, kvImageEdgeExtend);
            }
            BOOL effectImageBuffersAreSwapped = NO;
            if (hasSaturationChange) {
                CGFloat s = saturationDeltaFactor;
                CGFloat floatingPointSaturationMatrix[] = {
                    0.0722 + 0.9278 * s,  0.0722 - 0.0722 * s,  0.0722 - 0.0722 * s,  0,
                    0.7152 - 0.7152 * s,  0.7152 + 0.2848 * s,  0.7152 - 0.7152 * s,  0,
                    0.2126 - 0.2126 * s,  0.2126 - 0.2126 * s,  0.2126 + 0.7873 * s,  0,
                                  0,                    0,                    0,  1,
                };
                const int32_t divisor = 256;
                NSUInteger matrixSize = sizeof(floatingPointSaturationMatrix)/sizeof(floatingPointSaturationMatrix[0]);
                int16_t saturationMatrix[matrixSize];
                for (NSUInteger i = 0; i < matrixSize; ++i) {
                    saturationMatrix[i] = (int16_t)roundf(floatingPointSaturationMatrix[i] * divisor);
                }
                if (hasBlur) {
                    vImageMatrixMultiply_ARGB8888(&effectOutBuffer, &effectInBuffer, saturationMatrix, divisor, NULL, NULL, kvImageNoFlags);
                    effectImageBuffersAreSwapped = YES;
                }
                else {
                    vImageMatrixMultiply_ARGB8888(&effectInBuffer, &effectOutBuffer, saturationMatrix, divisor, NULL, NULL, kvImageNoFlags);
                }
            }
            if (!effectImageBuffersAreSwapped)
                effectImage = UIGraphicsGetImageFromCurrentImageContext();
            UIGraphicsEndImageContext();

            if (effectImageBuffersAreSwapped)
                effectImage = UIGraphicsGetImageFromCurrentImageContext();
            UIGraphicsEndImageContext();
        }

        UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]);
        CGContextRef outputContext = UIGraphicsGetCurrentContext();
        CGContextScaleCTM(outputContext, 1.0, -1.0);
        CGContextTranslateCTM(outputContext, 0, -self.size.height);

        CGContextDrawImage(outputContext, imageRect, self.CGImage);

        if (hasBlur) {
            CGContextSaveGState(outputContext);
            if (maskImage) {
                CGContextClipToMask(outputContext, imageRect, maskImage.CGImage);
            }
            CGContextDrawImage(outputContext, imageRect, effectImage.CGImage);
            CGContextRestoreGState(outputContext);
        }

        if (tintColor) {
            CGContextSaveGState(outputContext);
            CGContextSetFillColorWithColor(outputContext, tintColor.CGColor);
            CGContextFillRect(outputContext, imageRect);
            CGContextRestoreGState(outputContext);
        }

        UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();

        return outputImage;
    }

7

आप इस पेज में सेब के डेमो से अपना समाधान पा सकते हैं: WWDC 2013 , UIImageEffects नमूना कोड डाउनलोड करें और डाउनलोड करें।

फिर @ जेरेमी फॉक्स के कोड के साथ। मैंने इसे बदल दिया

- (UIImage*)getDarkBlurredImageWithTargetView:(UIView *)targetView
{
    CGSize size = targetView.frame.size;

    UIGraphicsBeginImageContext(size);
    CGContextRef c = UIGraphicsGetCurrentContext();
    CGContextTranslateCTM(c, 0, 0);
    [targetView.layer renderInContext:c]; // view is the view you are grabbing the screen shot of. The view that is to be blurred.
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return [image applyDarkEffect];
}

आशा है कि यह आपकी मदद करेगा।


7

यहाँ यह करने का एक बहुत आसान तरीका है: https://github.com/JagCesar/iOS-blur

बस यूआईटूलबार की परत की नकल करें और आप कर रहे हैं, AMBlurView आपके लिए करता है। ठीक है, यह नियंत्रण केंद्र के रूप में धुंधली नहीं है, लेकिन पर्याप्त धुंधली है।

याद रखें कि iOS7 NDA के अंतर्गत है।


6

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

यदि आप इस सभी इमेज प्रोसेसिंग को जीपीयू पर छोड़ना पसंद करते हैं (और आपको चाहिए) तो आप बहुत बेहतर प्रभाव प्राप्त कर सकते हैं और यह भी 50 के दौर की भयानक अवधि (यह मानते हुए कि आपके पास पहले दृष्टिकोण में 1 सेकंड का समय है), इसलिए, इसे करने दें ।

सबसे पहले यहां GPUImage फ्रेमवर्क (BSD लाइसेंसधारी) डाउनलोड करें

अगला, GPUImage से निम्न वर्ग (.m और .h) जोड़ें (मुझे यकीन नहीं है कि ये केवल धब्बा प्रभाव के लिए न्यूनतम आवश्यक हैं)

  • GPUImage.h
  • GPUImageAlphaBlendFilter
  • GPUImageFilter
  • GPUImageFilterGroup
  • GPUImageGaussianBlurPositionFilter
  • GPUImageGaussianSelectiveBlurFilter
  • GPUImageLuminanceRangeFilter
  • GPUImageOutput
  • GPUImageTwoInputFilter
  • GLProgram
  • GPUImageBoxBlurFilter
  • GPUImageGaussianBlurFilter
  • GPUImageiOSBlurFilter
  • GPUImageSaturationFilter
  • GPUImageSolidColorGenerator
  • GPUImageTwoPassFilter
  • GPUImageTwoPassTextureSamplingFilter

  • आईओएस / GPUImage-Prefix.pch

  • आईओएस / GPUImageContext
  • आईओएस / GPUImageMovieWriter
  • आईओएस / GPUImagePicture
  • आईओएस / GPUImageView

अगला, UIImage पर एक श्रेणी बनाएं, जो मौजूदा UIImage में एक धुंधला प्रभाव जोड़ देगा:

#import "UIImage+Utils.h"

#import "GPUImagePicture.h"
#import "GPUImageSolidColorGenerator.h"
#import "GPUImageAlphaBlendFilter.h"
#import "GPUImageBoxBlurFilter.h"

@implementation UIImage (Utils)

- (UIImage*) GPUBlurredImage
{
    GPUImagePicture *source =[[GPUImagePicture alloc] initWithImage:self];

    CGSize size = CGSizeMake(self.size.width * self.scale, self.size.height * self.scale);

    GPUImageBoxBlurFilter *blur = [[GPUImageBoxBlurFilter alloc] init];
    [blur setBlurRadiusInPixels:4.0f];
    [blur setBlurPasses:2.0f];
    [blur forceProcessingAtSize:size];
    [source addTarget:blur];

    GPUImageSolidColorGenerator * white = [[GPUImageSolidColorGenerator alloc] init];

    [white setColorRed:1.0f green:1.0f blue:1.0f alpha:0.1f];
    [white forceProcessingAtSize:size];

    GPUImageAlphaBlendFilter * blend = [[GPUImageAlphaBlendFilter alloc] init];
    blend.mix = 0.9f;

    [blur addTarget:blend];
    [white addTarget:blend];

    [blend forceProcessingAtSize:size];
    [source processImage];

    return [blend imageFromCurrentlyProcessedOutput];
}

@end

और अंतिम, अपनी परियोजना में निम्नलिखित रूपरेखाएँ जोड़ें:

AVFoundation CoreMedia CoreVideo OpenGLES

हाँ, यह बहुत तेजी से दृष्टिकोण के साथ मज़ा आया;)


4

आप मेरे कस्टम दृश्य का उपयोग करके देख सकते हैं, जिसमें पृष्ठभूमि को धुंधला करने की क्षमता है। यह बैकग्राउंड के स्नैपशॉट को फीका करके और धुंधला कर देता है, ठीक उसी तरह जैसे Apple के WWDC कोड में होता है। इसे इस्तेमाल करना बहुत आसान है।

मैंने प्रदर्शन को खोए बिना डायनेमिक ब्लर को नकली बनाने के लिए कुछ सुधार किया। मेरे दृश्य की पृष्ठभूमि एक स्क्रॉल दृश्य है जो दृश्य के साथ स्क्रॉल करता है, इस प्रकार बाकी सुपरवाइवे के लिए धब्बा प्रभाव प्रदान करता है।

मेरे GitHub पर उदाहरण और कोड देखें


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.