您的位置:首页 > 产品设计 > UI/UE

Deep Analysis UIImageJPEGRepresentation&UIImagePNGRepresentation

2015-08-12 11:57 597 查看
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);
}
];
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: