ios 用纵横比调整 UIImage 的大小?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1703100/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Resize UIImage with aspect ratio?
提问by Cory Imdieke
I'm using this code to resize an image on the iPhone:
我正在使用此代码调整 iPhone 上的图像大小:
CGRect screenRect = CGRectMake(0, 0, 320.0, 480.0);
UIGraphicsBeginImageContext(screenRect.size);
[value drawInRect:screenRect blendMode:kCGBlendModePlusDarker alpha:1];
UIImage *tmpValue = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Which is working great, as long as the aspect ratio of the image matches that of the new resized image. I'd like to modify this so that it keeps the correct aspect ratio and just puts a black background anywhere the image doesn't show up. So I would still end up with a 320x480 image but with black on the top and bottom or sides, depending on the original image size.
只要图像的纵横比与调整后的新图像的纵横比相匹配,这很好用。我想修改它以保持正确的纵横比,并在图像不显示的任何地方放置黑色背景。所以我仍然会得到一个 320x480 的图像,但顶部和底部或侧面是黑色的,这取决于原始图像的大小。
Is there an easy way to do this similar to what I'm doing? Thanks!
有没有一种简单的方法来做到这一点,类似于我正在做的事情?谢谢!
回答by Frank Schmitt
After you set your screen rect, do something like the following to decide what rect to draw the image in:
设置屏幕矩形后,请执行以下操作以决定在哪个矩形中绘制图像:
float hfactor = value.bounds.size.width / screenRect.size.width;
float vfactor = value.bounds.size.height / screenRect.size.height;
float factor = fmax(hfactor, vfactor);
// Divide the size by the greater of the vertical or horizontal shrinkage factor
float newWidth = value.bounds.size.width / factor;
float newHeight = value.bounds.size.height / factor;
// Then figure out if you need to offset it to center vertically or horizontally
float leftOffset = (screenRect.size.width - newWidth) / 2;
float topOffset = (screenRect.size.height - newHeight) / 2;
CGRect newRect = CGRectMake(leftOffset, topOffset, newWidth, newHeight);
If you don't want to enlarge images smaller than the screenRect, make sure factor
is greater than or equal to one (e.g. factor = fmax(factor, 1)
).
如果您不想放大小于 screenRect 的图像,请确保factor
大于或等于 1(例如factor = fmax(factor, 1)
)。
To get the black background, you would probably just want to set the context color to black and call fillRect before drawing the image.
要获得黑色背景,您可能只想将上下文颜色设置为黑色并在绘制图像之前调用 fillRect。
回答by Victor Thomas Wilcox Jr.
I know this is very old, but thanks for that post -- it redirected me from attempting to use scale to drawing the image. In case it is of benefit to anyone, I made an extension class I'll throw in here. It allows you to resize an image like this:
我知道这已经很老了,但感谢那篇文章——它让我不再尝试使用比例来绘制图像。万一它对任何人都有好处,我做了一个扩展类,我会在这里投入。它允许您像这样调整图像大小:
UIImage imgNew = img.Fit(40.0f, 40.0f);
I don't need a fit option, but it could easily be extended to support Fill as well.
我不需要 fit 选项,但它也可以轻松扩展以支持 Fill。
using CoreGraphics;
using System;
using UIKit;
namespace SomeApp.iOS.Extensions
{
public static class UIImageExtensions
{
public static CGSize Fit(this CGSize sizeImage,
CGSize sizeTarget)
{
CGSize ret;
float fw;
float fh;
float f;
fw = (float) (sizeTarget.Width / sizeImage.Width);
fh = (float) (sizeTarget.Height / sizeImage.Height);
f = Math.Min(fw, fh);
ret = new CGSize
{
Width = sizeImage.Width * f,
Height = sizeImage.Height * f
};
return ret;
}
public static UIImage Fit(this UIImage image,
float width,
float height,
bool opaque = false,
float scale = 1.0f)
{
UIImage ret;
ret = image.Fit(new CGSize(width, height),
opaque,
scale);
return ret;
}
public static UIImage Fit(this UIImage image,
CGSize sizeTarget,
bool opaque = false,
float scale = 1.0f)
{
CGSize sizeNewImage;
CGSize size;
UIImage ret;
size = image.Size;
sizeNewImage = size.Fit(sizeTarget);
UIGraphics.BeginImageContextWithOptions(sizeNewImage,
opaque,
1.0f);
using (CGContext context = UIGraphics.GetCurrentContext())
{
context.ScaleCTM(1, -1);
context.TranslateCTM(0, -sizeNewImage.Height);
context.DrawImage(new CGRect(CGPoint.Empty, sizeNewImage),
image.CGImage);
ret = UIGraphics.GetImageFromCurrentImageContext();
}
UIGraphics.EndImageContext();
return ret;
}
}
}
As per the post above, it starts a new context for an image, then for that image it figures out aspect and then paints into the image. If you haven't done any Swift xcode dev time, UIGraphics is a bit backwards to most systems I work with but not bad. One issue is that bitmaps by default paint bottom to top. To get around that,
根据上面的帖子,它为图像启动一个新的上下文,然后为该图像计算出外观,然后绘制到图像中。如果你没有做过任何 Swift xcode 开发时间,UIGraphics 对我使用的大多数系统来说有点落后,但还不错。一个问题是默认情况下位图从底部到顶部绘制。为了解决这个问题,
context.ScaleCTM(1, -1);
context.TranslateCTM(0, -sizeNewImage.Height);
Changes the orientation of drawing to the more common top-left to bottom-right... but then you need to move the origin as well hence the TranslateCTM.
将绘图的方向更改为更常见的左上角到右下角……但是您还需要移动原点,因此需要移动 TranslateCTM。
Hopefully, it saves someone some time.
希望它可以为某人节省一些时间。
Cheers
干杯