ChatGPT解决这个技术问题 Extra ChatGPT

调整 UIImage 大小的最简单方法?

在我的 iPhone 应用程序中,我用相机拍照,然后我想将其调整为 290*390 像素。我正在使用这种方法来调整图像的大小:

UIImage *newImage = [image _imageScaledToSize:CGSizeMake(290, 390)
                         interpolationQuality:1];    

它工作得很好,但它是一个未记录的功能,所以我不能再在 iPhone OS4 上使用它。

那么......调整 UIImage 大小的最简单方法是什么?

2019 年的做法,nshipster.com/image-resizing

P
Paul Lynch

最简单的方法是设置 UIImageView 的框架并将 contentMode 设置为调整大小选项之一。

或者,如果您确实需要调整图像大小,可以使用此实用程序方法:

+ (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize {
    //UIGraphicsBeginImageContext(newSize);
    // In next line, pass 0.0 to use the current device's pixel scaling factor (and thus account for Retina resolution).
    // Pass 1.0 to force exact pixel size.
    UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
    [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();    
    UIGraphicsEndImageContext();
    return newImage;
}

示例用法:

#import "MYUtil.h"
…
UIImage *myIcon = [MYUtil imageWithImage:myUIImageInstance scaledToSize:CGSizeMake(20, 20)];

我不会在这里保留结果。 newImage 已经被自动释放,它应该由调用它的方法决定是否保留它。这种方法只是在乞求内存错误,因为 init 不是方法名称的一部分。我希望像这样命名的方法返回一个自动释放的对象。
有效点,并已编辑。我只是提醒我使用它的代码会在其他地方产生 malloc 错误而没有额外的保留,这在某种程度上显然是我的错:-)。
As of iOS 4.0,UIGraphics* 函数都是线程安全的。
@Paul Lynch:请记住,此更改破坏了原始帖子的使命:如何将图像大小调整为某个精确的像素大小(而不是点大小)。
对于那些由于@NikolaiRuhe 指出的限制而苦苦挣扎的人,您可以通过在对 UIGraphicsBeginImageContextWithOptions 的调用中传递 1.0 而不是 0.0 来强制其精确到像素大小
p
pierre23

iOS 10+ 的正确 Swift 3.0 解决方案:使用 ImageRenderer 和闭包语法:

func imageWith(newSize: CGSize) -> UIImage {
    let image = UIGraphicsImageRenderer(size: newSize).image { _ in
        draw(in: CGRect(origin: .zero, size: newSize))
    }
        
    return image.withRenderingMode(renderingMode)
}

这是 Objective-C 版本:

@implementation UIImage (ResizeCategory)
- (UIImage *)imageWithSize:(CGSize)newSize
{
    UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithSize:newSize];
    UIImage *image = [renderer imageWithActions:^(UIGraphicsImageRendererContext*_Nonnull myContext) {
        [self drawInRect:(CGRect) {.origin = CGPointZero, .size = newSize}];
    }];
    return [image imageWithRenderingMode:self.renderingMode];
}
@end

非常优雅的解决方案,这应该是公认的答案!
这比优雅要好,这是正确的。 Apple 的 api 文档建议新代码像此代码一样使用 UIGraphicsRenderer。谢谢
@appsunited 这个问题已经快 8 年了。而且这种方法只适用于iOS10+,如上所述。
将新图像对象复制到剪贴板时,它会为我生成一个白色块。它实际上并没有调整图像视图的大小?
此函数返回 0 高度和 0 宽度的图像,期望高度为 9000 高度和 9000 宽度。
K
Ky.

这是 Paul Lynch's answer 的 Swift 版本

func imageWithImage(image:UIImage, scaledToSize newSize:CGSize) -> UIImage{
    UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0);
    image.drawInRect(CGRectMake(0, 0, newSize.width, newSize.height))
    let newImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return newImage
}

作为扩展:

public extension UIImage {
    func copy(newSize: CGSize, retina: Bool = true) -> UIImage? {
        // In next line, pass 0 to use the current device's pixel scaling factor (and thus account for Retina resolution).
        // Pass 1 to force exact pixel size.
        UIGraphicsBeginImageContextWithOptions(
            /* size: */ newSize,
            /* opaque: */ false,
            /* scale: */ retina ? 0 : 1
        )
        defer { UIGraphicsEndImageContext() }

        self.draw(in: CGRect(origin: .zero, size: newSize))
        return UIGraphicsGetImageFromCurrentImageContext()
    }
}

刚刚注意到,在 iOS 中,您的 newSize 将根据设备增加 2 倍、3 倍
UIGraphicsBeginImageContextWithOptions(newSize, false, image.scale);适用于所有设备
请注意,这不会调整底层 CGImage 的大小(至少在 iOS 12.1 中)。根据问题可以,但是如果您要写出图像,则必须使用 cgImage,并且您将获得原始图像。
仅适用于 scaleToFill 的比例
n
neave

更紧凑的 Swift 4 和 iOS 10+ 版本:

extension UIImage {
    func resized(to size: CGSize) -> UIImage {
        return UIGraphicsImageRenderer(size: size).image { _ in
            draw(in: CGRect(origin: .zero, size: size))
        }
    }
}

用法:

let resizedImage = image.resized(to: CGSize(width: 50, height: 50))

C
Community

用于 Stretch Fill、Aspect Fill 和 Aspect Fit 的快速解决方案

extension UIImage {
    enum ContentMode {
        case contentFill
        case contentAspectFill
        case contentAspectFit
    }
    
    func resize(withSize size: CGSize, contentMode: ContentMode = .contentAspectFill) -> UIImage? {
        let aspectWidth = size.width / self.size.width
        let aspectHeight = size.height / self.size.height
        
        switch contentMode {
        case .contentFill:
            return resize(withSize: size)
        case .contentAspectFit:
            let aspectRatio = min(aspectWidth, aspectHeight)
            return resize(withSize: CGSize(width: self.size.width * aspectRatio, height: self.size.height * aspectRatio))
        case .contentAspectFill:
            let aspectRatio = max(aspectWidth, aspectHeight)
            return resize(withSize: CGSize(width: self.size.width * aspectRatio, height: self.size.height * aspectRatio))
        }
    }
    
    private func resize(withSize size: CGSize) -> UIImage? {
        UIGraphicsBeginImageContextWithOptions(size, false, self.scale)
        defer { UIGraphicsEndImageContext() }
        draw(in: CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height))
        return UIGraphicsGetImageFromCurrentImageContext()
    }
}

并使用您可以执行以下操作:

let image = UIImage(named: "image.png")!
let newImage = image.resize(withSize: CGSize(width: 200, height: 150), contentMode: .contentAspectFill)

感谢 abdullahselek 的原始解决方案。


T
TechZen

Trevor Howard 有一些 UIImage categories 可以很好地处理调整大小。如果不出意外,您可以使用代码作为示例。

注意:从 iOS 5.1 开始,这个答案可能无效。请参阅下面的评论。


我也需要调整一些图像的大小,我首先尝试了 Trevor 对 UIImage 的添加,但在 PNG 上遇到了一些奇怪的错误(关于 alpha 通道的东西)。不过,这个问题的公认答案效果很好。
这不再有效(至少对于 iOS5.1
@Jann,看看帖子下面的提交。
@Jann 如果您遵循评论中建议的修复,请使用“Matt 说:2011 年 11 月 22 日下午 5:39”,因为他发布了 colorspaceref(与 horseshoe7 的类似解决方案不同)。
@sanmai 使用这些调整大小方法中的任何一种都会使图像失去清晰度。有什么办法可以达到锐度
R
Rishil Patel

我也看到了这一点(我在 UIButtons 上将其用于 Normal 和 Selected 状态,因为按钮 resize 不适合)。归功于原作者。

首先创建一个名为 UIImageResizing.hUIImageResizing.m 的空 .h 和 .m 文件

// Put this in UIImageResizing.h
@interface UIImage (Resize)
- (UIImage*)scaleToSize:(CGSize)size;
@end

// Put this in UIImageResizing.m
@implementation UIImage (Resize)

- (UIImage*)scaleToSize:(CGSize)size {
UIGraphicsBeginImageContext(size);

CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context, 0.0, size.height);
CGContextScaleCTM(context, 1.0, -1.0);

CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, size.width, size.height), self.CGImage);

UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

return scaledImage;
}

@end

将该 .h 文件包含在您要使用该函数的任何 .m 文件中,然后像这样调用它:

UIImage* image = [UIImage imageNamed:@"largeImage.png"];
UIImage* smallImage = [image scaleToSize:CGSizeMake(100.0f,100.0f)];

这不会复制图像方向。
m
malhal

对 Paul 代码的这种改进将在配备视网膜显示屏的 iPhone 上为您提供清晰的高分辨率图像。否则缩小时会很模糊。

+ (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize {
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
    if ([[UIScreen mainScreen] scale] == 2.0) {
        UIGraphicsBeginImageContextWithOptions(newSize, YES, 2.0);
    } else {
        UIGraphicsBeginImageContext(newSize);
    }
} else {
    UIGraphicsBeginImageContext(newSize);
}
[image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();    
UIGraphicsEndImageContext();
return newImage;
}

仅供参考,您所做的更改是不必要的,因为为 UIGraphicsBeginImageContextWithOptions 中的比例提供 0.0 值将自动使用主屏幕的比例(从 iOS 3.2 开始)。
a
asmad

这是一个简单的方法:

    UIImage * image = [UIImage imageNamed:@"image"];
    CGSize sacleSize = CGSizeMake(10, 10);
    UIGraphicsBeginImageContextWithOptions(sacleSize, NO, 0.0);
    [image drawInRect:CGRectMake(0, 0, sacleSize.width, sacleSize.height)];
    UIImage * resizedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

resizedImage 是一个新图像。


S
Scott Means

这里是上面 iWasRobbed 写的类别的修改。它保持原始图像的纵横比而不是扭曲它。

- (UIImage*)scaleToSizeKeepAspect:(CGSize)size {
    UIGraphicsBeginImageContext(size);

    CGFloat ws = size.width/self.size.width;
    CGFloat hs = size.height/self.size.height;

    if (ws > hs) {
        ws = hs/ws;
        hs = 1.0;
    } else {
        hs = ws/hs;
        ws = 1.0;
    }

    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextTranslateCTM(context, 0.0, size.height);
    CGContextScaleCTM(context, 1.0, -1.0);

    CGContextDrawImage(context, CGRectMake(size.width/2-(size.width*ws)/2,
        size.height/2-(size.height*hs)/2, size.width*ws,
        size.height*hs), self.CGImage);

    UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    return scaledImage;
}

s
sanmai

如果您只是想要一个更小的图像并且不关心确切的大小:

+ (UIImage *)imageWithImage:(UIImage *)image scaledToScale:(CGFloat)scale
{
    UIGraphicsBeginImageContextWithOptions(self.size, YES, scale);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
    [self drawInRect:CGRectMake(0, 0, self.size.width, self.size.height)];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;
}

将比例设置为 0.25f 将为您提供来自 8MP 相机的 816 x 612 图像。

这是为需要的人准备的a category UIImage+Scale


E
Eddie Deng

为什么这么复杂?我认为使用系统 API 可以达到相同的效果:

UIImage *largeImage;
CGFloat ratio = 0.4; // you want to get a new image that is 40% the size of large image.
UIImage *newImage = [UIImage imageWithCGImage:largeImage.CGImage
                                        scale:1/ratio
                                  orientation:largeImage.imageOrientation];
// notice the second argument, it is 1/ratio, not ratio.

唯一的问题是您应该将目标比率的倒数作为第二个参数传递,因为根据文档,第二个参数指定原始图像与新缩放图像的比率。


因为比例(%)与像素(w / h)不同。
比例应该是 largeImage.scale/ratio 而不是 1/ratio。
你拯救了我的一天。
V
Vadoff

对于斯威夫特 5:

extension UIImage {
  func resized(to newSize: CGSize) -> UIImage? {
    UIGraphicsBeginImageContextWithOptions(newSize, false, 0)
    defer { UIGraphicsEndImageContext() }

    draw(in: CGRect(origin: .zero, size: newSize))
    return UIGraphicsGetImageFromCurrentImageContext()
  }
}

a
abdullahselek

这是一个与 Swift 3 和 Swift 4 兼容的 UIImage 扩展,它可以将图像缩放到具有纵横比的给定大小

extension UIImage {

    func scaledImage(withSize size: CGSize) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
        defer { UIGraphicsEndImageContext() }
        draw(in: CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height))
        return UIGraphicsGetImageFromCurrentImageContext()!
    }

    func scaleImageToFitSize(size: CGSize) -> UIImage {
        let aspect = self.size.width / self.size.height
        if size.width / aspect <= size.height {
            return scaledImage(withSize: CGSize(width: size.width, height: size.width / aspect))
        } else {
            return scaledImage(withSize: CGSize(width: size.height * aspect, height: size.height))
        }
    }

}

示例用法

let image = UIImage(named: "apple")
let scaledImage = image.scaleImageToFitSize(size: CGSize(width: 45.0, height: 45.0))

我建议将函数命名为 scaledImage(with size:)scaledWithSize(_:)。此外,UIGraphicsGetImageFromCurrentImageContext 不能真正返回 nil,因此 ! 也可以。您还可以将矩形创建简化为 CGRect(origin: .zero, size: size)
a
aubykhan

我在 Apple 自己的示例中找到了 UIImage 的类别,该类别具有相同的作用。这是链接:https://developer.apple.com/library/ios/samplecode/sc2273/Listings/AirDropSample_UIImage_Resize_m.html

您只需要更改呼叫:

UIGraphicsBeginImageContextWithOptions(newSize, YES, 2.0);

imageWithImage:scaledToSize:inRect: 中:

UIGraphicsBeginImageContextWithOptions(newSize, NO, 2.0);

为了考虑图像中的alpha通道。


M
Martin Zikmund

对于我的 Xamarian 同胞,这是 @Paul Lynch 答案的 Xamarin.iOS C# 版本。

private UIImage ResizeImage(UIImage image, CGSize newSize) 
{
    UIGraphics.BeginImageContextWithOptions(newSize, false, 0.0f);
    image.Draw(new CGRect(0, 0, newSize.Width, newSize.Height));
    UIImage newImage = UIGraphics.GetImageFromCurrentImageContext();
    UIGraphics.EndImageContext();
    return newImage;
}

a
ashwini
 func resizeImage(image: UIImage, newWidth: CGFloat) -> UIImage 
{
        let scale = newWidth / image.size.width
        let newHeight = image.size.height * scale
        UIGraphicsBeginImageContext(CGSizeMake(newWidth, newHeight))
        image.drawInRect(CGRectMake(0, 0, newWidth, newHeight))
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return newImage
}

添加一些描述性文本以配合您的代码是一个好主意。
V
Vlad Andersen

如果您想制作 UIImage 的缩略图(按比例调整大小或可能涉及一些裁剪),请查看允许您使用简洁、类似 ImageMagick 的语法的 UIImage+Resize 类别:

UIImage* squareImage       = [image resizedImageByMagick: @"320x320#"];

t
tiritea

[cf Chris] 调整到所需大小:

UIImage *after = [UIImage imageWithCGImage:before.CGImage
                                     scale:CGImageGetHeight(before.CGImage)/DESIREDHEIGHT
                               orientation:UIImageOrientationUp];

或者,等效地,替换 CGImageGetWidth(...)/DESIREDWIDTH


请注意,图像数据本身没有调整大小,但应用了比例因子,这意味着图像在内存中的大小相同。
C
Community

Rogerio Chaves 作为快速扩展回答

func scaledTo(size: CGSize) -> UIImage{
    UIGraphicsBeginImageContextWithOptions(size, false, 0.0);
    self.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
    let newImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()!
    UIGraphicsEndImageContext()
    return newImage
}

还有奖金

func scaledTo(height: CGFloat) -> UIImage{
    let width = height*self.size.width/self.size.height
    return scaledTo(size: CGSize(width: width, height: height))
}

r
rowel

带有故障保护选项的 Swift 3.0(在出现错误时返回原始图像):

func resize(image: UIImage, toSize size: CGSize) -> UIImage{
    UIGraphicsBeginImageContextWithOptions(size,false,1.0)
    image.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
    if let resizedImage = UIGraphicsGetImageFromCurrentImageContext() {
        UIGraphicsEndImageContext()
        return resizedImage
    }
    UIGraphicsEndImageContext()
    return image
}

n
nathan

(兼容 Swift 4)iOS 10+ 和 iOS < 10 解决方案(如果可能,使用 UIGraphicsImageRenderer,否则使用 UIGraphicsGetImageFromCurrentImageContext

/// Resizes an image
///
/// - Parameter newSize: New size
/// - Returns: Resized image
func scaled(to newSize: CGSize) -> UIImage {
    let rect = CGRect(origin: .zero, size: newSize)

    if #available(iOS 10, *) {
        let renderer = UIGraphicsImageRenderer(size: newSize)
        return renderer.image { _ in
            self.draw(in: rect)
        }
    } else {
        UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0)
        self.draw(in: rect)
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return newImage!
    }
}

M
Mobile Team iOS-RN

无需拉伸图像的有效方法Swift 4

// Method to resize image
func resize(image: UIImage, toScaleSize:CGSize) -> UIImage {
                UIGraphicsBeginImageContextWithOptions(toScaleSize, true, image.scale)
                        image.draw(in: CGRect(x: 0, y: 0, width: toScaleSize.width, height: toScaleSize.height))
                        let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
                        UIGraphicsEndImageContext()
                        return scaledImage!
                }

// 调用方法

    let resizedImage = self.resize(image: UIImage(named: "YourImageName")!, toScaleSize: CGSize(width: 290, height: 390))

E
Ely

使用 iOS 15 或更新版本时,可以使用 UIImage 的新 prepareThumbnail 方法:

sourceImage.prepareThumbnail(of: thumbnailSize) { thumbnail in
    // Do something with the resized image
    DispatchQueue.main.async {
        cell.imageView?.image = thumbnail
    }
}

更多信息:https://developer.apple.com/documentation/uikit/uiimage/3750845-preparethumbnail


如果该方法考虑了屏幕比例值,您知道@Ely 吗?
@BlazejSLEBODA 不,它不会将缩略图大小参数值乘以 UIScreen.main.scale,您必须自己做。
w
wossoneri

@Paul Lynch 的回答很棒,但它会改变图像比例。如果您不想更改图像比例,但仍希望新图像适合新尺寸,请尝试此操作。

+ (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize {

// calculate a new size which ratio is same to original image
CGFloat ratioW = image.size.width / newSize.width;
CGFloat ratioH = image.size.height / newSize.height;

CGFloat ratio = image.size.width / image.size.height;

CGSize showSize = CGSizeZero;
if (ratioW > 1 && ratioH > 1) { 

    if (ratioW > ratioH) { 
        showSize.width = newSize.width;
        showSize.height = showSize.width / ratio;
    } else {
        showSize.height = newSize.height;
        showSize.width = showSize.height * ratio;
    }

} else if (ratioW > 1) {

    showSize.width = showSize.width;
    showSize.height = showSize.width / ratio;

} else if (ratioH > 1) {

    showSize.height = showSize.height;
    showSize.width = showSize.height * ratio;

}

//UIGraphicsBeginImageContext(newSize);
// In next line, pass 0.0 to use the current device's pixel scaling factor (and thus account for Retina resolution).
// Pass 1.0 to force exact pixel size.
UIGraphicsBeginImageContextWithOptions(showSize, NO, 0.0);
[image drawInRect:CGRectMake(0, 0, showSize.width, showSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;}

M
M.Othman

使用这个扩展

extension UIImage {
    public func resize(size:CGSize, completionHandler:(resizedImage:UIImage, data:NSData?)->()) {
        dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), { () -> Void in
            let newSize:CGSize = size
            let rect = CGRectMake(0, 0, newSize.width, newSize.height)
            UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0)
            self.drawInRect(rect)
            let newImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            let imageData = UIImageJPEGRepresentation(newImage, 0.5)
            dispatch_async(dispatch_get_main_queue(), { () -> Void in
                completionHandler(resizedImage: newImage, data:imageData)
            })
        })
    }
}

S
Sergio

调整 UIImage 大小的另一种方法:

// Resize to height = 100 points.
let originalImage = UIImage(named: "MyOriginalImage")!
let resizingFactor = 100 / originalImage.size.height
let newImage = UIImage(cgImage: originalImage.cgImage!, scale: originalImage.scale / resizingFactor, orientation: .up)

P
Phil

斯威夫特 2.0:

let image = UIImage(named: "imageName")
let newSize = CGSize(width: 10, height: 10)

UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0)
image?.drawInRect(CGRectMake(0, 0, newSize.width, newSize.height))
let imageResized = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

D
Dan Rosenstark

这是我有点冗长的 Swift 代码

func scaleImage(image:UIImage,  toSize:CGSize) -> UIImage {
    UIGraphicsBeginImageContextWithOptions(toSize, false, 0.0);

    let aspectRatioAwareSize = self.aspectRatioAwareSize(image.size, boxSize: toSize, useLetterBox: false)


    let leftMargin = (toSize.width - aspectRatioAwareSize.width) * 0.5
    let topMargin = (toSize.height - aspectRatioAwareSize.height) * 0.5


    image.drawInRect(CGRectMake(leftMargin, topMargin, aspectRatioAwareSize.width , aspectRatioAwareSize.height))
    let retVal = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return retVal
}

func aspectRatioAwareSize(imageSize: CGSize, boxSize: CGSize, useLetterBox: Bool) -> CGSize {
    // aspect ratio aware size
    // http://stackoverflow.com/a/6565988/8047
    let imageWidth = imageSize.width
    let imageHeight = imageSize.height
    let containerWidth = boxSize.width
    let containerHeight = boxSize.height

    let imageAspectRatio = imageWidth/imageHeight
    let containerAspectRatio = containerWidth/containerHeight

    let retVal : CGSize
    // use the else at your own risk: it seems to work, but I don't know 
    // the math
    if (useLetterBox) {
        retVal = containerAspectRatio > imageAspectRatio ? CGSizeMake(imageWidth * containerHeight / imageHeight, containerHeight) : CGSizeMake(containerWidth, imageHeight * containerWidth / imageWidth)
    } else {
        retVal = containerAspectRatio < imageAspectRatio ? CGSizeMake(imageWidth * containerHeight / imageHeight, containerHeight) : CGSizeMake(containerWidth, imageHeight * containerWidth / imageWidth)
    }

    return retVal
}

这节省了我的时间。谢谢!
有用,但在 segue 和回来活动后表现得很奇怪,请参见此处:stackoverflow.com/questions/30978685/…
请注意:您可能希望向 aspectRatioAwareSize 函数添加一个前置条件 (guard),以便在 imageSize 或 boxSize 的输入参数为 CGSize.zero 时它不会引发除以零异常
@pkluz 这是一个很好的建议,但我认为你需要在整个函数中使用它们,因为每个变量都是另一行的除数......为了清楚起见,我将保持原样。对于 github 的生产或库,您可能想要加强这一点......不仅仅是警卫,我担心该函数使用的短变量名称不多。我可能会先解决这个问题,然后为其他事情添加保护,然后添加单元测试。
D
DanielEdrisian

斯威夫特 4 答案:

func scaleDown(image: UIImage, withSize: CGSize) -> UIImage {
    let scale = UIScreen.main.scale
    UIGraphicsBeginImageContextWithOptions(withSize, false, scale)
    image.draw(in: CGRect(x: 0, y: 0, width: withSize.width, height: withSize.height))
    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return newImage!
}

无需设置实际比例:The scale factor to apply to the bitmap. If you specify a value of 0.0, the scale factor is set to the scale factor of the device’s main screen.