2011-10-04 179 views
112

我在许多文章中看到通过保持纵横比来调整图像的大小。这些功能在调整大小时使用RECT的固定点(宽度和高度)。但在我的项目中,我只需根据宽度调整视图大小,高度应根据高宽比自动调整。 任何人都可以帮助我实现这一点。通过保持纵横比和宽度来调整UIImage的尺寸

回答

215

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; 
} 
+20

尽管这里你确实不需要newWidth变量,但它已经是'i_width'了。 –

+2

您还需要按高度进行划分,并使用较接近0的比例来比较比例因子。上面的代码只适用于比高度更宽的图片 – IceForge

+1

如果我想要,我只需要按高度进行划分通过缩放宽度或高度来了解我的身高比。但由于TO明确要求保持比例和宽度,而不是宽度或高度,我的回答是完全正确的。 – Maverick1st

8

最简单的方法是设置您的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; 
} 
+0

我设法让它只用设置'contentMode'。 –

54

如果你不知道发生如果图像将是纵向还是横向(例如用户需要与摄像头PIC),我创建了另一个是需要最大宽度和高度参数的方法。

比方说你有一个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]; 
} 
+0

谢谢。这正是我一直在寻找的! – SeanK

+0

非常感谢! – 4GetFullOf

+1

这是最好的东西,但它总是返回我定义大小的两倍 – Mashhadi

4

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

2

为了提高对瑞安的答案:

+ (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]; 
    } 
31

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

此方法是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 
+2

发现这个以最小的内存占用给我最好的结果。 +1 –

+1

非常棒,非常感谢。 –

1

瑞安的解决方案@Ryan 在SWIFT代码

使用:

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); 
} 
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; 
} 

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

您可能还想检查this以及调整大小的计算。

0

我有一个更简单的方法

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

乘数规模将定义图像的scalling,更乘数越小,图像解决它。所以你可以检查什么适合你的屏幕。

或者你也可以通过分割图像宽度/屏幕宽度来获得多倍。

32

最佳答案特立独行1日的正确翻译为斯威夫特(带最新的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! 
} 
5

编程:

imageView.contentMode = UIViewContentModeScaleAspectFit; 

故事板:

enter image description here

0

In 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

这对我来说是完美的。保持宽高比并需要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; 
}