1 image的圆角问题
老问题,出现问题的根源在圆角效果可能带来的离屏渲染。
a. 圆角图片。
b. 子线程做圆角裁剪,同理还是圆角图片。
c. 添加一个中空的圆角遮罩层。
d.使用 Core Graphics 重新绘制带圆角的图片。
*d*
CGRect rect = (CGRect){0.f,0.f,size};
UIGraphicsBeginImageContextWithOptions(size, NO, [UIScreen mainScreen].scale);
CGContextAddPath(UIGraphicsGetCurrentContext(), [UIBezierPath bezierPathWithRoundedRect:rect byRoundingCorners:corner cornerRadii:CGSizeMake(radius, radius)].CGPath);
CGContextClip(UIGraphicsGetCurrentContext());
[strongSelf drawInRect:rect];
UIImage *output =UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
2 UIImage加载图片
基本流程:加载-->解码-->绘制。通常加载图片时IOS通常会延迟解码图片。
原生方法中最好使用imageNamed: 方法--加载图片后立即解压,不影响图片的绘制。但是此方法只对于应用中的资源图片有效,对于用户生成或者下载的图片来说是无效的。我们可以考虑绕开UIKit来加载图片。
NSInteger index = indexPath.row
NSURL *imageURL = [NSURL fileURLWithPath:imagePath];
NSDictionary *options = @{(__bridge id)kCGImageSourceShouldCache:YES};
CGImageSourceRef source = CGImageSourceCreateWithURL((__bridge CFURLRef)imageURL,NULL);
CGImageRef imageRef =CGImageSourceCreateImageAtIndex(source,0,(__bridge CFDictionary)options);
UIImage *image = [UIImage imageWithCGImage:imageRef];
CFRelease(source)
3 像素不对齐&image和容器大小不一致
出现像素不对齐的情况,会导致在GPU渲染时,对没对齐的边缘,需要进行插值计算,这个插值计算的过程会有性能损耗。
像素不对齐: 逻辑像素(point)乘以2(2x的视网膜屏) 或3(3x的视网膜屏)得到的物理像素为 整数值,或者说得到的浮点数且小数点后都是0的,这就像素对齐了,否则就是像素不对齐。
逻辑像素(point)与物理像素(pixel):通常我们UI标注和app里面视图大小为逻辑像素。不同机型显示屏1point对应2x或3x的物理像素。图片渲染前会将point换算为pixel。
当图片与图片容器像素大小不一致时同样会造成不必要的损耗。
查找不对齐像素:模拟器中勾选Debug -->Color Misaligned Images选项,当UIView(及其子类)的frame像素不对齐显示洋红色;当图片的像素大小与控件的大小不一致而导致需要缩放时,显示黄色。
1、frame设置时候,使用整数; 需要计算frame时候,计算的结果使用ceil处理一下,避免小数点后有非0数存在。UITableViewCell的高度的高度是整数。
2、项目中,要求UI设计师提供@2x和@3x的切图。
3、设置imageView的size要和切图的size(逻辑像素(point))相等。
4、网络上获取的图片的size要缩放和imageView的size(逻辑像素(point))要相等,缩放后的图片的scale和[UIScreen mainScreen].scale要相等。
5、缩放这样的耗时操作应该放到子线程去做。最好做缓存,避免每次显示都需要缩放操作。
4像素混合
iPhone模拟器中勾选 Debug ->Color Blended Layers选项 可以将像素混合的部分显示出来。发生了像素混合的区域显示红色,正常则显示绿色
像素混合: 是指在某视图为透明背景色,GPU在渲染视图时,需要将该视图和下层视图混合(Blend)后才能计算出该像素点的实际颜色;这增加了GPU的工作,损耗了性能。
5 view设置图片
UIImage *image = [UIImage imageNamed:@"playing"];
view.layer.contents = (__bridge id)image.CGImage;
//设置显示的图片范围(0~1)
view.layer.contentsCenter = CGRectMake(0.25, 0.25, 0.5, 0.5);
网友评论