ios 通过保持纵横比和宽度来调整 UIImage 的大小

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7645454/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 21:44:03  来源:igfitidea点击:

Resize UIImage by keeping Aspect ratio and width

iphoneobjective-ciosaspect-ratiofixed-width

提问by Jasmine

I seen in many posts for resizing the image by keeping aspect ratio. These functions uses the fixed points(Width and Height) for RECT while resizing. But in my project, I need to resize the view based on the Width alone, Height should be taken automatically based on the aspect ratio. anyone help me to achieve this.

我在许多帖子中看到通过保持纵横比来调整图像大小。这些函数在调整大小时使用 RECT 的固定点(宽度和高度)。但是在我的项目中,我需要仅根据宽度调整视图大小,应根据纵横比自动获取高度。任何人都可以帮助我实现这一目标。

回答by Maverick1st

The method of Srikar works very well, if you know both height andwidth of your new Size. If you for example know only the width you want to scale to and don't care about the height you first have to calculate the scale factor of the height.

如果您知道新尺寸的高度宽度,Srikar 的方法效果很好。例如,如果您只知道要缩放到的宽度而不关心高度,则首先必须计算高度的比例因子。

+(UIImage*)imageWithImage: (UIImage*) sourceImage scaledToWidth: (float) i_width
{
    float oldWidth = sourceImage.size.width;
    float scaleFactor = i_width / oldWidth;

    float newHeight = sourceImage.size.height * scaleFactor;
    float newWidth = oldWidth * scaleFactor;

    UIGraphicsBeginImageContext(CGSizeMake(newWidth, newHeight));
    [sourceImage drawInRect:CGRectMake(0, 0, newWidth, newHeight)];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();    
    UIGraphicsEndImageContext();
    return newImage;
}

回答by Ryan

If you don't happen to know if the image will be portrait or landscape (e.g user takes pic with camera), I created another method that takes max width and height parameters.

如果您不知道图像是纵向还是横向(例如用户用相机拍照),我创建了另一种采用最大宽度和高度参数的方法。

Lets say you have a UIImage *myLargeImagewhich is a 4:3 ratio.

假设您有一个UIImage *myLargeImage4:3 的比例。

UIImage *myResizedImage = [ImageUtilities imageWithImage:myLargeImage 
                                        scaledToMaxWidth:1024 
                                               maxHeight:1024];

The resized UIImage will be 1024x768 if landscape; 768x1024 if portrait. This method will also generate higher res images for retina display.

如果是横向,调整后的 UIImage 将为 1024x768;768x1024 如果是纵向。此方法还将为视网膜显示生成更高分辨率的图像。

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

    return newImage;
}

+ (UIImage *)imageWithImage:(UIImage *)image scaledToMaxWidth:(CGFloat)width maxHeight:(CGFloat)height {
    CGFloat oldWidth = image.size.width;
    CGFloat oldHeight = image.size.height;

    CGFloat scaleFactor = (oldWidth > oldHeight) ? width / oldWidth : height / oldHeight;

    CGFloat newHeight = oldHeight * scaleFactor;
    CGFloat newWidth = oldWidth * scaleFactor;
    CGSize newSize = CGSizeMake(newWidth, newHeight);

    return [ImageUtilities imageWithImage:image scaledToSize:newSize];
}

回答by Alessandro Ornano

Best answer Maverick 1st's correctly translated to Swift(working with latest swift 3):

最佳答案 Maverick 1st 正确翻译为Swift(使用最新的swift 3):

func imageWithImage (sourceImage:UIImage, scaledToWidth: CGFloat) -> UIImage {
    let oldWidth = sourceImage.size.width
    let scaleFactor = scaledToWidth / oldWidth

    let newHeight = sourceImage.size.height * scaleFactor
    let newWidth = oldWidth * scaleFactor

    UIGraphicsBeginImageContext(CGSize(width:newWidth, height:newHeight))
    sourceImage.draw(in: CGRect(x:0, y:0, width:newWidth, height:newHeight))
    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return newImage!
}

回答by János

thanks @Maverick1st the algorithm, I implemented it to Swift, in my case height is the input parameter

感谢@Maverick1st 算法,我实现了它Swift,在我的例子中,高度是输入参数

class func resizeImage(image: UIImage, newHeight: CGFloat) -> UIImage {

    let scale = newHeight / image.size.height
    let newWidth = image.size.width * scale
    UIGraphicsBeginImageContext(CGSizeMake(newWidth, newHeight))
    image.drawInRect(CGRectMake(0, 0, newWidth, newHeight))
    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    return newImage
}

回答by mohamede1945

This method is a category on UIImage. Does scale to fit in few lines of code using AVFoundation. Don't forget to import #import <AVFoundation/AVFoundation.h>.

这个方法是 UIImage 上的一个类。使用 AVFoundation 进行缩放以适应几行代码。不要忘记导入#import <AVFoundation/AVFoundation.h>.

@implementation UIImage (Helper)

- (UIImage *)imageScaledToFitToSize:(CGSize)size
{
    CGRect scaledRect = AVMakeRectWithAspectRatioInsideRect(self.size, CGRectMake(0, 0, size.width, size.height));
    UIGraphicsBeginImageContextWithOptions(size, NO, 0);
    [self drawInRect:scaledRect];
    UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return scaledImage;
}

@end

回答by Womble

Swift 5version of aspect-fit-to-height, based on answer by @János

Swift 5版本的 aspect-fit-to- height,基于@János 的回答

Uses the modern UIGraphicsImageRendererAPI, so a valid UIImageis guaranteed to return.

使用现代UIGraphicsImageRendererAPI,因此UIImage保证返回有效。

extension UIImage
{
    /// Given a required height, returns a (rasterised) copy
    /// of the image, aspect-fitted to that height.

    func aspectFittedToHeight(_ newHeight: CGFloat) -> UIImage
    {
        let scale = newHeight / self.size.height
        let newWidth = self.size.width * scale
        let newSize = CGSize(width: newWidth, height: newHeight)
        let renderer = UIGraphicsImageRenderer(size: newSize)

        return renderer.image { _ in
            self.draw(in: CGRect(origin: .zero, size: newSize))
        }
    }
}

You can use this in conjunction with a (vector-based) PDF image asset, to preserve quality at any render size.

您可以将它与(基于矢量的)PDF 图像资产结合使用,以保持任何渲染尺寸的质量。

回答by Srikar Appalaraju

The simplest way is to set the frame of your UIImageViewand set the contentModeto one of the resizing options.

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

The code goes like this - This can be used as an utility method -

代码是这样的 - 这可以用作实用方法 -

+ (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize
{
    UIGraphicsBeginImageContext(newSize);
    [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();    
    UIGraphicsEndImageContext();
    return newImage;
}

回答by Mona

Programmatically:

以编程方式:

imageView.contentMode = UIViewContentModeScaleAspectFit;

Storyboard:

故事板:

enter image description here

在此处输入图片说明

回答by swiftBoy

Well, we have few good answers here for resizing image, but I just modify as per my need. hope this help someone like me.

好吧,我们在这里调整图像大小的答案很少,但我只是根据我的需要进行修改。希望这能帮助像我这样的人。

My Requirement was

我的要求是

  1. If image width is more than 1920, resize it with 1920 width and maintaining height with original aspect ratio.
  2. If image height is more than 1080, resize it with 1080 height and maintaining width with original aspect ratio.
  1. 如果图像宽度大于 1920,则将其调整为 1920 宽度并保持高度与原始纵横比。
  2. 如果图像高度超过 1080,则将其调整为 1080 高度并保持宽度与原始纵横比。


 if (originalImage.size.width > 1920)
 {
        CGSize newSize;
        newSize.width = 1920;
        newSize.height = (1920 * originalImage.size.height) / originalImage.size.width;
        originalImage = [ProfileEditExperienceViewController imageWithImage:originalImage scaledToSize:newSize];        
 }

 if (originalImage.size.height > 1080)
 {
            CGSize newSize;
            newSize.width = (1080 * originalImage.size.width) / originalImage.size.height;
            newSize.height = 1080;
            originalImage = [ProfileEditExperienceViewController imageWithImage:originalImage scaledToSize:newSize];

 }

+ (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize
{
        UIGraphicsBeginImageContext(newSize);
        [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
        UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return newImage;
}

Thanks to @Srikar Appal, for resizing I have used his method.

感谢@ Srikar Appal,为了调整大小,我使用了他的方法。

You may like to check thisas well for resize calculation.

您可能还想检查这个以进行调整大小计算。

回答by mariusLAN

Just import AVFoundation and use AVMakeRectWithAspectRatioInsideRect(CGRectCurrentSize, CGRectMake(0, 0, YOUR_WIDTH, CGFLOAT_MAX)

只需导入 AVFoundation 并使用 AVMakeRectWithAspectRatioInsideRect(CGRectCurrentSize, CGRectMake(0, 0, YOUR_WIDTH, CGFLOAT_MAX)