最近复习了一下wwdc2018的课程
Image and Graphics Best Practices
(视频里面可以调中文字幕,强烈建议观看后再阅读本文)
视频里用swift写的,下文用OC实现了一遍
针对第一章的缩略图复习写了一遍,记录一下
一张图片,原图大小为3280 × 1940,png格式,因为他压缩过,所以只有5.6MB,但在运行时解压后……先来看一下图片和需求
![](https://img.haomeiwen.com/i1113278/cfc37deeb816ff2f.png)
我们的需求是用一个宽100高40的UIImageView把他展示出来,像下面这样
![](https://img.haomeiwen.com/i1113278/3ceea756d6ec9376.jpeg)
当你没有好好用视频里这个下采样知识的时候,一张图片占用的内存甚至可以高达65.5MB,即使ImageView的宽高只有100x40,还是把整张原图解码塞进内存里去了
![](https://img.haomeiwen.com/i1113278/8701758618ea2d34.png)
当我们用了这个以后,哼哼
![](https://img.haomeiwen.com/i1113278/468772512475a38f.png)
上面两段代码的显示结果几乎没有差别,但内存占用却有如此大的差距
话不多说,上代码,笔记都在注释里,建议复制到Xcode里阅读
- (UIImage *)downSamplingImgUrl:(NSURL *)imgURL
toPointSize:(CGSize)pointSize
scale:(CGFloat)scale {
//避免下次产生缩略图时大小不同,但被缓存了,取出来是缓存图片
//所以要把kCGImageSourceShouldCache设为false
CFStringRef key[1];
key[0] = kCGImageSourceShouldCache;
CFTypeRef value[1];
value[0] = (CFTypeRef)kCFBooleanFalse;
CFDictionaryRef imageSourceOption = CFDictionaryCreate(NULL,
(const void **) key,
(const void **) value,
1,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
CGImageSourceRef imageSource = CGImageSourceCreateWithURL((__bridge CFURLRef)imgURL, imageSourceOption);
CFMutableDictionaryRef mutOption = CFDictionaryCreateMutable(NULL,
4,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
CGFloat maxDimension = MAX(pointSize.width, pointSize.height) * scale;
NSNumber *maxDimensionNum = [NSNumber numberWithFloat:maxDimension];
// · kCGImageSourceCreateThumbnailFromImageAlways
//这个选项控制是否生成缩略图(没有设为true的话 kCGImageSourceThumbnailMaxPixelSize 以及 CGImageSourceCreateThumbnailAtIndex不会起作用)默认为false,所以需要设置为true
CFDictionaryAddValue(mutOption, kCGImageSourceCreateThumbnailFromImageAlways, kCFBooleanTrue);//
// · kCGImageSourceShouldCacheImmediately
// 是否在创建图片时就进行解码(当然要这么做,避免在渲染时解码占用cpu)并缓存,
/* Specifies whether image decoding and caching should happen at image creation time.
* The value of this key must be a CFBooleanRef. The default value is kCFBooleanFalse (image decoding will
* happen at rendering time). //默认为不缓存,在图片渲染时进行图片解码
*/
CFDictionaryAddValue(mutOption, kCGImageSourceShouldCacheImmediately, kCFBooleanTrue);
// · kCGImageSourceCreateThumbnailWithTransform
//指定是否应根据完整图像的方向和像素纵横比旋转和缩放缩略图
/* Specifies whether the thumbnail should be rotated and scaled according
* to the orientation and pixel aspect ratio of the full image.(默认为false
*/
//要设为true,因为我们要缩小他!
CFDictionaryAddValue(mutOption, kCGImageSourceCreateThumbnailWithTransform, kCFBooleanTrue);
// · kCGImageSourceThumbnailMaxPixelSize
/* Specifies the maximum width and height in pixels of a thumbnail. If
* this this key is not specified, the width and height of a thumbnail is
* not limited and thumbnails may be as big as the image itself. If
* present, this value of this key must be a CFNumberRef. */
//指定缩略图的宽(如果缩略图的高大于宽,那就是高,那个更大填哪个)
//这里我猜测生成的是一个矩形(划重点,我猜的,我猜的,我猜的,请自行论证)
//画丑了,总之下面是两个正方形!
/* 高更大 宽更大
________ _______
| \\\\ | or | |
| \\\\ | |\\\\\\\|
| \\\\ | | |
-------- -------
*/
CFDictionaryAddValue(mutOption, kCGImageSourceThumbnailMaxPixelSize, (__bridge CFNumberRef)maxDimensionNum);
CFDictionaryRef dowsamplingOption = CFDictionaryCreateCopy(NULL, mutOption);
//生成缩略图
CGImage *rf = CGImageSourceCreateThumbnailAtIndex(imageSource, 0, dowsamplingOption);
//用UIImage把他装起来,返回
UIImage *img = [UIImage imageWithCGImage:rf];
return img;
}
网友评论