在开发的过程中,我们一般或多或少遇到对图片进行“压”和“缩”处理。
“压”,一般我们就是使用UIImageJPEGRepresentation
NSData *data = UIImageJPEGRepresentation(image, compression);
UIImage *resultImage = [UIImage imageWithData:data];
进行处理,无非内容稍微变一下,
1.来一个for 循环,压到指定范围返回出,
2.再或者压缩一定比率的时候“压“不动那么进一步的重绘一下然后继续循环“压”处理。
这里不做细节的代码展示。给个想法,自己可以动手敲一下。(放心不会让你做徒劳工的,亲测可行!)
这里详细说一下"缩"的处理。
一般我们对图片进行“缩”处理都是要进行重回操作。
创建图形上下文的方法
方法1 UIGraphicsBeginImageContext(<#CGSize size#>);
方法2 UIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale)
使用两个方法同样都可以创建,但是使用第一个方法将来创建的图片清晰度和质量没有第二种方法的好。
方法2接收三个参数:
CGSize size:指定将来创建出来的bitmap的大小
BOOL opaque:设置透明YES代表透明,NO代表不透明
CGFloat scale:代表缩放,0代表"不"缩放(系统就会自动进行最佳的缩放)
创建出来的bitmap就对应一个UIImage对象
而我们有时候会遇到图片某一个特定区域的剪切处理,获得的图片并没有当时切的时候看到的那么清晰。
这是为什么?
因为 UIGraphicsBeginImageContext(size) = UIGraphicsBeginImageContextWithOptions(size,NO,1.0)
我个人的理解是:
图片再见切的时候它的scale,即缩放比率这里默认不缩放处理,那么剪切出来的图片用UI开发那边的说法即为1倍图,而我们iOS的手机现在市面上的一般都是retain屏幕,像素用一倍图处理处理的图片当然显示出来会比较模糊。那么。我们就可以将需要切的图片的scale写为2.0.这样就可以适配现在所有的手机显示,清晰度问题就解决了。
那么一般开发处理的时候不单单这里改为2.0就没问题了。
你要考虑到2倍的情况下的时候剪切区域的位置问题。尤其对于那些图片显示的时候并非是全屏幕显示的(一般我们的手机为了用户能一下全部看全,会有等比压缩,最大显示处理)那么我们的剪切位置frame.orgain.x与y都应该提取2.0倍。图片的剪切frame.size.width与height也应该2.0倍.(以下的2倍可以做成活的,将UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0)设成0,为最佳缩放处理,然后需要在选择区域位置不再是乘以2,而是乘以
[UIScreen mainScreen].scale,而且在绘制好之后的压缩处理的时候也要除以[UIScreen mainScreen].scale,以达到选择区域的宽度和高度的图片范围)
代码如下:
- (UIImage*)screenView:(UIView *)view{
//这个是可滑动选择的区域位置
CGRect newRect = CGRectMake((_cutView.frame.origin.x + 2 + 8)*2, (_cutView.frame.origin.y + 2 + 8)*2, (_cutView.frame.size.width - 4 - 16)*2, (_cutView.frame.size.height - 4 - 16)*2);
//由于图片不是全屏,先将图片整个屏幕绘制出来,方便滑动区域的位置和目前的位置一致
CGRect rect = CGRectMake(0, 0, kWidth, kHeight);
UIGraphicsBeginImageContextWithOptions(rect.size, NO, 2.0);
CGContextRef context = UIGraphicsGetCurrentContext();
[view.layer renderInContext:context];
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//剪切获取宽高均为2倍的图片绘制
img = [UIImage imageWithCGImage:CGImageCreateWithImageInRect(img.CGImage, newRect)];
//这个方法即为下面的半值压缩处理
img = [self harfWithImage:img toSize:CGSizeMake(img.size.width/2, img.size.height/2)];
return img;
}
然后对我们的照片进行“缩”处理,这个时候,获取的图片大小是我们想要的2倍大小。然后就需要进一步的“缩”1/2处理。
再一次的缩处理,我们还是要缩放选择2.0.即目前的倍率(不让选择1倍或者不缩放处理,结果一样是模糊的图片)。然后将我们的图片绘制到一个宽度和高度都是目前一般的image就可以了。
代码如下(将传入的size大小直接定为传入image的宽和高的一半就好了):
- (UIImage *)harfWithImage:(UIImage *)image toSize:(CGSize)size{
UIGraphicsBeginImageContextWithOptions(size, NO, 2.0);
[image drawInRect:CGRectMake(0, 0, size.width, size.height)];
UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return resultImage;
}
现在得到的代码就是想要的图片,清晰度问题一点都不用担心。和原图一样的清晰度。
next: iOS优秀的图片压缩处理方案(系统UIimagejpeg和uikit以及imageI/O处理)