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