在UIGraphicsBeginImageContextWithOptions中,CGContextDrawImage忽略UIEdgeInsets。

4
我正在尝试在离屏缓存上绘制图像时使用Image Insets,但遇到了困难。
对于UIImage,直接使用resizableImageWithCapInsets:方法并将其setImage:到按钮中,这种方法对我来说很有效:
UIImage * base = [UIImage imageNamed:@"button.png"];
UIImage * img = [base resizableImageWithCapInsets:UIEdgeInsetsMake(20,20,20,20)];
[self setImage:img forState:UIControlStateNormal];

如下所示(左边是原始缩放,右边是带插图的缩放):

Image stretched without ado Image stretched with decent insets

所以正确的那个是好的 - 上/下/左/右的线条间距相等。目前为止还不错。

现在,如果我尝试使用一张绘制并捕获到离屏缓冲区的图片来做同样的事情:

UIImage * base = [UIImage imageNamed:@"button.png"];
base = [base resizableImageWithCapInsets:UIEdgeInsetsMake(20,20,20,20)];

UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 0);
ctx = UIGraphicsGetCurrentContext();

CGContextDrawImage(ctx, CGRectMake(0,0,self.bounds.size.width,
         self.bounds.size.height), [base CGImage]);

img = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext(); 
[self setImage:img forState:UIControlStateNormal];

我得到了以下结果(左边是原始缩放,右边是带有插图):

raw scaling, side bufferscaling with inset, side buffer (WRONG!).

看起来这里忽略了插图。

有什么建议吗?完整的示例请参见http://people.apache.org/~dirkx/insetSample.zip,关键代码请参见http://pastebin.com/rm8h6YFV

欢迎任何建议。

Dw

1个回答

13
我猜可伸缩的UIImage是在比Quartz2D更高的级别上处理的,所以使用CGContextDrawImage不起作用。您可以尝试使用-[UIImage drawInRect]代替。这将绘制到当前的UIGraphics上下文中,该上下文是您在代码段中创建的位图上下文。相关代码如下:
[base drawInRect:CGRectMake(0,0,self.bounds.size.width,
                                    self.bounds.size.height)];

我刚刚尝试编辑您提供的项目,并进行了此更改,可以解决您的问题。 - Robin Summerhill
谢谢 - 确实非常准确。这个更改后运行得很好(供参考 - http://pastebin.com/FjZkfb9z 是更新的文件/代码)。 - Dirk-Willem van Gulik
实际上,当使用真实图像(类似于视觉混合器上看到的照明按钮)进行此操作时,需要确保旋转正确,因为两个绘图层的Y原点分别在顶部和底部。 - Dirk-Willem van Gulik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接