序言
今天我们来学习学习Instruments之Core Animation之Color Misaligned Images。
官方说明是这样的:Color Misaligned Images: Places a magenta overlay over images where the source pixels are not aligned to the destination pixels.
意思就是当图片的源像素与目标像素不对齐是会放一个洋红色的层在图片上。当图片的像素大小与控件的大小不一致而导致需要缩放时,图片会呈现黄色。
本篇文章是记录笔者学习优化图片显示的笔记,同时希望能够帮助大家进一步学习,当然更希望大家多思考多评论,将自己的想法都在评论中写出来!
Instruments Core Animation界面
我们先来说说Instruments中的选项之一:Core Animation。运行后,默认看到右下角是第一个按钮,勾选上用于设置监测FPS的:
而我们根本每一选项做优化,要看下图,每次只勾选一个,一步步优化:
优化前
根据官方说明,图片像素不对齐(也就是图片带alpha通道)时,会在图片上面加一层洋红色来标识;而图片被缩放时,会加一层黄色来标识。那么先看看我们的demo中被优化前的UI:
笔者通过网上找了一些带alpha通道的png图片,果真被标识为洋红色了。不过奇怪的是,两个一样的图片,为什么显示成正方形的时候,并没有被标识为像素不对齐呢?
笔者尝试修改左上角的头像为长方形,不过并没有用,还是显示为黄色而非洋红色。而且,这设置图片的代码是一样一样的,结果还是没有变化修改成洋红色,这个问题笔者暂时找不到原因。
希望大家知道原因的,可以告知一声,谢谢!
在优化前,我们监测FPS如下:
右边一列是FPS值的变化,我们是在滚动时的FPS,说明不做优化处理,对于滚动的流畅性影响是比较大的。
在优化前的代码是:
1 2 3 4 5 6 7 8 |
NSString *path = nil; if ([model.headImg hasSuffix:@".png"]) { path = model.headImg; } else { path = [[NSBundle mainBundle] pathForResource:model.headImg ofType:nil]; } UIImage *image = [UIImage imageNamed:path]; self.headImageView.image = image; |
对于UICollectionViewCell中显示的图片优化前是这样的:
1 2 3 4 5 6 7 8 9 |
NSString *imgName = self.model.imgs[indexPath.row]; NSString *path = nil; if ([imgName hasSuffix:@".png"]) { path = imgName; } else { path = [[NSBundle mainBundle] pathForResource:imgName ofType:nil]; } UIImage *image = [UIImage imageNamed:path]; imgView.image = image; |
优化后
在优化后,我们通过真机监测FPS在滚动时的变化,可以看到是比较稳定地处于60左右,说明优化的效果是比较明显的:
下面我们采用等比例的方式来生成新的图片并缓存起来,看到优化后的效果:
我们发现洋红色没有了,黄色也没有了。说明我们已经解决掉这个问题了。
等比例缩放
那么我们采用等比例缩放图片的代码如下(给UIImage添加了一个扩展方法):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
// 等比缩放 - (UIImage *)hyb_cropEqualScaleImageToSize:(CGSize)size { CGFloat scale = [UIScreen mainScreen].scale; // 这一行至关重要 // 不要直接使用UIGraphicsBeginImageContext(size);方法 // 因为控件的frame与像素是有倍数关系的 // 比如@1x、@2x、@3x图,因此我们必须要指定scale,否则黄色去不了 // 因为在5以上,scale为2,6plus scale为3,所生成的图是要合苹果的 // 规格才能正常 UIGraphicsBeginImageContextWithOptions(size, NO, scale); CGSize aspectFitSize = CGSizeZero; if (self.size.width != 0 && self.size.height != 0) { CGFloat rateWidth = size.width / self.size.width; CGFloat rateHeight = size.height / self.size.height; CGFloat rate = MIN(rateHeight, rateWidth); aspectFitSize = CGSizeMake(self.size.width * rate, self.size.height * rate); } [self drawInRect:CGRectMake(0, 0, aspectFitSize.width, aspectFitSize.height)]; UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image; } |
直接缩放至指定大小
下图是不按等比例来缩放,而是直接生成指定大小的图,优化后的效果图如下:
而我们生成指定大小的图的代码如下: