Deep Analysis UIImageJPEGRepresentation&UIImagePNGRepresentation


 ios中提供了將UIImage轉換成NSData的方法

UIKIT_EXTERN NSData *UIImagePNGRepresentation(UIImage *image);                               // return image as PNG. May return nil if image has no CGImageRef or invalid bitmap format
UIKIT_EXTERN NSData *UIImageJPEGRepresentation(UIImage *image, CGFloat compressionQuality);  // return image as JPEG. May return nil if image has no CGImageRef or invalid bitmap format. compression is 0(most)..1(least)

其中UIImageJPEGRepresentation(UIImage *image, CGFloat compressionQuality)提供了一個壓縮比率的參數compressionQuality,但是實際體驗確實compressionQuality並不能夠按照設定好的數值,按比例壓縮.

比如一張388kb的圖片(jpg格式),通過UIImageJPEGRepresentation方法壓縮

compressionQuality = 1.0 壓縮后圖片大小為979kb;

compressionQuality = 0.5 壓縮后圖片大小為506kb;

compressionQuality = 0.1 壓縮后圖片大小為188kb;

compressionQuality壓縮系數,跟最后文件的大小並沒有明顯的關系,不同的圖片呈現不同結果.

本人對圖片存儲格式不是很了解,但是圖片顏色細節越單一,圖片可壓縮的比率會越高.

這就帶來一個問題,究竟我們如何設置compressionQuality這個參數.我們如何保證圖片的原始大小轉成NSData.

如果圖片是PNG格式, UIImageJPEGRepresentation壓縮率會很高.如果想保證圖片原有質量,就需要用到UIImagePNGRepresentation(UIImage *image).

 

問題1:如何獲得圖片的原始尺寸,發送原圖?

發送圖片的時候需要將圖片轉換成NSData,這時肯定會涉及到UIImageJPEGRepresentation&UIImagePNGRepresentation這兩個方法.

如果是jpg的圖片,如果用了UIImagePNGRepresentation方法,圖片會變得很大.如果用UIImageJPEGRepresentation,又涉及到compressionQuality參數.

如果是png的圖片,直接用UIImagePNGRepresentation方法.關鍵是如何判斷圖片是PNG格式.

解決方案:可以通過判斷圖片的格式選擇合適轉換方法,如果是PNG格式直接用UIImagePNGRepresentation方法,如果是其它格式建議選擇用UIImageJPEGRepresentation方法,通過imagepicker獲取的圖片,可以獲得圖片的擴展屬性,通過這個擴展屬性可以判斷圖片的格式.因為UIImage無法判斷源文件的圖片格式.

 

問題2:如何有效的對圖片進行壓縮?

當使用UIImageJPEGRepresentation方法時,一定要注意compressionQuality參數的設置,設定合理的參數,既保證圖片的壓縮比率,又能保證圖片的清晰度.

 

除了ios提供的UIImageJPEGRepresentation(UIImage *image, CGFloat compressionQuality)方法,我們還可以通過對圖片分辨率的修改,對圖片進行壓縮

圖片大小剪裁:

-(UIImage *) imageCompressForWidth:(UIImage *)sourceImage targetWidth:(CGFloat)defineWidth
{
    CGSize imageSize = sourceImage.size;
    CGFloat width = imageSize.width;
    CGFloat height = imageSize.height;
    CGFloat targetWidth = defineWidth;
    CGFloat targetHeight = (targetWidth / width) * height;
    UIGraphicsBeginImageContext(CGSizeMake(targetWidth, targetHeight));
    [sourceImage drawInRect:CGRectMake(0,0,targetWidth,  targetHeight)];
    UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;
}

通過降低圖片分辨率的方法,可以極大減小圖片的文件大小.

 

相冊ImagePicker獲取Image的兩種方式: 

UIImagePickerControllerOriginalImage:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
        UIImage *orgImage = info[UIImagePickerControllerOriginalImage];
        [picker dismissViewControllerAnimated:YES completion:NULL];
}

UIImagePickerControllerReferenceURL:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
            [library assetForURL:[info objectForKey:UIImagePickerControllerReferenceURL]
                     resultBlock:^(ALAsset *asset)
             {
                 ALAssetRepresentation *representation = [asset defaultRepresentation];
                 CGImageRef imgRef = [representation fullResolutionImage];
                 UIImage *image = [UIImage imageWithCGImage:imgRef
                                                    scale:representation.scale
                                              orientation:(UIImageOrientation)representation.orientation];
                 NSData * data = UIImageJPEGRepresentation(image, 0.5);                

             }failureBlock:^(NSError *error){
                 NSLog(@"couldn't get asset: %@", error);
             }
             ];
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM