成都网站建设设计

将想法与焦点和您一起共享

ios开发图片处理,ios照片后期处理软件

iOS开发中加载图片的内存问题以及优化方案

图片的加载方式 iOS 目前有2种:

成都创新互联为客户提供专业的网站制作、成都网站制作、程序、域名、空间一条龙服务,提供基于WEB的系统开发. 服务项目涵盖了网页设计、网站程序开发、WEB系统开发、微信二次开发、手机网站开发等网站方面业务。

1.Resource 它是指inageWithContentsFile:创建图片的图片管理方式;

2.ImageAssets 它是指使用imageNamed:创建图片的图片的管理方式;

UIImage内存处理:

真是的App开发中,常用的无非是1和2两种方式

1的优缺点:

1的使用方式:NSString *path =[[NSBundle mainBundle]pathForResource:@"image@2x" type:@"png"];

UIImage *image = [UIImage imageWithContentsOfFile:path];

1的内部实现方式:+ (instancetype)imageWithContentsOfFile:(NSString *)fileName {

NSUInteger scale = 0;

{

scale = 2;//这一部分是提取fileName中@号后面的那个数字,如果存在则为1

}

return [[self alloc] initWithData:[NSData dataWithContentsOfFile:fileName scale:scale]];

}

这种方式使用的时候会有个局限性,这个图片必须是在.ipa的根目录或者沙盒中。根目录就是把图片文件拖到工程中,沙盒中的图片是写入进去或者存进去的;

1的特性:在1的图片管理方式中,所有的图片创建都是通过读取文件数据得到的,读取一次文件数据就会产生一次NSData以及产生一个UIImage,当图片创建好后会销毁对应的NSData,当UIImage的引用计数变为0的时候自动销毁UIImage,这样的话就可以保证图片不会长期存在内存中。

1的使用场景:由于这种方法的特性,所以1得方法一般用在图片数据很大,图片一般不需要多次使用的情况,比如引导页面的背景(图片全屏),有时候运行APP才显示,有时候根本就用不到。

1的优点:图片的生命周期可以得到管理,当需要图片的时候就创建一个,当不需要图片的时候就让他销毁,图片不会长期的保存在内存中,因此不会有内存浪费,在减少大图的内存占用中,1方式优先。

2的方式:2的设计初衷主要是为了解决自动适配Retian屏和非Retian屏,也就是说为了解决iPhone4和iPhone3GS以及以前的机型的屏幕适配,虽然没有3GS了,但是plus出来了,需要3x

2的使用方式:UIImage *image = [UIImage imageName:@"image"];

2的特性:与1相似,2也是从图片文件中读取图片数据转化成UIImage,只不过这些图片都打包在2中,最大的区别就是图片有缓存。相当于与一个字典,key是图片名,value是图片对象。调用imageNamed:方法的时候先从这个字典中去取,如果取到就直接返回,如果娶不到再去文件中创建,然后保存在这个字典中。由于字典的key和value都是强引用,所以一旦创建后的图片永不销毁。

2的内部实现方式:+(instancetype)imageName:(NSString*)imageName {

if(!imageName)

return nil;

}

UIImage *image = self.imageBuff[imageName];

if(image){

return image;

}

NSString *path = @"image Path";

image = [UIImage imageNamed:  ];

if(image){

self.imageBuff[imageName] = image;

}

return image;

}

+ (NSMutableDictionary*)imageBuff {

static NSMutableDictionary *_imageBuff;

static dispatch_once_t onceToken;

dispatch_once(onceToken,^{

_imageBuff = [[NSMutableDictionary alloc]init];

});

return _imageBuff;

}

2的使用场景:最主要的使用场景就是icon类的图片,一般的icon类的图片大小在3kb到20kb不等,都是一些小文件

2的优点:当一个icon在多个地方需要被显示的时候,其对应的UIImage对象只会被创建1次,而且多个地方的icon都将会共用一个UIImage对象,减少沙盒的读取操作。

iOS 开发中的图片压缩

在项目中经常遇到要上传图片,如果直接上传,那么会上传比较大的图片,导致费流量,刷新时加载图片时间过长,手机内存占用率高等问题。

一、先来介绍下概念:

图片的压缩其实是俩概念,

1、是 “压” 文件体积变小,但是像素数不变,长宽尺寸不变,那么质量可能下降,

2、是 “缩” 文件的尺寸变小,也就是像素数减少。长宽尺寸变小,文件体积同样会减小。

二、解决方法(以上传头像为例),先缩再压:

2.1 矫正图片方向(照片是有方向的,避免出现“倒立”的情况)

- (UIImage*)fixOrientation:(UIImage*)aImage {

// No-op if the orientation is already correct

if(aImage.imageOrientation==UIImageOrientationUp)

returnaImage;

// We need to calculate the proper transformation to make the image upright.

// We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.

CGAffineTransformtransform =CGAffineTransformIdentity;

switch(aImage.imageOrientation) {

caseUIImageOrientationDown:

caseUIImageOrientationDownMirrored:

transform =CGAffineTransformTranslate(transform, aImage.size.width, aImage.size.height);

transform =CGAffineTransformRotate(transform,M_PI);

break;

caseUIImageOrientationLeft:

caseUIImageOrientationLeftMirrored:

transform =CGAffineTransformTranslate(transform, aImage.size.width,0);

transform =CGAffineTransformRotate(transform,M_PI_2);

break;

caseUIImageOrientationRight:

caseUIImageOrientationRightMirrored:

transform =CGAffineTransformTranslate(transform,0, aImage.size.height);

transform =CGAffineTransformRotate(transform, -M_PI_2);

break;

default:

break;

}

switch(aImage.imageOrientation) {

caseUIImageOrientationUpMirrored:

caseUIImageOrientationDownMirrored:

transform =CGAffineTransformTranslate(transform, aImage.size.width,0);

transform =CGAffineTransformScale(transform, -1,1);

break;

caseUIImageOrientationLeftMirrored:

caseUIImageOrientationRightMirrored:

transform =CGAffineTransformTranslate(transform, aImage.size.height,0);

transform =CGAffineTransformScale(transform, -1,1);

break;

default:

break;

}

// Now we draw the underlying CGImage into a new context, applying the transform

// calculated above.

CGContextRefctx =CGBitmapContextCreate(NULL, aImage.size.width, aImage.size.height,

CGImageGetBitsPerComponent(aImage.CGImage),0,

CGImageGetColorSpace(aImage.CGImage),

CGImageGetBitmapInfo(aImage.CGImage));

CGContextConcatCTM(ctx, transform);

switch(aImage.imageOrientation) {

caseUIImageOrientationLeft:

caseUIImageOrientationLeftMirrored:

caseUIImageOrientationRight:

caseUIImageOrientationRightMirrored:

CGContextDrawImage(ctx,CGRectMake(0,0,aImage.size.height,aImage.size.width), aImage.CGImage);

break;

default:

CGContextDrawImage(ctx,CGRectMake(0,0,aImage.size.width,aImage.size.height), aImage.CGImage);

break;

}

CGImageRef cgimg =CGBitmapContextCreateImage(ctx);

UIImage *img = [UIImageimageWithCGImage:cgimg];

CGContextRelease(ctx);

CGImageRelease(cgimg);

return img;

}

2.2 拿到上面矫正过的图片,缩小图片尺寸,调用下面方法传入newSize,如(200,200):

+ (UIImage*)imageWithImageSimple:(UIImage*)image scaledToSize:(CGSize)newSize

{

UIGraphicsBeginImageContext(newSize);

[imagedrawInRect:CGRectMake(0,0,newSize.width,newSize.height)];

UIImage* newImage =UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

return newImage;

}

2.3 将2.2的图片再压,这个方法可以重复压

//调整大小

NSData *imageData =UIImageJPEGRepresentation(newImage,rate);

NSUIntegersizeOrigin = [image Datalength];//多少KB

NSUIntegersizeOriginKB = sizeOrigin /1024;//多少KB

2.4 上传头像

调用后台接口,把imageData二进制数据上传即可

总结:对图片压缩处理时,在保证图片清晰度变化不大时,减小图片文件大小。方法2.2中的newSize 和 2.3中的rate要以实际效果来设置,我在自己项目中上传的头像最终尺寸是200*200像素,大小为4KB左右。

iOS图片滤镜开发,GPUImage 图像处理

对于iOS开发者而言,想要打造一款美图App,最佳首选的开源框架莫过于GPUImage。它内嵌了上百种图像滤镜,能够满足市面上的一切美颜开发方案。同时也具备了实时美颜的功能。通过这样强大的开源框架,我们可以在其上层开发属于我们自己的美图应用。SnapseedImitation 是以Snapseed为原型,利用GPUImage框架开发的图像处理软件。

SnapseedImitation

Github地址:

主要依赖GPUImage Github:

1.安装Cocoapods

2.pod 'GPUImage'

3. improt 导入GPUImage.h后编译即可。

通过GPUImagePicture获取待编辑图像,再经过GPUImageFilter渲染后产出一帧frame,经由消息管道通知后,便可在GPUImageView显示编辑后的图片,或者我们可以通过GPUImageFilter直接导出渲染后的UIImage。

GPUImageInputGPUImageFilterGPUImageOutput

以拉升变形滤镜为例:

//@拉升变形镜滤镜

//创造输入源

GPUImagePicture* gpupicture = [[GPUImagePicturealloc]initWithImage:[UIImageimageNamed:@"Duck.jpg"]];

//创建滤镜

PUImageStretchDistortionFilter* stretchDistortionFilter = [GPUImageStretchDistortionFilternew];

//为滤镜赋值

stretchDistortionFilter.center=CGPointMake(0.2,0.2);

//将输入源和滤镜绑定

[gpupicture addTarget:stretchDistortionFilter];

//为原图附上滤镜效果[gpupicture processImage];

//滤镜收到原图产生的一个frame,并将它作为自己的当前图像缓存

[stretchDistortionFilter useNextFrameForImageCapture];

//通过滤镜,获取当前的图像。

UIImage*image = [stretchDistortionFilter imageFromCurrentFramebuffer];

图像拉升变形前后对比 :

开发过程中,必然会有多种滤镜复合的需求,例如一个可以变化亮度、对比度、曝光的图像调节程序。但是依照上一个示例,我们每添加一种滤镜,便会代替之前的滤镜效果。如果每次处理的都是上一次的filter导出的UIImage图片的话,又会导致无法恢复到原图样子,导致失真。(可参考在绘画板中,把图片缩小到最小,再放大,图片变成为了一个像素块。)

这时候,我们需要一个很好用的类:GPUImageFilterPipeline

GPUImageFilterPipeline可以将多个滤镜进行复合,并且在多次处理后,仍然能够恢复成为原图不失真。

仍然以拉升变形和卡通描边效果为例 :

//获取原图

GPUImagePicture* gpupicture = [[GPUImagePicturealloc]initWithImage:[UIImageimageNamed:@"Duck.jpg"]];

//输出图像的

ViewGPUImageView* gpuimageView = [[GPUImageViewalloc]initWithFrame:CGRectMake(0,60,320,320)];[self.viewaddSubview:gpuimageView];

//卡通描边滤镜

GPUImageToonFilter* toonFilter = [GPUImageToonFilternew];toonFilter.threshold=0.1;

//拉升变形滤镜

GPUImageStretchDistortionFilter* stretchDistortionFilter = [GPUImageStretchDistortionFilternew];

stretchDistortionFilter.center=CGPointMake(0.5,0.5);

//将滤镜组成数组

NSArray* filters = @[toonFilter,stretchDistortionFilter];

//通过pipline,将输入源,输出,滤镜,三方绑定

GPUImageFilterPipeline* pipLine = [[GPUImageFilterPipelinealloc]initWithOrderedFilters:filters input:self.gpupictureoutput:self.gpuimageView];

//绘制产出最终带有复合滤镜的图像。

[self.gpupictureprocessImage];

//获取产出的UIImage图像

//此时调用useNextFrameForImageCapture的可以是任一在数组中的Filter。

[stretchDistortionFilter useNextFrameForImageCapture];

UIImage* image = [self.pipLinecurrentFilteredFrame];

基于GPUImage框架,我为其添加了一套了Snapseed的UI,通过手势识别方案对图像滤镜进行调节拖控。

更多内容:

GPUImage 进阶学习,实时视频录制,人脸检测

iOS 开发-UIImageViews(图片)的使用

UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"bgImage"]]; 

创建并设置默认图, 也可以

UIImageView*imageView = [[UIImageView alloc] init];

imageView.image= [UIImageimageNamed:@"bgImage"];

还可以这样先设置imageview的大, 在设置图片

UIImageView*imageView = [[UIImageView alloc] initWithFrame:(CGRectMake(0,144,SCREEN_Width,50))];

imageView.image= [UIImageimageNamed:@"bgImage"];

由此可看imageview的frame可以这样设置

imageView.frame=CGRectMake(0,144,SCREEN_Width,50);

通常我们使用的的imageview都会添加圆角边框

imageView.layer.masksToBounds = YES;

imageView.layer.cornerRadius=25;

imageView.layer.borderColor = [UIColor blueColor].CGColor;

imageView.layer.borderWidth=1;

这个圆角和边框像view和label以及button的设置方式都是一样的 当然imageview也一样

imageView.backgroundColor= [UIColorclearColor]; 图片设置背景颜色, 我通常使用clearColor  透明

 imageView.userInteractionEnabled = YES; 图片设置成可交互, 设置为NO则不能交互

[self.viewaddSubview: imageView]; 添加视图也可叫做显示视图

设置图片内容的布局方式 imageView.contentMode

这个属性是用来设置图片的显示方式,如居中、居右,是否缩放等

imageView.contentMode = UIViewContentModeScaleAspectFit;

UIViewContentMode contentMode枚举类型

    (1)  UIViewContentModeScaleToFill;     默认,对图片进行拉伸处理(不是按比例),是充满bouns

  (2)  UIViewContentModeScaleAspectFit;     按原图比例进行拉伸,是图片完全展示在bouns中

    (3)  UIViewContentModeScaleAspectFill;     按原图比例填充,使图片展示在bouns中,可能只显示部分

    (4)  UIViewContentModeRedraw;     重划边界变化(重设 - setNeedsDisplay)

    (5)  UIViewContentModeCenter;     图片显示在imageview的正中间,原图大小

    (6)  UIViewContentModeTop;     图片显示在imageview的上部,原图大小

    (7)  UIViewContentModeBottom;     图片显示在imageview的下部,原图大小

    (8)  UIViewContentModeLeft;     图片显示在imageview的左部,原图大小

    (9)  UIViewContentModeRight;     图片显示在imageview的右部,原图大小

    (10)  UIViewContentModeTopLeft;     图片显示在imageview的左上部,原图大小

    (11)  UIViewContentModeTopRight;     图片显示在imageview的右上部,原图大小

    (12)  UIViewContentModeBottomLeft;     图片显示在imageview的左下部,原图大小

    (13)  UIViewContentModeBottomRight;     图片显示在imageview的右下部,原图大小

imageView.alpha = 1.0;    设置图片透明度

   NSString *path1 = [[NSBundle mainBundle] pathForResource:@"1" ofType:@"jpg"];

   NSString *path2 = [[NSBundle mainBundle] pathForResource:@"2" ofType:@"jpg"];

   NSString *path3 = [[NSBundle mainBundle] pathForResource:@"3" ofType:@"jpg"];

   imageView.animationImages = @[[UIImage imageWithContentsOfFile:path1],[UIImage imageWithContentsOfFile:path2],[UIImage imageWithContentsOfFile:path3]];

   imageView.animationDuration = 5.0f;    设置循环一次的时间

   imageView.animationRepeatCount = 0;    // 设置循环次数(0为无线循环)

   [imageView startAnimating];            // 开始动画

   [imageView stopAnimating];              // 停止动画

NSData *imageData = [NSData dataWithContentsOfFile:path];

UIImage *image4 = [UIImage imageWithData:imageData];

NSString *path = [[NSBundle mainBundle] pathForResource:@"1" ofType:@"jpg"];

UIImage *image2 = [UIImage imageWithContentsOfFile:path];

ImageView.hidden = NO;    隐藏或者显示图片 YES为隐藏

[ImageView sizeToFit];    将图片尺寸调整为与内容图片相同

UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapImageView:)]; // 设置手势

[ImageView addGestureRecognizer:singleTap]; // 给图片添加手势


本文标题:ios开发图片处理,ios照片后期处理软件
文章位置:http://chengdu.cdxwcx.cn/article/hoggho.html