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