是drawRect"浪费"什么时候裁剪?还有其他选择吗?

时间:2014-02-26 14:29:18

标签: ios ios7 core-graphics drawrect

假设您有原始图片

200 high, 100 wide

假设您只想绘制一个方格。让我们说,只是底部的方块。

假设您要将其绘制到

的新小图像上
20 high, 20 wide

当然,你只需这样做:

CGRect imageRect = CGRectMake( -10,0, 20,20);
.. begin graphics context ..
[originalImage drawInRect:imageRect];

使用drawRect,您可以提供相同的完整形状(相同比例)原始图像的矩形,但以新画布的大小表示< / strong>即可。没问题。

BUT:

在示例中,您正在将整个原始图像 - 整个200高度绘制到新的小方块上。

(当然“上半部分”错过了新画布,你只能在新画布上得到下半部分 - 这就是你想要的。)

我的印象是iOS 呈现或计算“整个”原始图像,它只会“将”下半部分(在示例中)“放到”新画布上。

这似乎非常浪费。

有更快的方法吗?

似乎应该有一个命令,如下所示:

drawThisPartOfTheOriginalImage: (0,100 to 100,200)
ontoThisPartOfTheNewCanvas: (0,20 to 20,20)

情况如何?当你只是绘制原始图像的一小部分时,是否有比drawRect更有效的命令?干杯


CGContextClipToRect方法......(不起作用!)

我尝试使用CGContextClipToRect,正如Peter在下面所建议的那样。

CGContextClipToRect确实会在“结果”画布上设置绘制到的区域。我只是将它设置为结果画布的大小(在上面的例子中它将是20.20)。重复这里的目标是通过避免无意义地绘制原始的,错误的,未绘制的部分来节省iOS时间。

此示例适用于绘制到500.500的原始图像2000.2000(即,仅将原始图像的左上角四分之一绘制到结果上)。

事实上,当你包含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;
 }

1 个答案:

答案 0 :(得分:4)

这是剪辑进入的地方。剪切到脏的矩形,然后将整个图像绘制到边界。裁剪路径将使图像的其余部分至少不出现,并希望完全合成或采样。

如果您在Instruments中的分析发现效率不够高,您可以尝试使用CGImageCreateWithImageInRect裁剪图像本身,然后将该图像绘制到脏矩形中。您可能希望保留裁剪后的图像,并在矩形更改时将其丢弃。无论如何,裁剪图像可能更有效 - 但不要忘记在之前和之后对其进行分析以证明这一点。