2011-11-04 15 views
8

अपने iPhone अनुप्रयोग में, मैं iPhone के कैमरे का उपयोग कर रहा हूँ एक तस्वीर लेने के लिए और यह डिस्क (आवेदन के दस्तावेजों फ़ोल्डर) कर बचाने के लिए है। इस प्रकार मैं इसे सहेजता हूं:चित्र लोड धीमी

[UIImageJPEGRepresentation(photoTaken, 0.0) writeToFile:jpegPath atomically:YES]; 

सबसे संपीड़न का उपयोग करके, मुझे लगता है कि डिस्क से छवि को पढ़ने से जल्दी होगा। लेकिन ऐसा नहीं है! मैं अपने विचारों में से किसी एक बटन के लिए पृष्ठभूमि छवि के रूप में छवि का उपयोग करता हूं। मैं इसे इस तरह लोड करता हूं:

[self.frontButton setBackgroundImage:[UIImage imageWithContentsOfFile:frontPath] forState:UIControlStateNormal]; 

जब मैं इस बटन के साथ दृश्य पर नेविगेट करता हूं, तो यह धीमा और चंचल होता है। मैं यह कैसे तय करुं?

उत्तर

37

+imageWithContentsOfFile: तुल्यकालिक है, इसलिए अपने मुख्य थ्रेड पर यूआई डिस्क आपरेशन से छवि लोड हो रहा है और choppiness के कारण द्वारा अवरुद्ध किया जा रहा है। समाधान एक विधि का उपयोग करना है जो फ़ाइल को डिस्क से असीमित रूप से लोड करता है। आप पृष्ठभूमि थ्रेड में भी ऐसा कर सकते हैं। यह मुख्य कतार कि -setBackgroundImage: लपेटता के बाद से UIKit तरीकों मुख्य थ्रेड पर चलाने के लिए की जरूरत पर dispatch_async() में +imageWithContentsOfFile: एक नेस्टेड dispatch_async() लपेटकर, तब तक आसानी से किया जा सकता है। यदि आप व्यू लोड के तुरंत बाद छवि को दिखाना चाहते हैं, तो आपको डिस्क से छवि को प्री-कैश करना होगा ताकि दृश्य दिखाई देने पर तुरंत इन-मेमोरी हो।

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ 

    UIImage *image = [UIImage imageWithContentsOfFile:frontPath]; 

    dispatch_async(dispatch_get_main_queue(), ^{ 
     [self.frontButton setBackgroundImage:image forState:UIControlStateNormal]; 
    }); 

}); 

एक अलग रूप में, अगर बटन छवि एक ढाल होता है, निम्नलिखित गुण का उपयोग कर डिस्क से भरी हुई छवि फ़ाइल सुनिश्चित करने के लिए पर विचार के रूप में छोटे है:

- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets 

या (हटा दिया गया, केवल यदि आप का उपयोग करें आईओएस 4.x का समर्थन करने की आवश्यकता है):

- (UIImage *)stretchableImageWithLeftCapWidth:(NSInteger)leftCapWidth topCapHeight:(NSInteger)topCapHeight 
+0

तुम मेरे जीवन को बचाने! धन्यवाद! –

+0

@Andrew आप प्री-कैश कैसे करते हैं? पुन: –

+0

@Van दू ट्रॅन, इस मामले में पूर्व कैशिंग सिर्फ छवि एक UIImage में इससे पहले कि आप की जरूरत है (उदाहरण के लिए पहले दृश्य दिखाई देता है) लोड हो रहा है का मतलब है "क्या आप डिस्क से-कैश पूर्व करने के लिए छवि की आवश्यकता होगी।" इस तरह, जब आप दृश्य लोड करते हैं, तो छवि पहले से ही स्मृति में आयोजित की जाती है, इसलिए स्क्रीन पर इसे दिखाने के लिए कोई डिस्क I/O आवश्यक नहीं है। – Andrew

2

यह मुझे पता है कि यह तेज़ तरीका है। आपको #import <ImageIO/ImageIO.h>

मैं स्क्रॉलव्यू के अंदर स्क्रॉल के दौरान छवियों को डाउनलोड और संपीड़ित करने के लिए इस कोड का उपयोग करने की आवश्यकता होगी और आप शायद ही देरी पर ध्यान दें।

CGImageSourceRef src = CGImageSourceCreateWithData((CFDataRef)mutableData, NULL); 
CFDictionaryRef options = (CFDictionaryRef)[[NSDictionary alloc] initWithObjectsAndKeys:(id)kCFBooleanTrue, (id)kCGImageSourceCreateThumbnailWithTransform, (id)kCFBooleanTrue, (id)kCGImageSourceCreateThumbnailFromImageIfAbsent, (id)[NSNumber numberWithDouble:200.0], (id)kCGImageSourceThumbnailMaxPixelSize, nil]; 
CGImageRef thumbnail = CGImageSourceCreateThumbnailAtIndex(src, 0, options); 

UIImage *image = [[UIImage alloc] initWithCGImage:thumbnail]; 
// Cache 
NSString *fileName = @"fileName.jpg"; 
NSString *path = [NSTemporaryDirectory() stringByAppendingPathComponent:@"thumbnail"]; 
path = [path stringByAppendingPathComponent:fileName]; 
if ([UIImagePNGRepresentation(image) writeToFile:path atomically:YES]) { 
    // Success 
} 
+0

से उपयोग करने के लिए इस कोड को अभी भी आप के लिए धीमी गति से हैं, तो आप सिर्फ एक धागा अंदर डाल करने की आवश्यकता है के लिए सुरक्षित कर रहे हैं। कृपया ध्यान दें कि "200।0 "अधिकतम आकार है जिसे आप पिक्सेल में चाहते हैं। –

0

मुझे एक बहुत ही समान समस्या का सामना करना पड़ा जहां मुझे निर्देशिका से सैकड़ों छवियों को लोड करना पड़ा। यदि मैं UIImage (contentOfFile :) विधि का उपयोग करता हूं तो मेरा प्रदर्शन काफी धीमा था। नीचे दी गई विधि ने मेरा प्रदर्शन 70% बढ़ा दिया।

वर्ग ImageThumbnailGenerator: ThumbnailGenerator { निजी देना यूआरएल: यूआरएल

init(url: URL) { 
     self.url = url 
    } 

func generate(size: CGSize) -> UIImage? { 
    guard let imageSource = CGImageSourceCreateWithURL(url as NSURL, nil) else { 
     return nil 
    } 

    let options: [NSString: Any] = [ 
     kCGImageSourceThumbnailMaxPixelSize: Double(max(size.width, size.height) * UIScreen.main.scale), 
     kCGImageSourceCreateThumbnailFromImageIfAbsent: true 
    ] 

    return CGImageSourceCreateThumbnailAtIndex(imageSource, 0, options as NSDictionary).flatMap { UIImage(cgImage: $0) } 
} 
} 
संबंधित मुद्दे