首页 文章

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

提问于
浏览
125

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

16 回答

  • 5

    如果你知道新尺寸的宽度,那么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;
    }
    
  • 5

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

    假设你有 UIImage *myLargeImage ,这是一个4:3的比例 .

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

    如果是风景,重新调整大小的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];
    }
    
  • 8

    最佳答案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!
    }
    
  • 2

    感谢@ 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
    }
    
  • 0

    此方法是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
    
  • 36

    最简单的方法是设置 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;
    }
    
  • 33

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

    My Requirement was

    • 如果图像宽度大于1920,请使用1920宽度调整大小并使用原始高宽比保持高度 .

    • 如果图像高度超过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;
    }
    

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

    您可能还想检查this以进行调整大小计算 .

  • 1

    编程方式:

    imageView.contentMode = UIViewContentModeScaleAspectFit;
    

    故事板:

    enter image description here

  • 56

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

  • 1

    为了改进Ryan的答案:

    + (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)size {
    CGFloat oldWidth = image.size.width;
            CGFloat oldHeight = image.size.height;
    
    //You may need to take some retina adjustments into consideration here
            CGFloat scaleFactor = (oldWidth > oldHeight) ? width / oldWidth : height / oldHeight;
    
    return [UIImage imageWithCGImage:image.CGImage scale:scaleFactor orientation:UIImageOrientationUp];
        }
    
  • 0

    Ryan的解决方案@Ryan在快速代码中

    使用:

    func imageWithSize(image: UIImage,size: CGSize)->UIImage{
        if UIScreen.mainScreen().respondsToSelector("scale"){
            UIGraphicsBeginImageContextWithOptions(size,false,UIScreen.mainScreen().scale);
        }
        else
        {
             UIGraphicsBeginImageContext(size);
        }
    
        image.drawInRect(CGRectMake(0, 0, size.width, size.height));
        var newImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    
        return newImage;
    }
    
    //Summon this function VVV
    func resizeImageWithAspect(image: UIImage,scaledToMaxWidth width:CGFloat,maxHeight height :CGFloat)->UIImage
    {
        let oldWidth = image.size.width;
        let oldHeight = image.size.height;
    
        let scaleFactor = (oldWidth > oldHeight) ? width / oldWidth : height / oldHeight;
    
        let newHeight = oldHeight * scaleFactor;
        let newWidth = oldWidth * scaleFactor;
        let newSize = CGSizeMake(newWidth, newHeight);
    
        return imageWithSize(image, size: newSize);
    }
    
  • 226

    Swift 3 中有一些变化 . 这是UIImage的扩展:

    public extension UIImage {
        public func resize(height: CGFloat) -> UIImage? {
            let scale = height / self.size.height
            let width = self.size.width * scale
            UIGraphicsBeginImageContext(CGSize(width: width, height: height))
            self.draw(in: CGRect(x:0, y:0, width:width, height:height))
            let resultImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            return resultImage
        }
    }
    
  • 0

    我用更简单的方式解决了这个问题

    UIImage *placeholder = [UIImage imageNamed:@"OriginalImage.png"];
    self.yourImageview.image = [UIImage imageWithCGImage:[placeholder CGImage] scale:(placeholder.scale * 1.5)
                                      orientation:(placeholder.imageOrientation)];
    

    比例的乘数将定义图像的scalling,更多的乘数更小的图像 . 所以你可以检查什么适合你的屏幕 .

    或者您也可以通过划分图像宽度/屏幕宽度来获得倍增 .

  • 0

    这个对我来说很完美 . 保持纵横比并采用 maxLength . 宽度或高度不会超过 maxLength

    -(UIImage*)imageWithImage: (UIImage*) sourceImage maxLength: (float) maxLength
    {
        CGFloat scaleFactor = maxLength / MAX(sourceImage.size.width, sourceImage.size.height);
    
        float newHeight = sourceImage.size.height * scaleFactor;
        float newWidth = sourceImage.size.width * scaleFactor;
    
        UIGraphicsBeginImageContext(CGSizeMake(newWidth, newHeight));
        [sourceImage drawInRect:CGRectMake(0, 0, newWidth, newHeight)];
        UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return newImage;
    }
    
  • 17

    Calculates the best height of the image for available width.

    import Foundation
    
    public extension UIImage {
        public func height(forWidth width: CGFloat) -> CGFloat {
            let boundingRect = CGRect(
                x: 0,
                y: 0,
                width: width,
                height: CGFloat(MAXFLOAT)
            )
            let rect = AVMakeRect(
                aspectRatio: size,
                insideRect: boundingRect
            )
            return rect.size.height
        }
    }
    
  • 4
    extension UIImage {
    
        /// Returns a image that fills in newSize
        func resizedImage(newSize: CGSize) -> UIImage? {
            guard size != newSize else { return self }
    
        let hasAlpha = false
        let scale: CGFloat = 0.0
        UIGraphicsBeginImageContextWithOptions(newSize, !hasAlpha, scale)
            UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0)
    
            draw(in: CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height))
            let newImage: UIImage? = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            return newImage
        }
    
        /// Returns a resized image that fits in rectSize, keeping it's aspect ratio
        /// Note that the new image size is not rectSize, but within it.
        func resizedImageWithinRect(rectSize: CGSize) -> UIImage? {
            let widthFactor = size.width / rectSize.width
            let heightFactor = size.height / rectSize.height
    
            var resizeFactor = widthFactor
            if size.height > size.width {
                resizeFactor = heightFactor
            }
    
            let newSize = CGSize(width: size.width / resizeFactor, height: size.height / resizeFactor)
            let resized = resizedImage(newSize: newSize)
    
            return resized
        }
    }
    

    当scale设置为0.0时,使用主屏幕的比例因子,Retina显示的比例因子为2.0或更高(iPhone 6 Plus上为3.0) .

相关问题