2012-02-29 17 views
24

मैं छवियों (कैमरा/फोटो लाइब्रेरी) को संपीड़ित करना चाहता हूं और फिर इसे सर्वर पर भेजना चाहता हूं। मुझे पता है कि मैं ऊंचाई और चौड़ाई से संपीड़ित कर सकता हूं, लेकिन मैं आकार के अनुसार छवियों को एक निश्चित आकार (200 केबी) तक संकुचित करना चाहता हूं और मूल ऊंचाई और चौड़ाई को रखना चाहता हूं। जेपीईजी प्रतिनिधित्व में स्केल कारक आकार और केवल संपीड़न गुणवत्ता का प्रतिनिधित्व नहीं करता है। किसी भी तृतीय पक्ष लाइब्रेरी का उपयोग किए बिना मैं इसे कैसे प्राप्त कर सकता हूं (एक निश्चित आकार में संपीड़ित)? किसी भी मदद के लिए धन्यवाद।छवि संपीड़न - आईफोन एसडीके

+0

वहाँ SDK में इसके लिए कोई एपीआई है। जैसा कि आप पाते हैं, आप या तो संकल्प या गुणवत्ता के द्वारा आकार बदल सकते हैं। हमें एक ही समस्या थी और आखिरकार हमने स्क्रीन डिस्प्ले का आकार बदलने और 85% तक संपीड़ित करने का निर्णय लिया जो फ़ाइल आकार को नाटकीय रूप से कम करता है लेकिन फिर भी एक बहुत अच्छी छवि गुणवत्ता प्रदान करता है। –

उत्तर

62

Heres कुछ उदाहरण कोड है कि इतना है कि यह या तो एक अधिकतम संपीड़न या अधिकतम फ़ाइल आकार

CGFloat compression = 0.9f; 
CGFloat maxCompression = 0.1f; 
int maxFileSize = 250*1024; 

NSData *imageData = UIImageJPEGRepresentation(yourImage, compression); 

while ([imageData length] > maxFileSize && compression > maxCompression) 
{ 
    compression -= 0.1; 
    imageData = UIImageJPEGRepresentation(yourImage, compression); 
} 
+2

उपरोक्त लिखित कोड महान काम करता है :)। लेकिन मैं चाहता हूं कि मेरी छवि 20 केबी तक संपीड़ित हो, मैंने आपके कोड के साथ खेलने की कोशिश की। लेकिन केवल 200 केबी के आकार को पाने में सक्षम, क्या आप मुझे एक तरीका बता सकते हैं कि मैं 20 केबी कैसे प्राप्त कर सकता हूं। –

+0

@DeepK ऊपर क्या समाधान करता है मूल छवि को संपीड़ित करता है। अधिकतम संपीड़न आपको अपेक्षाकृत समाधान नहीं मिल सकता है। तो संपीड़ित डेटा से छवि बनाएं और तब तक छवि को तब तक संपीड़ित करें जब तक आप जो चाहते हैं उसे प्राप्त न करें। एक विचार है। – CodetrixStudio

+0

@ कोडेट्रिक्स समाधान का सुझाव देने के लिए धन्यवाद। –

3

ऐसा करने का एक तरीका है, जब तक आप वांछित आकार नहीं पाते, तब तक फ़ाइल को लूप में दोबारा संपीड़ित करना है। आप पहली बार ऊंचाई और चौड़ाई पा सकते हैं, और संपीड़न कारक (बड़ी छवि अधिक संपीड़न) का अनुमान लगा सकते हैं, फिर इसे संपीड़ित करने के बाद, आकार की जांच करें, और फिर अंतर को विभाजित करें।

मुझे पता है कि यह सुपर कुशल नहीं है, लेकिन मुझे विश्वास नहीं है कि एक विशिष्ट आकार की छवि प्राप्त करने के लिए एक ही कॉल है।

1

यहाँ से अधिक नहीं है आप के लिए एक छवि सेक करने का प्रयास करेंगे, JPEGRepresentation काफी स्मृति लगता है और अगर हम का उपयोग लूप में तो यह बेहद उच्च स्मृति उपभोग है। तो नीचे कोड & का उपयोग करें छवि आकार 200KB से अधिक नहीं होगा।

UIImage* newImage = [self captureView:yourUIView]; 


- (UIImage*)captureView:(UIView *)view { 
CGRect rect = view.bounds; 
UIGraphicsBeginImageContext(rect.size); 
CGContextRef context = UIGraphicsGetCurrentContext(); 

[view.layer renderInContext:context]; 
UIImage* img = [UIImage alloc]init]; 
img = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 
NSLog(@"img=%@",img); 
return img; 
} 
-1
- (UIImage *)resizeImageToSize:(CGSize)targetSize 
{ 
    UIImage *sourceImage = captureImage; 
    UIImage *newImage = nil; 

    CGSize imageSize = sourceImage.size; 
    CGFloat width = imageSize.width; 
    CGFloat height = imageSize.height; 

    CGFloat targetWidth = targetSize.width; 
    CGFloat targetHeight = targetSize.height; 

    CGFloat scaleFactor = 0.0; 
    CGFloat scaledWidth = targetWidth; 
    CGFloat scaledHeight = targetHeight; 

    CGPoint thumbnailPoint = CGPointMake(0.0,0.0); 

    if (CGSizeEqualToSize(imageSize, targetSize) == NO) { 

     CGFloat widthFactor = targetWidth/width; 
     CGFloat heightFactor = targetHeight/height; 

     if (widthFactor < heightFactor) 
      scaleFactor = widthFactor; 
     else 
      scaleFactor = heightFactor; 

     scaledWidth = width * scaleFactor; 
     scaledHeight = height * scaleFactor; 

     // make image center aligned 
     if (widthFactor < heightFactor) 
     { 
      thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5; 
     } 
     else if (widthFactor > heightFactor) 
     { 
      thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5; 
     } 
    } 

    UIGraphicsBeginImageContext(targetSize); 
    CGRect thumbnailRect = CGRectZero; 
    thumbnailRect.origin = thumbnailPoint; 
    thumbnailRect.size.width = scaledWidth; 
    thumbnailRect.size.height = scaledHeight; 

    [sourceImage drawInRect:thumbnailRect]; 
    newImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 

    if(newImage == nil) 
     NSLog(@"could not scale image"); 

    return newImage ; 
} 
+0

सवाल विशेष रूप से _file size_ के लिए पूछ रहा है, छवि आयाम नहीं – bengoesboom

0

में कुछ परीक्षण करने के बाद, मैं A relationship between image size and compression value को खोजने के लिए सक्षम था। चूंकि यह संबंध सभी मानों के लिए रैखिक है जहां संपीड़न 1 से कम है, मैंने एक निश्चित मूल्य पर छवियों को हमेशा संपीड़ित करने का प्रयास करने के लिए एक एल्गोरिदम बनाया है।

//Use 0.99 because at 1, the relationship between the compression and the file size is not linear 
NSData *image = UIImageJPEGRepresentation(currentImage, 0.99); 
float maxFileSize = MAX_IMAGE_SIZE * 1024; 

//If the image is bigger than the max file size, try to bring it down to the max file size 
if ([image length] > maxFileSize) { 
    image = UIImageJPEGRepresentation(currentImage, maxFileSize/[image length]); 
} 
+2

यह उत्तर है सही और भ्रामक नहीं है। कृपया इसे हटाने पर विचार करें – ikbal

0

मैं @kgutteridge का जवाब लिया और स्विफ्ट 3.0 पुनरावर्ती प्रयोग करने के लिए इसी तरह की एक समाधान बनाया:

extension UIImage { 
    static func compress(image: UIImage, maxFileSize: Int, compression: CGFloat = 1.0, maxCompression: CGFloat = 0.4) -> Data? { 

     if let data = UIImageJPEGRepresentation(image, compression) { 

      let bcf = ByteCountFormatter() 
      bcf.allowedUnits = [.useMB] // optional: restricts the units to MB only 
      bcf.countStyle = .file 
      let string = bcf.string(fromByteCount: Int64(data.count)) 
      print("Data size is: \(string)") 

      if data.count > (maxFileSize * 1024 * 1024) && (compression > maxCompression) { 
       let newCompression = compression - 0.1 
       let compressedData = self.compress(image: image, maxFileSize: maxFileSize, compression: newCompression, maxCompression: maxCompression) 
       return compressedData 
      } 

      return data 
     } 

     return nil 
    } 
}