正确使用UIRectClip将UIImage缩小到图标大小

Joe*_*rea 7 iphone icons scale uiimage

鉴于任何尺寸的UIImage,我希望生成一个方形"图标"大小的版本,px像素到一边,没有任何失真(拉伸).但是,我遇到了一些障碍.不太确定问题出在哪里.这是我到目前为止所做的.

首先,给定一个UImage size,我确定了三件事:ratio缩小图像时使用; a delta(我们想要的图标大小和最长边之间的差异)和a offset(用于在剪裁图像时计算出我们的原点坐标):

 if (size.width > size.height) {
   ratio = px / size.width;
   delta = (ratio*size.width - ratio*size.height);
   offset = CGPointMake(delta/2, 0);
 } else {
   ratio = px / size.height;
   delta = (ratio*size.height - ratio*size.width);
   offset = CGPointMake(0, delta/2);
 }
Run Code Online (Sandbox Code Playgroud)

现在,假设您有一个640px宽,480px高的图像,我们希望得到一个50px x 50px图标.宽度大于高度,因此我们的计算是:

ratio = 50px / 640px = 0.078125
delta = (ratio * 640px) - (ratio * 480px) = 50px - 37.5px = 12.5px
offset = {x=6.25, y=0}
Run Code Online (Sandbox Code Playgroud)

接下来,我创建一个CGRect rect,它足够大,可以裁剪到我们想要的图标大小而不会失真,还有一个clipRect用于剪切的目的:

CGRect rect = CGRectMake(0.0, 0.0, (ratio * size.width) + delta,
                                   (ratio * size.height) + delta);
CGRect clipRect = CGRectMake(offset.x, offset.y, px, px);
Run Code Online (Sandbox Code Playgroud)

从上面代替我们的价值观,我们得到:

rect = origin {x=0.0, y=0.0}, size {width=62.5, height=50.0}
clipRect = origin {x=6.25, y=0}, size {width=50.0, height=50.0}
Run Code Online (Sandbox Code Playgroud)

所以现在我们有一个62.5像素宽,50像素高的矩形工作,以及一个抓住"中间"50x50部分的剪切矩形.

到家里伸展!接下来,我们设置我们的图像上下文,将UIImage(myImage在此处称为)绘制到rect中,设置剪切矩形,获取(可能是现在剪裁的)图像,使用它,最后清理我们的图像上下文:

 UIGraphicsBeginImageContext(rect.size);
 [myImage drawInRect:rect]; 
 UIRectClip(clipRect);
 UIImage *icon = UIGraphicsGetImageFromCurrentImageContext();

 // Do something with the icon here ...

 UIGraphicsEndImageContext();
Run Code Online (Sandbox Code Playgroud)

只有一个问题:剪辑永远不会发生!我最终得到了63px宽x50px高的图像.:(

也许我误用/误解了UIRectClip?我试过改变各种各样的东西:交换使用rectclipRect,在drawInRect之前移动UIRectClip : . 没有骰子.

我也尝试在网上搜索这种方法的例子,但无济于事.对于记录,UIRectClip定义为:

通过将当前剪切路径与指定的矩形相交来修改当前剪切路径.

随波逐流的东西让我们更接近:

UIGraphicsBeginImageContext(clipRect.size);
UIRectClip(rect);
[myImage drawInRect:rect];
Run Code Online (Sandbox Code Playgroud)

现在我们没有失真,但是剪切的图像并没有像我预期的那样居中.尽管如此,至少图像是50x50,尽管变量名称现在由于所述改组而被犯规.(我会尊重地将重命名作为读者的练习.)

Joe*_*rea 7

找到了!我把事情搞砸了.这有效:

CGRect clipRect = CGRectMake(-offset.x, -offset.y,
                             (ratio * size.width) + delta,
                             (ratio * size.height) + delta);
UIGraphicsBeginImageContext(CGSizeMake(px, px));
UIRectClip(clipRect);
[myImage drawInRect:clipRect];
UIImage *icon = UIGraphicsGetImageFromCurrentImageContext();

// Do something with the icon here ...

UIGraphicsEndImageContext();
Run Code Online (Sandbox Code Playgroud)

不再需要了rect.诀窍似乎是在剪切矩形中使用偏移,从而排列我们想要抓住50 x 50图像的原点(在此示例中).

也许有一种更简单的方法.如果是这样,请称重!