【发布时间】:2014-02-26 14:29:17
【问题描述】:
假设您有一张原始图片
200 high, 100 wide
假设您只想绘制它的一个正方形。比方说,只是底部的正方形。
假设你想将它绘制到一个新的小图像上
20 high, 20 wide
当然,您只需这样做:
CGRect imageRect = CGRectMake( -10,0, 20,20);
.. begin graphics context ..
[originalImage drawInRect:imageRect];
使用drawRect,您可以提供一个与原始图像相同的完整形状(相同比例)的矩形,但以新画布的大小。没问题。
但是:
在示例中,您将 整个原始图像 -- 整个 200 高度 绘制到新的小正方形上。
(当然,“上半部分”错过了新画布,而您只能在新画布上获得下半部分——这正是您想要的。)
我的印象是 iOS 渲染或计算“整个”原始图像,它只将下半部分(在示例中)“放到”新画布上。
这看起来很浪费。
有更快的方法吗?
好像应该有一个命令,是这样的:
drawThisPartOfTheOriginalImage: (0,100 to 100,200)
ontoThisPartOfTheNewCanvas: (0,20 to 20,20)
什么情况?当您只绘制原始图像的一小部分时,有没有比 drawRect 更有效的命令?干杯
CGContextClipToRect 方法...(不起作用!)
.
我按照 Peter 下面的建议尝试了 CGContextClipToRect。
CGContextClipToRect 确实在“结果”画布上设置了您将绘制到的区域。我只是将其设置为结果画布的大小(在上面的示例中为 20.20)。重复这里的目标是通过避免毫无意义地绘制原始的、错误的、未绘制的部分来让 iOS 节省时间。
此示例用于将原始图像 2000.2000 绘制到 500.500(即,仅将原始图像的左上四分之一绘制到结果上)。
实际上请注意,当您包含 CGContextClipToRect 时它会稍微慢一些,这再次表明 iOS“知道何时停止”。
// no need to "overdraw"... quickener turned OFF
//CGContextRef c = UIGraphicsGetCurrentContext();
//CGContextClipToRect(c, CGRectMake(0, 0, resultSize.width,resultSize.height));
//Execution Time .................................. 0.443669
// no need to "overdraw"... quickener turned ON
CGContextRef c = UIGraphicsGetCurrentContext();
CGContextClipToRect(c, CGRectMake(0, 0, resultSize.width,resultSize.height));
//Execution Time .................................. 0.461845
正如您所见,实际上,添加 CGContextClipToRect 技巧会慢一点。
为了记录,这里是用于裁剪图像的确切例程:
-(UIImage *)simplishTopCrop:(UIImage *)fromImage
{
// check for zero fromImage.size.width etc etc
CGSize resultSize = CGSizeMake(640,640);
CGFloat scale = MAX(
resultSize.width/fromImage.size.width,
resultSize.height/fromImage.size.height);
CGFloat width = fromImage.size.width * scale;
CGFloat height = fromImage.size.height * scale;
CGRect imageRect = CGRectMake(0,0, width,height);
UIGraphicsBeginImageContextWithOptions(resultSize, NO, 0);
// INSERT 'CGContextClipToRect' TRICK ABOVE, RIGHT HERE
[fromImage drawInRect:imageRect];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
【问题讨论】:
-
相差约 20 毫秒?您是否多次运行测试? 20 毫秒可能在正常误差范围内。
-
嗨,彼得,当然,我们对它进行了非常、非常、非常广泛的试验。烦人的是,没有时间节省。正如我所说,平均而言,它实际上比简单地省略两行 CGContextClipToRect 代码慢一点(你没有注意到)。我的猜测是,在内部,iOS“知道”无论如何都不会“过度扫描”,所以(显然)非常可悲的是,调用 CGContextClipToRect 完全没有意义。
标签: ios ios7 core-graphics drawrect