मैं UIImageView का मुखौटा कैसे लगा सकता हूं?


100

मैं कुछ इस तरह से एक छवि को मुखौटा बनाने की कोशिश कर रहा हूं:

नकाबपोश होने की छवि

क्या आप मेरी मदद करेंगे?

मैं इस कोड का उपयोग कर रहा हूं:

- (void) viewDidLoad {
    UIImage *OrigImage = [UIImage imageNamed:@"dogs.png"];
    UIImage *mask = [UIImage imageNamed:@"mask.png"];
    UIImage *maskedImage = [self maskImage:OrigImage withMask:mask];
    myUIIMage.image = maskedImage;
}

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

यह एक ही आकार होना है, है ना?
करेनएने

हाइपर-सुरुचिपूर्ण कोड, धन्यवाद। बस एक उपयोगी लिंक अगर किसी को मास्क करने से पहले एक छवि को क्रॉप करने की जरूरत है ... stackoverflow.com/questions/17712797/…
Fattie

इसके बारे में कोई विचार .. stackoverflow.com/questions/28122370/…
मिलन पटेल

1
मैं आपसे आग्रह करता हूं कि कृपया चयनित उत्तर को लगभग 3 गुना अधिक उत्थान के साथ बदल दें। मेरी राय में यह हर तरह से निकट है।
अल्बर्ट रेनशॉ

जवाबों:


163

एक आसान तरीका है।

#import <QuartzCore/QuartzCore.h>
// remember to include Framework as well

CALayer *mask = [CALayer layer];
mask.contents = (id)[[UIImage imageNamed:@"mask.png"] CGImage];
mask.frame = CGRectMake(0, 0, <img_width>, <img_height>);
yourImageView.layer.mask = mask;
yourImageView.layer.masksToBounds = YES;

स्विफ्ट 4 और प्लस नीचे दिए गए कोड का पालन करें

let mask = CALayer()
mask.contents =  [ UIImage(named: "right_challenge_bg")?.cgImage] as Any
mask.frame = CGRect(x: 0, y: 0, width: leftBGImage.frame.size.width, height: leftBGImage.frame.size.height)
leftBGImage.layer.mask = mask
leftBGImage.layer.masksToBounds = true

1
धन्यवाद, लेकिन मैंने इस कोड को डाल दिया viewDidLoadलेकिन कुछ भी नहीं हुआ!
Mc.Lover

6
आपको मुखौटा का उपयोग करने के लिए परत संपत्ति सेट करनी चाहिए, अर्थात [yourImageView.layer setMasksToBounds: YES];
वोल्फगैंग श्रेयर्स

3
ध्यान दें कि इस समाधान के लिए UIImageView होना आवश्यक है। अन्य समाधान केवल UIImage के साथ काम करता है।
adriendenat

1
मैंने इस दृष्टिकोण की कोशिश की लेकिन ऐसा लगता है कि यह iOS 8
bdv

2
स्विफ्ट कोड के लिए, जब मास्क लगाया जाता है। कॉन्टेंट्स, सीजीआईमैज होना चाहिए। नहीं [CGImage]। यदि ब्रैकेट का उपयोग करें [], इसका अर्थ है एरे।
स्ट्रॉबेरी

59

ट्यूटोरियल इस पद्धति का उपयोग दो मापदंडों के साथ करता है: imageऔर maskImage, इन्हें आपको विधि को कॉल करने पर सेट करना होगा। एक उदाहरण कॉल इस तरह दिख सकता है, यह मानते हुए कि विधि एक ही कक्षा में है और चित्र आपके बंडल में हैं:

नोट - आश्चर्यजनक रूप से छवियों का आकार समान नहीं है।

...
UIImage *image = [UIImage imageNamed:@"dogs.png"];
UIImage *mask = [UIImage imageNamed:@"mask.png"];

// result of the masking method
UIImage *maskedImage = [self maskImage:image withMask:mask];

...

- (UIImage*) maskImage:(UIImage *)image withMask:(UIImage *)maskImage {

    CGImageRef maskRef = maskImage.CGImage; 

    CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
        CGImageGetHeight(maskRef),
        CGImageGetBitsPerComponent(maskRef),
        CGImageGetBitsPerPixel(maskRef),
        CGImageGetBytesPerRow(maskRef),
        CGImageGetDataProvider(maskRef), NULL, false);

    CGImageRef maskedImageRef = CGImageCreateWithMask([image CGImage], mask);
    UIImage *maskedImage = [UIImage imageWithCGImage:maskedImageRef];

    CGImageRelease(mask);
    CGImageRelease(maskedImageRef);

    // returns new image with mask applied
    return maskedImage;
}

आपके द्वारा अपना कोड प्रदान करने के बाद मैंने कुछ संख्याएँ संदर्भ के लिए टिप्पणियों के रूप में जोड़ दी हैं। आपके पास अभी भी दो विकल्प हैं। यह पूरी चीज एक विधि है, जिसे आप कहीं बुला रहे हैं। आपको इसके अंदर चित्र बनाने की आवश्यकता नहीं है: यह विधि की पुन: प्रयोज्य को शून्य कर देता है।

अपने कोड को काम करने के लिए। तरीकों सिर ( 1. ) को बदलें

- (UIImage *)maskImageMyImages {

तब में चर का नाम बदलने 2. करने के लिए

UIImage *maskImage = [UIImage imageNamed:@"mask.png"];

विधि आपकी नकाबपोश छवियों को वापस कर देगी इसलिए आपको इस विधि को किसी स्थान पर कॉल करना होगा। क्या आप हमें वह कोड दिखा सकते हैं जहाँ आप अपना तरीका बता रहे हैं?


माफ़ करना ! UIImage *imageकोड कहां लिखना चाहिए !!! क्योंकि -(UIimage *) maskeImageसंकलक पर पुनर्वितरण त्रुटि देता है!
McLover

क्षमा करें, क्या आप मेरे लिए एक नमूना कोड अपलोड करेंगे? Iam उलझन में: -s
Mc.Lover

1
संभव नहीं है, सब कुछ है। आपको हमें यह दिखाना होगा कि आप इस पद्धति को कैसे कॉल कर रहे हैं, या कम से कम वह हिस्सा जिसमें आप अपनी छवियों को मास्क करना चाहते हैं और परिणाम दिखा सकते हैं।
निक वीवर

मेरी समस्या इसे कॉल करना है, क्या यह कुछ ऐसा होना चाहिए ?? (viewDidLoad): मेरा संपादित कोड देखें
McLover

रिवर्स मास्किंग के बारे में कोई भी विचार। (उपरोक्त प्रक्रिया का उल्टा)। क्या मैं भरण क्षेत्र (इसे पारदर्शी बनाना चाहता हूं) और पारदर्शी क्षेत्र को भरना चाहता हूं।
मिलन पटेल

16

स्विफ्ट 3 - सबसे सरल समाधान मुझे मिला

मैंने इसके लिए बनाया @IBDesignableताकि आप अपने स्टोरीबोर्ड पर तुरंत प्रभाव देख सकें।

import UIKit

@IBDesignable
class UIImageViewWithMask: UIImageView {
    var maskImageView = UIImageView()

    @IBInspectable
    var maskImage: UIImage? {
        didSet {
            maskImageView.image = maskImage
            updateView()
        }
    }

    // This updates mask size when changing device orientation (portrait/landscape)
    override func layoutSubviews() {
        super.layoutSubviews()
        updateView()
    }

    func updateView() {
        if maskImageView.image != nil {
            maskImageView.frame = bounds
            mask = maskImageView
        }
    }
} 

कैसे इस्तेमाल करे

  1. ऊपर एक नई फाइल बनाएं और उस कोड में पेस्ट करें।
  2. अपने स्टोरीबोर्ड में UIImageView जोड़ें (यदि आप चाहें तो एक छवि प्रदान करें)।
  3. पहचानकर्ता निरीक्षक पर: कस्टम वर्ग को "UIImageViewWithMask" (ऊपर का कस्टम वर्ग नाम) बदलें।
  4. इंस्पेक्टर्स इंस्पेक्टर पर: वह मास्क इमेज चुनें, जिसका आप उपयोग करना चाहते हैं।

उदाहरण

स्टोरीबोर्ड पर मास्किंग

टिप्पणियाँ

  • आपकी मुखौटा छवि में गैर-काले भाग के लिए एक पारदर्शी पृष्ठभूमि (PNG) होनी चाहिए।

12

मैंने दोनों कोड का उपयोग करने की कोशिश की या तो CALayer या CGImageCreateWithMask का उपयोग किया लेकिन उनमें से किसी ने भी मेरे लिए काम नहीं किया

लेकिन मुझे पता चला कि समस्या png फ़ाइल प्रारूप के साथ है, कोड नहीं !!
तो बस मेरी खोज को साझा करने के लिए!

यदि आप उपयोग करना चाहते हैं

- (UIImage*) maskImage:(UIImage *)image withMask:(UIImage *)maskImage

आपको अल्फा चैनल के बिना 24bit png का उपयोग करना चाहिए

यदि आप कैलेयर मास्क का उपयोग करना चाहते हैं, तो आपको अल्फा चैनल के साथ (24bit या 8bit) png का उपयोग करना होगा जहां आपके png का पारदर्शी हिस्सा छवि को मास्क करेगा (चिकनी ढाल अल्फा मास्क के लिए .. अल्फा चैनल के साथ 24bit png का उपयोग करें)


10
- (UIImage*) maskImage:(UIImage *)image withMask:(UIImage *)maskImage {
        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

        CGImageRef maskImageRef = [maskImage CGImage];

        // create a bitmap graphics context the size of the image
        CGContextRef mainViewContentContext = CGBitmapContextCreate (NULL, maskImage.size.width, maskImage.size.height, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast);
        CGColorSpaceRelease(colorSpace);

        if (mainViewContentContext==NULL)
            return NULL;

        CGFloat ratio = 0;

        ratio = maskImage.size.width/ image.size.width;

        if(ratio * image.size.height < maskImage.size.height) {
            ratio = maskImage.size.height/ image.size.height;
        }

        CGRect rect1  = {{0, 0}, {maskImage.size.width, maskImage.size.height}};
        CGRect rect2  = {{-((image.size.width*ratio)-maskImage.size.width)/2 , -((image.size.height*ratio)-maskImage.size.height)/2}, {image.size.width*ratio, image.size.height*ratio}};


        CGContextClipToMask(mainViewContentContext, rect1, maskImageRef);
        CGContextDrawImage(mainViewContentContext, rect2, image.CGImage);


        // Create CGImageRef of the main view bitmap content, and then
        // release that bitmap context
        CGImageRef newImage = CGBitmapContextCreateImage(mainViewContentContext);
        CGContextRelease(mainViewContentContext);

        UIImage *theImage = [UIImage imageWithCGImage:newImage];

        CGImageRelease(newImage);

        // return the image
        return theImage;
}

यह मेरे लिए काम करता है।


धन्यवाद, यह उत्तर बेहतर है तो अन्य अधिक और बड़ी छवियों के साथ प्रदर्शन के बारे में बोल रहे हैं।
राडू उर्सचे

1
रिवर्स मास्किंग के बारे में कोई भी विचार। (उपरोक्त प्रक्रिया का उलटा)। क्या मैं भरण क्षेत्र (पारदर्शी बनाने के लिए) और पारदर्शी क्षेत्र को भरना चाहता हूं।
मिलन पटेल

धन्यवाद, यह कोड पहले से बेहतर काम करता है !! लेकिन मुझे दो परेशानियाँ हैं: "kCGImageAlphaPremultipliedLast" पर चेतावनी (मैं इसे ठीक करने के लिए "CGBitmapInfo" पर आता हूं) और रेटिना छवियों के लिए काम नहीं करता है !! क्या आप मेरी मदद कर सकते हैं? ...
अंगुली

@Milanpatel आसान उपाय यह है कि आप नकाब की छवि में अपने रंगों को उलट दें। :)
दिनांक १४:१५

@ZyiOS मैं नकाबपोश छवि के फ्रेम को कैसे अनुकूलित कर सकता हूं। यानी उपयोगकर्ता नकाबपोश छवि के आकार को बढ़ा या घटा सकता है।
दलविक

8

स्विफ्ट 3 XCODE 8.1

func maskImage(image: UIImage, withMask maskImage: UIImage) -> UIImage {

    let maskRef = maskImage.cgImage

    let mask = CGImage(
        maskWidth: maskRef!.width,
        height: maskRef!.height,
        bitsPerComponent: maskRef!.bitsPerComponent,
        bitsPerPixel: maskRef!.bitsPerPixel,
        bytesPerRow: maskRef!.bytesPerRow,
        provider: maskRef!.dataProvider!,
        decode: nil,
        shouldInterpolate: false)

    let masked = image.cgImage!.masking(mask!)
    let maskedImage = UIImage(cgImage: masked!)

    // No need to release. Core Foundation objects are automatically memory managed.

    return maskedImage

}

// उपयोग के लिए

testImage.image = maskImage(image: UIImage(named: "OriginalImage")!, withMask: UIImage(named: "maskImage")!)

क्या आप मुझे तस्वीर दे सकते हैं
अहमद सफादी 12

3

स्वीकृत समाधान का स्विफ्ट संस्करण:

func maskImage(image: UIImage, withMask maskImage: UIImage) -> UIImage {

    let maskRef = maskImage.CGImage

    let mask = CGImageMaskCreate(
        CGImageGetWidth(maskRef),
        CGImageGetHeight(maskRef),
        CGImageGetBitsPerComponent(maskRef),
        CGImageGetBitsPerPixel(maskRef),
        CGImageGetBytesPerRow(maskRef),
        CGImageGetDataProvider(maskRef),
        nil,
        false)

    let masked = CGImageCreateWithMask(image.CGImage, mask)
    let maskedImage = UIImage(CGImage: masked)!

    // No need to release. Core Foundation objects are automatically memory managed.

    return maskedImage

}

बस अगर किसी को इसकी जरूरत है।

यह मेरे लिए निर्दोष काम कर रहा है।


क्या आपके पास इसमें स्विफ्ट 3.0 संस्करण है?
वान डू ट्रान

2

हमने पाया, कि सही उत्तर अब काम नहीं कर रहा है और थोड़ा ड्रॉप-इन क्लास लागू किया गया है, जो UIImageView में किसी भी छवि को मुखौटा बनाने में मदद करता है।

यह यहां उपलब्ध है: https://github.com/Werbary/WBMaskedImageView

उदाहरण:

WBMaskedImageView *imgView = [[WBMaskedImageView alloc] initWithFrame:frame];
imgView.originalImage = [UIImage imageNamed:@"original_image.png"];
imgView.maskImage = [UIImage imageNamed:@"mask_image.png"];

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