正确使用UIRectClip将UIImage缩放到图标大小 [英] Proper use of UIRectClip to scale a UIImage down to icon size
问题描述
鉴于任何维度的 UIImage ,我希望生成一个正方形图标大小的版本, px
像素到一边,没有任何扭曲(拉伸)。但是,我遇到了一些障碍。不太确定问题出在哪里。以下是我到目前为止所做的事情。
Given a UIImage of any dimension, I wish to generate a square "icon" sized version, px
pixels to a side, without any distortion (stretching). However, I'm running into a little snag. Not quite sure where the problem is. Here's what I'm doing so far.
首先,给定 UImage 尺寸
,我确定缩小图像时要使用的三件事:比率
; a delta
(我们所需图标大小与最长边之间的差异)和偏移量
(用于在裁剪图像时弄清楚我们的原点坐标):
First, given a UImage size
, I determine three things: the ratio
to use when scaling down the image; a delta
(the difference between our desired icon size and the longest side), and an offset
(which is used to figure out our origin coordinate when clipping the image):
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);
}
现在,假设您的图像宽640像素×高480像素,我们想要获得50px x 50px的图标。宽度大于高度,因此我们的计算结果是:
Now, let's say you have an image 640px wide by 480px high, and we want to get a 50px x 50px icon out of this. The width is greater than the height, so our calculations are:
ratio = 50px / 640px = 0.078125
delta = (ratio * 640px) - (ratio * 480px) = 50px - 37.5px = 12.5px
offset = {x=6.25, y=0}
接下来,我创建一个 CGRect rect
,它足够大,可以裁剪到我们的所需的图标大小没有失真,加上 clipRect
用于剪辑目的:
Next, I create a CGRect rect
that is large enough to be cropped down to our desired icon size without distortion, plus a clipRect
for clipping purposes:
CGRect rect = CGRectMake(0.0, 0.0, (ratio * size.width) + delta,
(ratio * size.height) + delta);
CGRect clipRect = CGRectMake(offset.x, offset.y, px, px);
从上面代替我们的价值,我们得到:
Substituting our values from above, we get:
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}
所以现在我们的宽度为62.5px使用50px高矩形,以及抓住中间50x50部分的剪切矩形。
So now we have a 62.5px wide by 50px high rect to work with, and a clipping rectangle that grabs the "middle" 50x50 portion.
进入主页!接下来,我们设置我们的图像上下文,将 UIImage (在此处称为 myImage
)绘制到rect中,设置剪切矩形,得到(推测)现在剪裁)图像,使用它,最后清理我们的图像上下文:
On to the home stretch! Next, we set up our image context, draw the UIImage (called myImage
here) into the rect, set the clipping rectangle, get the (presumably now-clipped) image, use it, and finally clean up our image context:
UIGraphicsBeginImageContext(rect.size);
[myImage drawInRect:rect];
UIRectClip(clipRect);
UIImage *icon = UIGraphicsGetImageFromCurrentImageContext();
// Do something with the icon here ...
UIGraphicsEndImageContext();
只有一个问题:剪辑永远不会发生!我最终得到了63px宽x50px高的图像。 :(
Only one problem: The clipping never occurs! I end up with an image 63px wide x 50px high. :(
也许我在滥用/误解 UIRectClip ?我试过了改变各种各样的东西:交换使用 rect
和 clipRect
,在之前移动 UIRectClip strong> drawInRect:。没有骰子。
Perhaps I'm misusing/misunderstanding UIRectClip? I've tried shuffling various things around: swapping the use of rect
and clipRect
, moving UIRectClip before drawInRect:. No dice.
我尝试在线搜索此方法的示例,但无济于事。为了记录, UIRectClip 定义为:
I tried searching for an example of this method online as well, to no avail. For the record, UIRectClip is defined as:
修改当前剪切路径
与指定的$ b $相交b矩形。
Modifies the current clipping path by intersecting it with the specified rectangle.
随身携带的东西让我们更接近:
Shuffling things around gets us a little bit closer:
UIGraphicsBeginImageContext(clipRect.size);
UIRectClip(rect);
[myImage drawInRect:rect];
现在我们没有失真,但剪裁的图像并没有像我预期的那样居中于原始图像。但是,至少图像是50x50,尽管变量名称由于洗牌,现在重新犯规了。 (我会尊重地将重命名作为读者的练习。)
Now we don't have distortion, but the clipped image isn't centered on the original as I expected. Still, at least the image is 50x50, though the variable names are now fouled up as a result of said shuffling. (I'll respectfully leave renaming as an exercise for the reader.)
推荐答案
尤里卡!我把事情搞砸了。这有效:
Eureka! I had things a little mixed up. This works:
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();
不再需要 rect
。诀窍似乎是在裁剪矩形中使用负偏移,从而排列我们想要抓住50 x 50图像的原点(在此示例中)。
No more need for rect
. The trick appears to be using a negative offset in the clipping rectangle, thereby lining up the origin of where we want to grab our 50 x 50 image (in this example).
也许有一种更简单的方法。如果是这样,请称重!
Perhaps there's an easier way. If so, please weigh in!
这篇关于正确使用UIRectClip将UIImage缩放到图标大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!