UIView को इमेज में कैसे बदलें


93

मैं एक UIView को एक छवि में बदलना चाहता हूं और इसे अपने ऐप में सहेजना चाहता हूं। क्या कोई मुझे बता सकता है कि किसी दृश्य का स्क्रीनशॉट कैसे ले सकता है या इसे एक छवि में कैसे बदल सकता है और इसे ऐप में सहेजने का सबसे अच्छा तरीका क्या है (कैमरा रोल नहीं)? यहाँ देखने के लिए कोड है:

var overView   = UIView(frame: CGRectMake(0, 0, self.view.frame.width/1.3, self.view.frame.height/1.3))
overView.center = CGPointMake(CGRectGetMidX(self.view.bounds),
CGRectGetMidY(self.view.bounds)-self.view.frame.height/16);
overView.backgroundColor = UIColor.whiteColor()
self.view.addSubview(overView)
self.view.bringSubviewToFront(overView)

इसके अलावा प्रासंगिक: stackoverflow.com/q/59592933/294884
फेटी

जवाबों:


187

पर एक विस्तार UIViewचाल करना चाहिए।

extension UIView {

    // Using a function since `var image` might conflict with an existing variable
    // (like on `UIImageView`)
    func asImage() -> UIImage {
        let renderer = UIGraphicsImageRenderer(bounds: bounds)
        return renderer.image { rendererContext in
            layer.render(in: rendererContext.cgContext)
        }
    }
}

Apple UIGraphicsBeginImageContextP3 रंग सरगम ​​की शुरूआत के साथ iOS 10 का उपयोग करने को हतोत्साहित करता है । UIGraphicsBeginImageContextsRGB और 32-बिट ही है। उन्होंने नई UIGraphicsImageRendererएपीआई पेश की जो पूरी तरह से रंग प्रबंधित है, ब्लॉक-आधारित है, जिसमें पीडीएफ और छवियों के लिए उपवर्ग हैं, और स्वचालित रूप से संदर्भ जीवनकाल का प्रबंधन करता है। की जाँच करें WWDC16 सत्र 205 अधिक जानकारी के लिए (छवि प्रतिपादन 11:50 निशान के आसपास शुरू होता है)

यह सुनिश्चित करने के लिए कि यह प्रत्येक डिवाइस पर काम करता है, #availableiOS के पुराने संस्करणों में वापसी के साथ उपयोग करें :

extension UIView {

    // Using a function since `var image` might conflict with an existing variable
    // (like on `UIImageView`)
    func asImage() -> UIImage {
        if #available(iOS 10.0, *) {
            let renderer = UIGraphicsImageRenderer(bounds: bounds)
            return renderer.image { rendererContext in
                layer.render(in: rendererContext.cgContext)
            }
        } else {
            UIGraphicsBeginImageContext(self.frame.size)
            self.layer.render(in:UIGraphicsGetCurrentContext()!)
            let image = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            return UIImage(cgImage: image!.cgImage!)
        }
    }
}

9
इसे सही उत्तर के रूप में चिह्नित किया जाना चाहिए। अन्य सभी विकल्प स्पष्टता खोने और पिक्सेलयुक्त / धुंधली दिखने के लिए प्रदान की गई छवि का कारण बनेंगे।
ट्यूपलिंग डी

एकमात्र सही तरीका! शुरुआती लोगों के लिए उपयोग है: छवि = customView.asImage ()
Fabio

1
क्या पारदर्शी पृष्ठभूमि के साथ UIView को प्रस्तुत करना संभव है? मेरा कुछ गोल कोनों है।
ixany

@ixany इसे पहले से ही ध्यान रखना चाहिए। मैंने इसे प्लेग्राउंड में निम्नलिखित के साथ आज़माया और इसने काम किया: let view = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100)); view.backgroundColor = .black; view.layer.cornerRadius = 9; view.asImage();
नावेद जे।

2
धन्यवाद! अगर किसी को पता है, तो मुझे यह जानने के लिए उत्सुक होना चाहिए कि hackingwithswift.com/example-code/media/… से कोड में क्या अंतर हैं, रिटर्न रेंडरर .image {ctx in drawHierarchy (in: सीमा, afterScreenUpdates: true)}
कक्राट

63

आप एक्सटेंशन का उपयोग कर सकते हैं

extension UIImage {
    convenience init(view: UIView) {
        UIGraphicsBeginImageContext(view.frame.size)
        view.layer.render(in:UIGraphicsGetCurrentContext()!)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        self.init(cgImage: image!.cgImage!)
    }
}

यहां स्विफ्ट 3/4 संस्करण:

extension UIImage {
    convenience init(view: UIView) {
        UIGraphicsBeginImageContext(view.frame.size)
        view.layer.render(in:UIGraphicsGetCurrentContext()!)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        self.init(cgImage: image!.cgImage!)
    }
}

5
मैं यह पूछने वाला शर्मिंदा हूं, लेकिन मैं इसे कैसे कहूं? मेरी कोई छवि नहीं है और एक UIView कि मैं एक छवि बनना चाहता हूं। उपरोक्त कोड मुझे UIImage एक्सटेंशन देता है ... लेकिन अब क्या?
डेव जी

8
let image = UIImage(view: myView)
डॉक्टरब्रोक्टर

मेरे लिए काम नहीं करता है क्योंकि UIGraphicsGetCurrentContext () शून्य हो सकता है और कोड क्रैश हो सकता है।
जुआन कार्लोस ओस्पिना गोंजालेज 15

@JuanCarlosOspinaGonzalez यदि UIGraphicsGetCurrentContext नील वापस आ गया है, तो मुझे संदेह है कि आपको UIGraphicsBeginImageContext की जाँच करने की आवश्यकता है ताकि यह पता लगाया जा सके कि यह विफल क्यों हुआ। मेरा अनुमान है कि आपके आकार का एक आयाम शून्य है या अन्यथा अमान्य है, लेकिन मुझे वास्तव में पता नहीं है कि क्या कारण असफल हो सकता है।
जॉन स्टीफन

2
आपको स्क्रीन के पैमाने को भी ध्यान में रखना चाहिए, इसलिए मैं इसके साथ UIGraphicsBeginImageContextWithOptions(view.frame.size, false, UIScreen.main.scale)
इनिशलाइज़र

41

ड्रा के माध्यम से अपने UIView को चित्र में बदलेंहाइरार्कीइंटरक्ट: afterScreenUpdates: जो रेंडर से कई गुना तेज है।

महत्वपूर्ण नोट: इस फ़ंक्शन को viewDidLoad या viewWillAppear से कॉल न करें , सुनिश्चित करें कि यह प्रदर्शित होने के बाद आप इसे कैप्चर कर रहे हैं / पूरी तरह से लोड किया गया है

ओबज सी

     UIGraphicsBeginImageContextWithOptions(myView.bounds.size, myView.opaque, 0.0f);
     [myView drawViewHierarchyInRect:myView.bounds afterScreenUpdates:NO];
     UIImage *snapshotImageFromMyView = UIGraphicsGetImageFromCurrentImageContext();
     UIGraphicsEndImageContext();

     myImageView.image =  snapshotImageFromMyView;

संपादित छवि फ़ोटो एल्बम सहेजें

     UIImageWriteToSavedPhotosAlbum(snapshotImageFromMyView, nil,nil, nil);

स्विफ्ट 3/4

    UIGraphicsBeginImageContextWithOptions(myView.bounds.size, myView.isOpaque, 0.0)
    myView.drawHierarchy(in: myView.bounds, afterScreenUpdates: false)
    let snapshotImageFromMyView = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    print(snapshotImageFromMyView)
    myImageView.image = snapshotImageFromMyView

एक्सटेंशन, iOS11, स्विफ्ट 3/4 के साथ सुपर आसान सामान्यीकरण

extension UIImage{
    convenience init(view: UIView) {

    UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.isOpaque, 0.0)
    view.drawHierarchy(in: view.bounds, afterScreenUpdates: false)
    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    self.init(cgImage: (image?.cgImage)!)

  }
}


Use : 
 //myView is completly loaded/visible , calling this code after only after viewDidAppear is call
 imgVV.image = UIImage.init(view: myView)
 // Simple image object
 let img =  UIImage.init(view: myView)

3
मेरे लिए कोई काम नहीं करने पर मुझे मेरे UiImage के लिए एक ब्लैकस्क्रीन मिला
Badr Filali

वास्तव में ?? क्या आप यहां अपना कोड पेस्ट कर सकते हैं .. U गलत UIView ऑब्जेक्ट का उपयोग UIImage के रूप में परिवर्तित करने के लिए हो सकता है।
विजय Avhad

`func ConvertViewIntoImg () -> शून्य {imgFakeCard.image = UIImage.init (देखें: कार्ड)}` स्विफ्ट 3 में आपके एक्सटेंशन के साथ यह फ़ंक्शन viewDidLoad में कॉल किया जाता है
Badr Filali

1
अपना कोड पोस्ट करने और यह देखने के लिए धन्यवाद कि आपने viewDidLoad में कॉल किया है। यहाँ आप गलत क्या है मेमोरी में लोड होने से पहले आप स्नैपशॉट को कैप्चर कर रहे हैं। कृपया ViewDidAppear में कॉलिंग कोड आज़माएं, जिससे समस्या का हल सुनिश्चित हो जाएगा। किसी भी सवाल का जवाब कृपया।
विजे अवध

उस महान काम के लिए धन्यवाद, समस्या यह है कि जहां से मैंने आपके एक्सटेंशन को बुलाया
बदर फ़िलाली

20

IOS 10 पर:

extension UIImage {
    convenience init(view: UIView) {
        UIGraphicsBeginImageContext(view.frame.size)
        view.layer.render(in: UIGraphicsGetCurrentContext()!)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        self.init(cgImage: (image?.cgImage)!)
    }
}

1
इससे दुर्घटनाएं होती हैं।
किंगपॉलीगॉन्ज

18

IOS 10 और स्विफ्ट 3 के रूप में सर्वश्रेष्ठ अभ्यास

अभी भी iOS 9 का समर्थन करते हुए और इससे पहले अभी भी iOS 13, Xcode 11.1, स्विफ्ट 5.1 के रूप में काम करता है

extension UIView {

    func asImage() -> UIImage? {
        if #available(iOS 10.0, *) {
            let renderer = UIGraphicsImageRenderer(bounds: bounds)
            return renderer.image { rendererContext in
                layer.render(in: rendererContext.cgContext)
            }
        } else {
            UIGraphicsBeginImageContextWithOptions(self.bounds.size, self.isOpaque, 0.0)
            defer { UIGraphicsEndImageContext() }
            guard let currentContext = UIGraphicsGetCurrentContext() else {
                return nil
            }
            self.layer.render(in: currentContext)
            return UIGraphicsGetImageFromCurrentImageContext()
        }
    }
}

मैं अनिश्चित हूं कि प्रश्न का क्या अर्थ है:

ऐप में इसे बचाने का सबसे अच्छा तरीका क्या है (कैमरा रोल नहीं)?


17
    UIGraphicsBeginImageContext(self.view.bounds.size);        
    self.view.layer.renderInContext(UIGraphicsGetCurrentContext())
    var screenShot = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();


1
UIGraphicsGetImageFromCurrentImageContext UIImage देता है। इसे UIImage में डालने की आवश्यकता नहीं है
लियो डबस

यह पूरे दृश्य का स्क्रीनशॉट लेता है? मैं सिर्फ अपने कोड में एक UIView यानी ओवरव्यू को बदलना चाहता हूं जो एक छवि के लिए self.view का सबव्यू है। संपूर्ण दृश्य नहीं!
समीर हुसैन

@Vakas जब मैंने इमेज को प्रिंट करने की कोशिश की। यह बहुत छोटा है। इसके लिए समाधान क्या है
Krutarth Patel

6
स्क्रीनशॉट छवि में अच्छी गुणवत्ता नहीं है, मुझे क्या करना चाहिए?
नीला

13

उदाहरण के लिए यदि मेरे पास आकार है: 50 50 100,100 पर। मैं स्क्रीनशॉट लेने के लिए निम्नलिखित का उपयोग कर सकता हूं:

    UIGraphicsBeginImageContextWithOptions(CGSizeMake(100, 100), false, 0);
    self.view.drawViewHierarchyInRect(CGRectMake(-50,-5-,view.bounds.size.width,view.bounds.size.height), afterScreenUpdates: true)
    var image:UIImage = UIGraphicsGetImageFromCurrentImageContext();

self.view लाइन में पैरामीटर में गलती है। मुझे लगता है कि यह -5 होना चाहिए -5 नहीं
क्रतुर्थ पटेल

@sameer में मेरा एक प्रश्न है। जब मैं इस चित्र को छापता हूँ तो यह बहुत छोटा होता है
क्रुर्थ पटेल

7

मेरी राय में, शुरुआती के साथ दृष्टिकोण उतना महान नहीं है क्योंकि यह दो छवियां बनाता है।

यह मेरे लिए ज़्यादा प्रधान है:

extension UIView {
    var snapshot: UIImage? {
        UIGraphicsBeginImageContext(self.frame.size)
        guard let context = UIGraphicsGetCurrentContext() else {
            return nil
        }
        layer.render(in: context)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }
}

आपको संपत्ति को छवि के अलावा कुछ और कहना चाहिए। यह उन उपवर्गों के साथ हस्तक्षेप कर सकता है जिनमें छवि नामक गुण हैं, जैसे कि UIImageView।
को टीज

@HobbestheTige के सुझाव का पालन किया और संपत्ति का नाम बदल दिया
टिनो

6

स्विफ्ट 4.2, आईओएस 10

extension UIView {

    // If Swift version is lower than 4.2, 
    // You should change the name. (ex. var renderedImage: UIImage?)

    var image: UIImage? {
        let renderer = UIGraphicsImageRenderer(bounds: bounds)
        return renderer.image { rendererContext in layer.render(in: rendererContext.cgContext) }
    }
}

नमूना

let view = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
view.backgroundColor = .blue

let view2 = UIView(frame: CGRect(x: 10, y: 10, width: 20, height: 20))
view2.backgroundColor = .red
view.addSubview(view2)

let imageView = UIImageView(image: view.image)

यहां छवि विवरण दर्ज करें


केवल यह इंगित करना चाहता था कि यदि आप अपने प्रोजेक्ट में किसी भी UIImageViews का उपयोग कर रहे हैं, तो इसे कुछ और नाम दिया जाना चाहिए, अन्यथा .image केवल पढ़ा जाता है। शायद इसे 'छवि' के बजाय 'स्क्रीनकैचर' कहें।
क्रिस

@ क्रिस हाँ, आप सही हैं। यदि स्विफ्ट संस्करण 4.2 से कम है, तो आपको एक नाम बदलना चाहिए। आपकी गलती के लिए धन्यवाद।
डेन

6

यह मेरे लिए Xcode 9 / Swift 3.2 / Swift 4 और Xcode 8 / Swift 3 के लिए काम करता है

 if #available(iOS 10.0, *) {

     // for Xcode 9/Swift 3.2/Swift 4 -Paul Hudson's code
     let renderer = UIGraphicsImageRenderer(size: view!.bounds.size)
     let capturedImage = renderer.image { 
         (ctx) in
         view!.drawHierarchy(in: view!.bounds, afterScreenUpdates: true)
     }
     return capturedImage

 } else {

     // for Xcode 8/Swift 3
     UIGraphicsBeginImageContextWithOptions((view!.bounds.size), view!.isOpaque, 0.0)
     view!.drawHierarchy(in: view!.bounds, afterScreenUpdates: false)
     let capturedImage = UIGraphicsGetImageFromCurrentImageContext()
     UIGraphicsEndImageContext()
     return capturedImage!
 }

एक फ़ंक्शन के अंदर इसका उपयोग कैसे करें:

fileprivate func captureUIImageFromUIView(_ view:UIView?) -> UIImage {

     guard (view != nil) else{

        // if the view is nil (it's happened to me) return an alternative image
        let errorImage = UIImage(named: "Error Image")
        return errorImage
     }

     // if the view is all good then convert the image inside the view to a uiimage
     if #available(iOS 10.0, *) {

         let renderer = UIGraphicsImageRenderer(size: view!.bounds.size)
         let capturedImage = renderer.image { 
             (ctx) in
             view!.drawHierarchy(in: view!.bounds, afterScreenUpdates: true)
         }
         return capturedImage

     } else {

         UIGraphicsBeginImageContextWithOptions((view!.bounds.size), view!.isOpaque, 0.0)
         view!.drawHierarchy(in: view!.bounds, afterScreenUpdates: false)
         let capturedImage = UIGraphicsGetImageFromCurrentImageContext()
         UIGraphicsEndImageContext()
         return capturedImage!
     }
}

यहां बताया गया है कि फ़ंक्शन से लौटी छवि के साथ कुछ करना है:

@IBOutlet weak fileprivate var myCustomView: UIView!
var myPic: UIImage?

let myImageView = UIImageView()

@IBAction fileprivate func saveImageButtonTapped(_ sender: UIButton) {

   myPic = captureUIImageFromUIView(myCustomView)

   // display the pic inside a UIImageView
   myImageView.image = myPic!
}

मुझे Xcode 9 / स्विफ्ट 3.2 / स्विफ्ट 4 का जवाब मिला, पॉल हडसन ने uiview को uiimage में बदल दिया

मुझे Xcode 8 / Swift 3 कहीं से SO पर बहुत पहले मिल गया था और मैं भूल गया कि :(


यह भी कि छवि कहाँ प्रदर्शित होती है और / या बचाई जाती है?
पारिवारिक टेक

@FamicTech एक बार छवि बनाने के बाद युवाओं के लिए यह तय करना है कि इसके साथ क्या करना है। अपने कोड से उदाहरण में मैंने UIView को "myPic" नामक UIImage में परिवर्तित किया लेकिन मैंने 'myPic' के साथ कुछ नहीं किया। अगला संभव कदम इस तरह से UIImageVIew के अंदर 'myPic' प्रदर्शित करना है: myImageVIew.image = myPic। यदि आप एक संग्रह दृश्य का उपयोग कर रहे हैं और आप उसमें चित्र प्रदर्शित करना चाहते हैं तो आप प्रत्येक सेल में एक UIImageVIew बनाएं और फिर UIImageVIew के अंदर की छवि (myPic) को indexPath.item के माध्यम से datasource पूर्व: myImageView.image = dataSource [indexPath से प्रदर्शित करें .item] .myPic
लांस सामरिया

@ फ़ेमटेक आप थोड़ी सी गलती कर रहे हैं। यह एक संग्रह के साथ कुछ नहीं करना है। आपके पास 2 अलग-अलग प्रकार के प्रकार हैं: UIImage और एक UIView। दोनों का उपयोग किसी भी छवि को प्रदर्शित करने के लिए किया जा सकता है लेकिन वे दोनों इसे अलग-अलग तरीकों से करते हैं। IOS में बहुत कुछ सब कुछ एक UIView का उपवर्ग है, लेकिन एक UIImage केवल छवियों (2 अलग-अलग चीजों) को प्रदर्शित कर सकता है। यह कार्य जो करता है वह UIVIew लेता है और इसे UIImage में परिवर्तित करता है। एक आसान उदा। यदि आप 4.0 (एक डबल) को 4 (एक इंट) में परिवर्तित करना चाहते हैं, तो आप इसे इंट (4.0) परिणाम डालते हैं। 4. लेकिन इसके साथ आप छवि को यूआईवीवाई के अंदर यूआईआईएमएजे में परिवर्तित करते हैं। समझना?
लांस सामरिया

मैं जो करने की कोशिश कर रहा हूं वह यह है कि उपयोगकर्ता मेरे संग्रह व्यू कंट्रोलर के पास आए और एक बटन दबाएं जो वर्तमान दृश्य को ले जाए, जो कि संग्रह 10x10 देखें और पूरे 10x10 ग्रिड की एक छवि बनाएं (कृपया ध्यान दें कि संपूर्ण ग्रिड पूरी तरह से दृश्य में नहीं है)। क्या आपका कोड ऊपर उस उपयोग के मामले को हल करता है?
पारिवारिक टेक

बटन नेविगेशन कंट्रोलर में है। उपयोगकर्ता इसे क्लिक करेगा और यह नेविगेशन नियंत्रक के तहत प्रदर्शित संग्रह दृश्य को 'ले जाना' चाहिए और संग्रह दृश्य में मौजूद सभी सूचनाओं के साथ संग्रह दृश्य (एक पीडीएफ भी काम करेगा) की एक छवि बनाएं।
फेमिक टेक

5
var snapshot = overView.snapshotViewAfterScreenUpdates(false)

या उद्देश्य-सी में

UIView* snapshot = [overView snapshotViewAfterScreenUpdates:NO];

क्या ImageView छवि के समान है? यदि हां, तो मैं इसे अपने ऐप में कैसे सहेज सकता हूं?
समीर हुसैन

4

आप इस तरह से एक्सटेंशन का उपयोग करके आसानी से उपयोग कर सकते हैं

// Take a snapshot from a view (just one view)
let viewSnapshot = myView.snapshot

// Take a screenshot (with every views in screen)
let screenSnapshot = UIApplication.shared.snapshot

// Take a snapshot from UIImage initialization
UIImage(view: self.view)

यदि आप उन विस्तार विधि / चर का उपयोग करना चाहते हैं, तो इसे लागू करें

  1. UIImage एक्सटेंशन

    extension UIImage {
        convenience init(view: UIView) {
            if let cgImage = view.snapshot?.cgImage {
                self.init(cgImage: cgImage)
            } else {
                self.init()
            }
        }
    }
  2. UIView विस्तार

    extension UIView {
    
        var snapshot: UIImage? {
            UIGraphicsBeginImageContextWithOptions(bounds.size, isOpaque, 0.0)
            if UIGraphicsGetCurrentContext() != nil {
                drawHierarchy(in: bounds, afterScreenUpdates: true)
                let screenshot = UIGraphicsGetImageFromCurrentImageContext()
                UIGraphicsEndImageContext()
                return screenshot
            }
            return nil
        }
    }
  3. UIApplication एक्सटेंशन

    extension UIApplication {
    
        var snapshot: UIImage? {
            return keyWindow?.rootViewController?.view.snapshot
        }
    }

मेरे पास सब-ज़ॉप्रिशन के साथ जोड़तोड़ किए गए दृश्य थे, और अन्य उत्तर मुझे सही लेयर पोज़िशन नहीं देते थे, धन्यवाद।
अश्कान घोडरात

3

या iOS 10+ आप नए UIGraphicsImageRenderer + की सिफारिश की गई ड्रॉअरहार्की का उपयोग कर सकते हैं, जो कुछ स्थितियों में लेयर से अधिक तेज हो सकता है।

extension UIView {
    func asImage() -> UIImage {
        let renderer = UIGraphicsImageRenderer(size: self.bounds.size)
        return renderer.image { _ in
            self.drawHierarchy(in: CGRect(x: 0, y: 0, width: bounds.size.width, height: bounds.size.height), afterScreenUpdates: false)
        }
    }
}

3

धन्यवाद @ बाओ तुआन डाइप! मैं एक पूरक जोड़ना चाहता हूं।

जब आप कोड का उपयोग करते हैं:

yourView.layer.render(in:UIGraphicsGetCurrentContext()!)

आपको ध्यान देना चाहिए कि:

 - If you had used `autoLayout` or `Masonry` in `yourView` (that you want to convert) .
 - If you did not add `yourView` to another view which means that `yourView` was not used as a subview but just an object.

फिर, आपका उपयोग करना चाहिए :

[yourView setNeedsLayout];
[yourView layoutIfNeeded];

yourViewपहले अद्यतन करने के लिए yourView.layer.render(in:UIGraphicsGetCurrentContext()!)

अन्यथा आपको एक छवि ऑब्जेक्ट मिल सकती है जिसमें कोई तत्व नहीं हैं


इसके लिए धन्यवाद। बहुत मदद की !!
मक्सिम नियाज़ेव

2

स्विफ्ट 4.2

import Foundation
import UIKit  

extension UIImage {

    convenience init(view: UIView) {

        UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.isOpaque, 0.0)
        view.drawHierarchy(in: view.bounds, afterScreenUpdates: false)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        self.init(cgImage: (image?.cgImage)!)

    } 
}

का उपयोग करते हुए:

चलो img = UIImage.init (देखें: self.holderView)


1

स्विफ्ट 3 में कार्यान्वयन :

नीचे दिए गए कोड को वर्ग दायरे से बाहर जोड़ें।

extension UIImage {
    convenience init(_ view: UIView) {
        UIGraphicsBeginImageContext(view.frame.size)
        view.layer.render(in: UIGraphicsGetCurrentContext()!)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        self.init(cgImage: (image?.cgImage)!)
    }
}

उपयोग:

let image = UIImage( Your_View_Outlet )

त्रुटि प्राप्त करना "एक दृश्य खींचना (0x1040a6970, UIView) जिसे कम से कम एक बार प्रस्तुत नहीं किया गया है"
किशु मेवाड़ा

0

मैंने @Naveed जे की विधि को इस तरह लागू किया, और यह एक आकर्षण की तरह काम किया।

यहाँ उसका विस्तार था:

extension UIView {

    // Using a function since `var image` might conflict with an existing variable
    // (like on `UIImageView`)
    func asImage() -> UIImage {
        let renderer = UIGraphicsImageRenderer(bounds: bounds)
        return renderer.image { rendererContext in
            layer.render(in: rendererContext.cgContext)
        }
    }
}

यहां बताया गया है कि मैंने इसे कैसे लागू किया।

//create an image from yourView to display
//determine the frame of the view/imageimage
let screen = self.superview!.bounds
let width = screen.width / 4 //make image 1/4 width of screen
let height = width
let frame = CGRect(x: 0, y: 0, width: width, height: height)
let x = (screen.size.width - frame.size.width) * 0.5
let y = (screen.size.height - frame.size.height) * 0.5
let mainFrame = CGRect(x: x, y: y, width: frame.size.width, height: frame.size.height)

let yourView = YourView() //instantiate yourView
yourView.frame = mainFrame //give it the frame
yourView.setNeedsDisplay() //tell it to display (I am not 100% sure this is needed)

let characterViewImage = yourView.asImage()

0

IOS 10 के बाद से उपलब्ध नए UIGraphicsImageRenderer के साथ प्रारंभिक:

extension UIImage{
    convenience init(view: UIView) {

    let renderer = UIGraphicsImageRenderer(size: self.bounds.size)
    let canvas = CGRect(x: 0, y: 0, width: bounds.size.width, height: bounds.size.height)
    let image = renderer.image { _ in
        self.drawHierarchy(in: canvas, afterScreenUpdates: false)
    }
    self.init(cgImage: (image?.cgImage)!)
  }
}

0

मेरे साथ ठीक काम करो!

Swift4

 extension UIView {

    func toImage() -> UIImage {
        UIGraphicsBeginImageContextWithOptions(self.bounds.size, self.isOpaque, 0.0)
        self.drawHierarchy(in: self.bounds, afterScreenUpdates: false)
        let snapshotImageFromMyView = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return snapshotImageFromMyView!
    }

    }

return snapshotImageFromMyView!धागा 1: घातक त्रुटि: एक वैकल्पिक मूल्य को
उजागर

0

देखने के लिए धुंधला सबव्यू (जैसे UIVisualEffectView उदाहरण) शामिल हैं, केवल drawViewHierarchyInRect: afterScreenUpdates काम करता है।

@ वीजे अवध का जवाब इस केस के लिए सही है।


-1
please try below code.
-(UIImage *)getMainImageFromContext
{
UIGraphicsBeginImageContextWithOptions(viewBG.bounds.size, viewBG.opaque, 0.0);
[viewBG.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.