iOS中大尺寸图片的旋转与缩放实例详解中大尺寸图片的旋转与缩放实例详解
前言前言
由于iPhone的硬件性能限制,直到iPhone 6s开始,才将最大内存拓展到2G。
可即使是如此,也不代表一个应用可使用的空间是2G。
一张10000 x 10000的图片,如果通过UIImageJPEGRepresentation方法将图片转成内存数据,会有一个峰值波动。
这里的峰值其实是图片在解压时产生的位图数据所占空间,然后才转换成我们可以操作的NSData。
其计算公式是 W x H x 4 / 1024 / 1024 也就是 10000 x 10000 x4 /1024 / 1024 = 381.4(M)。
这里会产生381M的消耗,及时会被回收,但是想一下,如果图片尺寸很大,数量很多的时候,很容易就会发生异常了。
本文将给大家详细介绍关于iOS大尺寸图片旋转与缩放的相关内容,分享出来供大家参考学习,话不多说了,接下来说下具体的操作
旋转旋转
我们知道如果对一个UIImage对象进行旋转操作,相信做项目时肯定会有用到 UIImage 这个类,可以有如下的方式
通过通过 CGContextDrawImage 进行图片绘制进行图片绘制
+ (UIImage *)image:(UIImage *)image rotation:(UIImageOrientation)orientation {
long double rotate = 0.0;
CGRect rect;
float translateX = 0;
float translateY = 0;
float scaleX = 1.0;
float scaleY = 1.0;
switch (orientation) {
case UIImageOrientationLeft:
rotate = M_PI_2;
rect = CGRectMake(0, 0, image.size.height, image.size.width);
translateX = 0;
translateY = -rect.size.width;
scaleY = rect.size.width/rect.size.height;
scaleX = rect.size.height/rect.size.width;
break;
default:
rotate = 0.0;
rect = CGRectMake(0, 0, image.size.width, image.size.height);
translateX = 0;
translateY = 0;
break;
}
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
//做CTM变换
CGContextTranslateCTM(context, 0.0, rect.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextRotateCTM(context, rotate);
CGContextTranslateCTM(context, translateX, translateY);
CGContextScaleCTM(context, scaleX, scaleY);
//绘制图片
CGContextDrawImage(context, CGRectMake(0, 0, rect.size.width, rect.size.height), image.CGImage);
UIImage *newPic = UIGraphicsGetImageFromCurrentImageContext();
return newPic;
}
这里有一个问题是,这里会创建一个新的图片大小空间的,然后进行重新绘制。可能会存在一个隐患,就是当图片尺寸过大的时候,就会出现内存占用过高的情况
接下来介绍一种另辟蹊径的解决方法接下来介绍一种另辟蹊径的解决方法–通过给图片添加滤镜的方式。通过给图片添加滤镜的方式。
既然操作的对象是图片,那么它就会各种滤镜展示。系统给我们提供了多大一百多种滤镜,这里的滤镜不单只颜色等状态发生变化。
这其中就有我们需要的滤镜Key inputTransform。
+ (UIImage *)getRotationImage:(UIImage *)image rotation:(CGFloat)rotation {
CIImage *ciImage = [[CIImage alloc] initWithImage:image];
CIFilter *filter = [CIFilter filterWithName:@"CIAffineTransform" keysAndValues:kCIInputImageKey, ciImage, nil];
[filter setDefaults];
CGAffineTransform transform = CATransform3DGetAffineTransform([self rotateTransform:CATransform3DIdentity clockwise:NO angle:rotation]);
[filter setValue:[NSValue valueWithBytes:&transform objCType:@encode(CGAffineTransform)] forKey:@"inputTransform"];
//根据滤镜设置图片
CIContext *context = [CIContext contextWithOptions:@{kCIContextUseSoftwareRenderer : @(NO)}];
CIImage *outputImage = [filter outputImage];
CGImageRef cgImage = [context createCGImage:outputImage fromRect:[outputImage extent]];
UIImage *result = [UIImage imageWithCGImage:cgImage];
CGImageRelease(cgImage);
return result;
}
+ (CATransform3D)rotateTransform:(CATransform3D)initialTransform clockwise:(BOOL)clockwise angle:(CGFloat)angle {
CGFloat arg = angle*M_PI / 180.0f;
if(!clockwise){
arg *= -1;
}
//进行形变
CATransform3D transform = initialTransform;
transform = CATransform3DRotate(transform, arg, 0, 0, 1);
CGFloat _flipState1 = 0;
CGFloat _flipState2 = 0;
transform = CATransform3DRotate(transform, _flipState1*M_PI, 0, 1, 0);
transform = CATransform3DRotate(transform, _flipState2*M_PI, 1, 0, 0);
return transform;
}
通过这种操作,可以利用GPU来进行图片操作,可以一定程度的降低消耗,节约资源。