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

pim*_*oum 381 resize uiimage ios

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

UIImage *newImage = [image _imageScaledToSize:CGSizeMake(290, 390)
                         interpolationQuality:1];    
Run Code Online (Sandbox Code Playgroud)

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

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

Pau*_*nch 762

最简单的方法是设置您的框架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;
}
Run Code Online (Sandbox Code Playgroud)

用法示例:

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

  • [从iOS 4.0开始](http://developer.apple.com/library/ios/#releasenotes/General/WhatsNewIniPhoneOS/Articles/iPhoneOS4.html#//apple_ref/doc/uid/TP40009559-SW29),UIGraphics*函数都是线程安全的. (25认同)
  • 我不会在这里保留结果.`newImage`将会自动释放,它应该由调用它的方法保留或不保留.这种方法只是乞求内存错误,因为`init`不是方法名称的一部分.我希望这样命名的方法返回一个自动释放的对象. (11认同)
  • 对于因限制而受到困扰的人@NikolaiRuhe指出,你可以通过在调用"UIGraphicsBeginImageContextWithOptions"时传递1.0而不是0.0来强制它达到精确的像素大小. (8认同)
  • @Paul Lynch:请记住,这一改变打破了原始帖子的使命:如何将图像调整为精确的*像素*大小(而不是*点*大小). (3认同)

Rog*_*ves 80

这是Paul Lynch答案的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
}
Run Code Online (Sandbox Code Playgroud)

Swift 3.0版本:

func imageWithImage(image:UIImage, scaledToSize newSize:CGSize) -> UIImage{
    UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0);
    image.draw(in: CGRect(origin: CGPoint.zero, size: CGSize(width: newSize.width, height: newSize.height)))
    let newImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()!
    UIGraphicsEndImageContext()
    return newImage
}
Run Code Online (Sandbox Code Playgroud)

  • UIGraphicsBeginImageContextWithOptions(newSize,false,image.scale); 适用于所有设备 (6认同)
  • 刚刚指出,在iOS中,您的newSize将乘以2倍,基于设备为3倍 (2认同)

Jak*_*ůša 56

适用于iOS 10+解决方案的适当Swift 3.0:使用和关闭语法:ImageRenderer

func imageWith(newSize: CGSize) -> UIImage {
    let renderer = UIGraphicsImageRenderer(size: newSize)
    let image = renderer.image { _ in
        self.draw(in: CGRect.init(origin: CGPoint.zero, size: newSize))
    }

    return image
}
Run Code Online (Sandbox Code Playgroud)

这是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;
}
@end
Run Code Online (Sandbox Code Playgroud)

  • 这比优雅更好,这是正确的.Apple的api文档建议使用UIGraphicsRenderer作为此代码的新代码.谢谢 (2认同)

Tec*_*Zen 31

特雷弗霍华德有一些UIImage类别,可以很好地处理调整大小.如果没有别的,您可以使用代码作为示例.

注意:从iOS 5.1开始,此答案可能无效.见下面的评论.

  • 我也需要调整一些图像的大小,我首先尝试了Trevor对UIImage的补充,但在PNG上有一些奇怪的错误(关于alpha通道的一些东西).尽管如此,这个问题的答案得到了很好的解决. (2认同)

iwa*_*bed 25

我也看到过这个(我UIButtons用于Normal和Selected状态,因为按钮不resize适合).归功于原作者的任何人.

首先创建一个名为UIImageResizing.h和的空.h和.m文件UIImageResizing.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
Run Code Online (Sandbox Code Playgroud)

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

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


nea*_*ave 20

适用于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))
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

let resizedImage = image.resized(to: CGSize(width: 50, height: 50))
Run Code Online (Sandbox Code Playgroud)


mal*_*hal 19

保罗代码的这一改进将为您提供具有视网膜显示屏的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;
}
Run Code Online (Sandbox Code Playgroud)

  • 仅供参考,您所做的更改是不必要的,因为在`UIGraphicsBeginImageContextWithOptions`中为比例提供0.0值将自动使用主屏幕的比例(从iOS 3.2开始). (13认同)

小智 15

这是一个简单的方法:

    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();
Run Code Online (Sandbox Code Playgroud)

resizedImage是一个新图像.


Sco*_*ans 15

以下是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;
}
Run Code Online (Sandbox Code Playgroud)


Ely*_*Ely 14

当使用iOS 15或更高版本时,您可以使用以下新prepareThumbnail方法UIImage

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

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


san*_*mai 11

如果您只想要一个较小的图像而不关心确切的大小:

+ (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;
}
Run Code Online (Sandbox Code Playgroud)

设置比例0.25f将为您提供来自800万像素摄像头的816乘612图像.

这是一个类别UIImage + Scale,适合那些需要的人.


Jos*_*eld 10

适用于Stretch Fill,Aspect Fill和Aspect Fit的Swift解决方案

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, 1)
        defer { UIGraphicsEndImageContext() }
        draw(in: CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height))
        return UIGraphicsGetImageFromCurrentImageContext()
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

感谢abdullahselek的原始解决方案.


Vad*_*off 10

对于 Swift 5:

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

    draw(in: CGRect(origin: .zero, size: newSize))
    return UIGraphicsGetImageFromCurrentImageContext()
  }
}
Run Code Online (Sandbox Code Playgroud)


Chr*_*ris 9

为什么这么复杂?我认为使用系统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.
Run Code Online (Sandbox Code Playgroud)

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


aub*_*han 8

我在Apple自己的例子中找到了UIImage的一个类别,它也做了同样的伎俩.这是链接:https://developer.apple.com/library/ios/samplecode/sc2273/Listings/AirDropSample_UIImage_Resize_m.html.

你只需要改变电话:

UIGraphicsBeginImageContextWithOptions(newSize, YES, 2.0);
Run Code Online (Sandbox Code Playgroud)

imageWithImage:scaledToSize:inRect::与:

UIGraphicsBeginImageContextWithOptions(newSize, NO, 2.0);
Run Code Online (Sandbox Code Playgroud)

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


abd*_*lek 8

这是一个与Swift 3Swift 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))
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

用法示例

let image = UIImage(named: "apple")
let scaledImage = image.scaleImageToFitSize(size: CGSize(width: 45.0, height: 45.0))
Run Code Online (Sandbox Code Playgroud)


小智 6

 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
}
Run Code Online (Sandbox Code Playgroud)


小智 5

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

UIImage* squareImage       = [image resizedImageByMagick: @"320x320#"];
Run Code Online (Sandbox Code Playgroud)


Int*_*tss 5

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
}
Run Code Online (Sandbox Code Playgroud)

还有奖金

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


tir*_*tea 5

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

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

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


小智 5

带有故障保护选项的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
}
Run Code Online (Sandbox Code Playgroud)


nat*_*han 5

(兼容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!
    }
}
Run Code Online (Sandbox Code Playgroud)


iOS*_*eam 5

无需拉伸图像的有效方法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!
                }
Run Code Online (Sandbox Code Playgroud)

//调用方法

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


Mar*_*und 5

对于我的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;
}
Run Code Online (Sandbox Code Playgroud)