通过保持宽高比和宽度来调整UIImage的大小

Jas*_*ine 131 iphone objective-c aspect-ratio fixed-width ios

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

Mav*_*1st 227

如果您知道新尺寸的高度宽度,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;
}
Run Code Online (Sandbox Code Playgroud)

  • 你不需要这里的'newWidth`变量,它已经是`i_width`了. (21认同)
  • 很好的回答,谢谢.还有一件事:如果你使用这种方法遇到任何图像质量损失,那么使用`UIGraphicsBeginImageContextWithOptions(CGSizeMake(newWidth,newHeight),NO,0);`而不是`UIGraphicsBeginImageContext(CGSizeMake(newWidth,newHeight));` (12认同)
  • 您还需要按高度进行划分,并使用接近0的比较比较缩放因子.上面的代码仅适用于宽度高于高的图像 (2认同)

Rya*_*yan 57

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

假设你有一个UIImage *myLargeImage4:3的比例.

UIImage *myResizedImage = [ImageUtilities imageWithImage:myLargeImage 
                                        scaledToMaxWidth:1024 
                                               maxHeight:1024];
Run Code Online (Sandbox Code Playgroud)

如果是风景,重新调整大小的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];
}
Run Code Online (Sandbox Code Playgroud)

  • 要适应最大宽度和最大高度,您需要最小比率作为比例因子:`min(ratioX,ratioY)`.否则,如果宽度较大,则可能不适合最大高度. (5认同)
  • 如果只想缩小而不是缩小,别忘了用以下方法启动imageWithImage:scaledToMaxWidth:maxHeight:方法:if(image.size.width <width && image.size.height <height){返回图像;} (2认同)

Ale*_*ano 38

最佳答案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!
}
Run Code Online (Sandbox Code Playgroud)


Ján*_*nos 36

感谢@ Maverick1st算法,我实现了它Swift,在我的情况下,height是输入参数

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


moh*_*945 18

此方法是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
Run Code Online (Sandbox Code Playgroud)

  • 发现这一点,以最小的内存占用为我提供最好的结果.+1 (2认同)

Sri*_*aju 7

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

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

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


mar*_*LAN 5

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


swi*_*Boy 5

好吧,我们在这里没有很好的答案来调整图像大小,但我只是根据我的需要进行修改.希望这有助于像我这样的人.

我的要求是

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

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

您可能也想检查这个以调整大小.


Mon*_*ona 5

编程方式:

imageView.contentMode = UIViewContentModeScaleAspectFit;
Run Code Online (Sandbox Code Playgroud)

故事板:

在此输入图像描述


Wom*_*ble 5

斯威夫特5版方面配合-TO-的高度,通过@亚诺什基于答案

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

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