苹果手机照片怎么缩小尺寸(iOS 内存优化 图片缩略图)




iOS的内存管理非常重要。处理不好会导致页面卡顿,或者App崩溃掉线。基本上,所有应用崩溃都与内存有关。

在平时的开发中,会用到大量的图片。在处理高分辨率图片时,因为画质太高,有时需要对图片进行压缩(目前新iPhone机型拍摄的照片都是高精度的,图片非常大,如果不压缩可能会造成死机)。

Apple提供了五种生成缩略图的方法。

UIKit

UIGraphicsBeginImageContextWithOptions(大小,是,0); [self drawin rect:CGRectMake(0,0,size.width,size . height)]; ui image * image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext();画图时,drawInRect会先解码图片,然后生成原始分辨率的位图。此过程会消耗大量内存,因此应避免生成中间位图。

核心显卡

CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef);CGContextRef context = CGBitmapContextCreate(nil, size.width, size.height, bytePerComponent, bytePerRow, colorSpace, bitmapInfo); //设置插值质量 cgcontextsetinterpolation质量(context,kcginterpolarization高); //drawing cgcontextdrawimage(context,cgrectmake (0,0,size.width,size.height),imageref); //生成imageref cgimageref bitmapimageref = cgbitmapcontextcreateimage(context); ui image * image =[ui image imagewithcigimage:bitmapImageRef scale:self . scale orientation:self . image orientation];CGBitmapContextCreate重新生成一个位图,然后在这个位图上绘制图片,最后得到压缩后的图片。

核心映像

ci image * ci image input =[ci image imageWithCGImage:imageRef]; ci filter * filter =[ci filter filter with name:@ & # 34;CILanczosScaleTransform & # 34]; [filter setValue:ci image input forKey:kCIInputImageKey]; [过滤器设置值:[ns number number with double:scale]forKey:kCIInputScaleKey]; [过滤器设置值:@(1.0)forKey:kciinputasperationkey]; ci image * ci image output =[filter value forkey:kCIOutputImageKey]; 如果(!ciImageOutput) { 返回nil } ci context * ci context =[[ci context alloc]init with options:@ { kcicontextusesoftware renderer:@(NO)}]; CGImageRef ci imageref =[ci context create cgimage:ci image output from rect:CGRectMake(0,0,size.width,size . height)];这种性能比较差,不推荐。

ImageIO

//获取原始图片属性 cfdictionaryef property = cgimagesourcecopyproperties at index(image source,0,nil); ns dictionary * properties = CFBridgingRelease(property); CG float height =[properties[@ & # 34;像素高度& # 34;]integer value];//图片K宽高,12000 CG float width =[Properties[@ & # 34;像素宽度& # 34;]integer value]; //基于较大的边 int image size =(int)max(size。宽度,大小。身高); CFStringRef keys[5]; CFTypeRef值[5]; //创建一个缩放大小相等的缩略图,将根据长度和宽度值中较大的一个进行缩放,作为生成的缩略图大小imageSize /kcgimageresourcenumnaimapixelsize。设置为800时,如果图片本身大于800*600,则生成的图片大小为800*600,如果源图片为700*500,则生成的图片为800 * 500 keys[0]= kcgimageresourcenumnaimapixelsize; CFNumberRef thumbnailSize = CFNumberCreate(NULL,kCFNumberIntType,& imageSize); values[0]=(cf typeref)thumbnail size; keys[1]= kcgimagesourcecreatethumbnailfroimagealways; values[1]=(cf typeref)kcfbooleentrue; keys[2]= kcgimagesourcecreatethumbnailwithstransform; values[2]=(cf typeref)kcfbooleentrue; keys[3]= kcgimagesourcecreatethumbnailfroimageifabsent; values[3]=(cf typeref)kcfbooleentrue; keys[4]= kCGImageSourceShouldCacheImmediately; values[4]=(cf typeref)kcfbooleentrue; CFDictionaryRef options = cfdictionaryrecreate(kCFAllocatorDefault,(const void **)keys,(const void **)values,4,&kCFTypeDictionaryKeyCallBacks,& kCFTypeDictionaryValueCallBacks); CGImageRef thumbnail image = CGImageSourceCreateThumbnailAtIndex(image source,0,options); ui image * result img =[ui image image with gimage:thumbnail image];ImageIO是一个独立的框架,很低级,但是很强大。

VImage

//定义argb 8888 V image _ CG image format格式的结构格式; format . bitsper component = 8; format . bitsperpixel = 32;//ARGB四通道4 * 8 format . color space = nil;//Default srgb format . bitmapinfo = kcgimagalphahfirst | kcgbitmapbyteorderdefault;//表示ARGB format . version = 0; format . decode = nil;//默认颜色映射范围[0,1.0] 格式。渲染意图= kcgrenderingingtefault//当 //源图片缓冲区超出[0,1]范围时怎么办,输出图片缓冲区 vimage _ buffersource buffer,输出缓冲区; vImage _ Error Error = vImage buffer _ initwithcigimage(& source buffer,&format,nil,imageRef,kvImageNoFlags); if(错误!= kvImageNoError){ return nil; } float scale = self . scale; int width =(int)size . width; int height =(int)size . height; int bytes per pixel =(int)CGImageGetBitsPerPixel(imageRef)/8; //设置输出格式 output buffer . width = width; output buffer . height = height; output buffer . row bytes = bytes per pixel * width; output buffer . data = malloc(output buffer . row bytes * output buffer . height); //缩放到当前大小 Error = vimagescale _ argb 8888(& source buffer,& outputbuffer,nil,kvagehighquality resampling); if(错误!= kvImageNoError){ return nil; } CGImageRef output imageref = vImageCreateCGImageFromBuffer(& output buffer,&format,nil,nil,kvImageNoFlags,& error);

相比较而言,推荐使用第一种方法获取原图中间部分的缩略图。

照片怎么缩小尺寸

-(ui image *)getThumbnailWithTargetSize:(CGSize)targetSize { CGSize imageSize = self . size; if(CGSizeEqualToSize(targetSize,cgsizezezero)){ 返回self } if(targetsize . width & gt;imagesize . width & & targetsize . height & gt;imageSize.height) { 返回自我; } CG float scale = MAX(targetsize . width/imagesize . width,targetsize . height/imagesize . height); CGSize scaleSize = CGSizeMake(imagesize . width * scale,imagesize . height * scale); UIGraphicsBeginImageContextWithOptions(targetSize,false,0); UIBezierPath * bezierPath =[UIBezierPath bezierPathWithRect:CGRectMake(0,0,targetSize.width,targetsize . height)]; [bezier path add clip]; CGRect rect = CGRectMake((targetsize . width-scaleSize.width)/2,(targetsize . height-scalesize . height)/2,scalesize . width,scalesize . height); [self drawin rect:rect]; ui image * new image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); 返回newImage }对于用户上传的图片,要做好判断。如果超过一定大小,最好压缩图片;对于列表中显示的图片,如果服务器不返回缩略图,如果是大图,不处理列表滚动就会卡死。

您可以还会对下面的文章感兴趣

使用微信扫描二维码后

点击右上角发送给好友