আমি কীভাবে একটি ইউআইআইমেজভিউকে মাস্ক করতে পারি?


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
আমি সেই ব্যক্তি যিনি মূল টিউটোরিয়ালটি লিখেছিলেন। মাস্ক চিত্রটি কেবল ফটোশপে তৈরি করা একটি সাধারণ গ্রেস্কেল চিত্র। এটি সম্পর্কে বিশেষ কিছুই। কালো অঞ্চলটি মাস্কের "স্বচ্ছ" অংশে পরিণত হয়। মনে রাখবেন যে ধূসর রঙের যে কোনও শেডকে অস্বচ্ছতার একটি ডিগ্রী হিসাবে ব্যাখ্যা করা হয়। এই পদ্ধতিতে, মুখোশগুলি পাশাপাশি গ্রেডিয়েন্ট হতে পারে যা একটি মুখোশের চারপাশে নরম সীমানা তৈরি করার জন্য দরকারী।
ra9r

এই একই আকার হতে হবে, তাই না?
কারেনআ্নে

হাইপার-মার্জিত কোড, ধন্যবাদ মাস্কিংয়ের আগে যদি কারও একটি ছবি ক্রপ করতে হয় তবে কেবলমাত্র একটি দরকারী লিঙ্ক ... stackoverflow.com/questions/17712797/…
ফ্যাটি

এ সম্পর্কে কোনও ধারণা .. stackoverflow.com/questions/28122370/…
মিলান প্যাটেল

4
আমি আপনাকে অনুরোধ করছি দয়া করে নির্বাচিত উত্তরটিকে প্রায় 3 বার হিসাবে অনেকগুলি উচ্চপদ দিয়ে পরিবর্তন করুন। আমার মতে এটি প্রতিটি উপায়েই ভাল।
অ্যালবার্ট রেনশওয়া

উত্তর:


165

একটি সহজ উপায় আছে।

#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

4
আপনাকে ধন্যবাদ তবে আমি এই কোডটি লাগিয়েছি viewDidLoadকিন্তু কিছুই ঘটেনি!
ম্যাক.লভার

6
আপনার মুখোশটি ব্যবহার করার জন্য স্তর বৈশিষ্ট্যটি নির্ধারণ করা উচিত, অর্থাত্ [আপনার আইজ্যামভিউ.লায়ার সেটমাস্কটোবাউন্ডস: হ্যাঁ];
ওল্ফগ্যাং শেরুর্স

4
লক্ষ্য করুন যে এই সমাধানের জন্য এটি ইউআইআইমেজভিউ হওয়া দরকার। অন্যান্য সমাধানটি কেবলমাত্র একটি ইউআইআইমেজ নিয়ে কাজ করে।
অ্যাড্রেডেনাট

4
আমি এই পদ্ধতির চেষ্টা করেছি তবে মনে হচ্ছে এটি iOS 8
bdv

4
সুইফট কোডের জন্য, যখন মাস্ককন্টনেস্ট লাগানো উচিত, তখন সিজিআইমেজ করা উচিত। [সিজিআইমেজ] নয়। যদি বন্ধনী ব্যবহার করেন [], এর অর্থ অ্যারে।
স্ট্রানট

61

টিউটোরিয়ালটি দুটি পরামিতি সহ এই পদ্ধতিটি ব্যবহার করে: imageএবং maskImage, আপনি যখন পদ্ধতিটি কল করবেন তখন এগুলি আপনাকে সেট করতে হবে। পদ্ধতিটি একই শ্রেণিতে রয়েছে এবং ছবিগুলি আপনার বান্ডেলে রয়েছে তা ধরে নিয়ে উদাহরণ কলটি এর মতো দেখতে পারে could

দ্রষ্টব্য - আশ্চর্যজনকভাবে চিত্রগুলিও একই আকারের হতে পারে না।

...
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সংকলক পুনরায় সংজ্ঞা ত্রুটি দেয়!
ম্যাক.প্রেম

দুঃখিত আপনি আমার জন্য একটি নমুনা কোড আপলোড করবেন?
আইএম

4
সম্ভব নয়, সব আছে। আপনি কীভাবে এই পদ্ধতিটি কল করছেন তা আমাদের দেখাতে হবে বা কমপক্ষে যে অংশে আপনি আপনার চিত্রগুলি মুখোশ করতে চান এবং ফলাফলটি প্রদর্শন করতে চান।
নিক ওয়েইভার

আমার সমস্যাটি এটিকে কল করা, এটি কি এমন কিছু হওয়া উচিত ?? (ভিউডিডলড): আমার সম্পাদিত কোডটি দেখুন
ম্যাক.লভের

বিপরীত মুখোশ সম্পর্কে কোনও ধারণা above (উপরের প্রক্রিয়াটির বিপরীত) e
মিলান পটেল

17

সুইফট 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. আপনার স্টোরিবোর্ডে ইউআইআইমেজভিউ যুক্ত করুন (আপনি চাইলে একটি চিত্র নির্ধারণ করুন)।
  3. পরিচয়ের পরিদর্শকটিতে: কাস্টম ক্লাসটি "ইউআইআইমেজভিউউথথমাস্ক" এ পরিবর্তন করুন (উপরে কাস্টম শ্রেণীর নাম)।
  4. বৈশিষ্ট্য পরিদর্শকের উপর: আপনি ব্যবহার করতে চান এমন মাস্ক চিত্র নির্বাচন করুন।

উদাহরণ

স্টোরিবোর্ডে মাস্কিং

মন্তব্য

  • আপনার মাস্ক চিত্রের অ-কালো অংশের জন্য একটি স্বচ্ছ পটভূমি (PNG) হওয়া উচিত।

12

আমি উভয় কোডই CALayer বা CGImageCreateWithMask ব্যবহার করে চেষ্টা করেছি কিন্তু সেগুলির কোনওোটাই আমার পক্ষে কাজ করেনি

তবে আমি জানতে পেরেছি যে সমস্যাটি পিএনজি ফাইল ফর্ম্যাট, কোড নয় !!
তাই শুধু আমার সন্ধান ভাগ!

আপনি যদি ব্যবহার করতে চান

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

আপনাকে অবশ্যই আলফা চ্যানেল ছাড়াই 24 বিবিটি পিএনজি ব্যবহার করতে হবে

আপনি যদি ক্যালায়ার মাস্কটি ব্যবহার করতে চান তবে আপনাকে অবশ্যই আলফা চ্যানেলের সাথে (24 বিট বা 8 বিট) পিএনজি ব্যবহার করতে হবে যেখানে আপনার পিএনগির স্বচ্ছ অংশটি চিত্রটি মাস্ক করবে (মসৃণ গ্রেডিয়েন্ট আলফা মাস্কের জন্য .. আলফা চ্যানেলের সাথে 24 বিট পিএনজি ব্যবহার করুন)


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;
}

এটি আমার পক্ষে কাজ করে।


আপনাকে ধন্যবাদ, এই উত্তরটি আরও ভাল যদি অন্যের আরও বেশি বড় চিত্র সহ পারফরম্যান্স সম্পর্কে কথা বলে।
রাদু উর্ছে

4
বিপরীত মুখোশ সম্পর্কে কোনও ধারণা above (উপরের প্রক্রিয়াটির বিপরীত) e
মিলান পটেল

ধন্যবাদ, এই কোডটি প্রথমের চেয়ে আরও ভাল কাজ করেছে !! তবে আমার দুটি সমস্যা রয়েছে: "কেসিজিআইমেজএল্ফাপ্রিমুলিটিপ্লাইস্টস্ট" ("সিজিবিটম্যাপআইএনফো" কে ঠিক করার জন্য আমি কাস্ট করেছি) এবং রেটিনা চিত্রগুলির জন্য কাজ করে না !! আপনি কি আমাকে সাহায্য করতে পারেন ?? ...
ফিঙ্গারপ্রপ

@ মিলনপ্যাটেল সহজ সমাধানটি হ'ল মুখোশের চিত্রটিতে আপনার রঙগুলি উল্টানো। :)
Dids

@ জাইওএস কীভাবে আমি মুখোশযুক্ত চিত্রের ফ্রেমটি কাস্টমাইজ করতে পারি। অর্থাত্ ব্যবহারকারী মুখোশযুক্ত চিত্রের আকার বাড়া বা হ্রাস করতে পারে।
ডালভিক

8

সুইফট 3 এক্সকোড 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")!)

আপনি কি আমাকে ছবিটি উপহার দিতে পারবেন
আহমেদ সাফাদি

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

আমরা পেয়েছি যে সঠিক উত্তরটি এখন কাজ করছে না এবং সামান্য ড্রপ-ইন ক্লাস প্রয়োগ করেছে, যা ইউআইআইমেজভিউতে কোনও চিত্রকে মুখোশ করতে সহায়তা করে।

এটি এখানে উপলভ্য: 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"];

4
ভাল একটা! এটা সত্যিই সাহায্য করেছে।
অভিমুরলিধরণ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.