UIImage调整大小(比例缩放)

53

可能是重复问题:
如何按比例调整UIImage的大小?

以下代码可以完美地调整图像的大小,但问题是它会破坏它的长宽比(导致图像倾斜)。有什么解决方法吗?

// Change image resolution (auto-resize to fit)
+ (UIImage *)scaleImage:(UIImage*)image toResolution:(int)resolution {
    CGImageRef imgRef = [image CGImage];
    CGFloat width = CGImageGetWidth(imgRef);
    CGFloat height = CGImageGetHeight(imgRef);
    CGRect bounds = CGRectMake(0, 0, width, height);

    //if already at the minimum resolution, return the orginal image, otherwise scale
    if (width <= resolution && height <= resolution) {
        return image;

    } else {
        CGFloat ratio = width/height;

        if (ratio > 1) {
            bounds.size.width = resolution;
            bounds.size.height = bounds.size.width / ratio;
        } else {
            bounds.size.height = resolution;
            bounds.size.width = bounds.size.height * ratio;
        }
    }

    UIGraphicsBeginImageContext(bounds.size);
    [image drawInRect:CGRectMake(0.0, 0.0, bounds.size.width, bounds.size.height)];
    UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return imageCopy;
}

请查看这个问题(以及我的答案):https://dev59.com/oHI-5IYBdhLWcg3wu7FU#1703210 - Frank Schmitt
将链接到其他SO问题的答案并不被认为是很好的答案。如果这是一个重复的问题,应该将其关闭。 - joran
这帮助了我解决了一个问题,我需要缩放UIImage,谢谢 :) - RelativeGames
5个回答

122

我使用这一行代码创建一个经过缩放的新UIImage。设置比例和方向参数以达到您想要的效果。第一行代码只是获取图像。

    // grab the original image
    UIImage *originalImage = [UIImage imageNamed:@"myImage.png"];
    // scaling set to 2.0 makes the image 1/2 the size. 
    UIImage *scaledImage = 
                [UIImage imageWithCGImage:[originalImage CGImage] 
                              scale:(originalImage.scale * 2.0)
                                 orientation:(originalImage.imageOrientation)];

20
这是一个逻辑上的调整大小。如果您想要为了性能而调整图像大小,请参阅http://vocaro.com/trevor/blog/2009/10/12/resize-a-uiimage-the-right-way/,或者如果您在iOS 5中遇到错误行为,请查看http://eran.sandler.co.il/2011/11/07/uiimage-in-ios-5-orientation-and-resize/。 - Xavi Gil
10
很明显这是阿卜杜勒所为,否则不会有36个人赞同。你做错了什么。 - Adam Waite
8
升级到2.0会使图像变为原来的一半大小...哈哈! - zonabi
1
对于Swift编程语言: let img: UIImage = UIImage(named: "lena")! var scaledImage = UIImage(CGImage: img.CGImage!, scale: img.scale * 2, orientation: img.imageOrientation) - vkalit
@zonabi,这并不好笑。将其除以2.0而不是乘以它怎么样... UIImage *scaledImage = [UIImage imageWithCGImage:[image CGImage] scale:image.scale/2.0 orientation:(image.imageOrientation)]; 这样你就可以更合理地呈现你的比例需求(也就是“我想用n因子乘以比例”)。 - Bejil

17

没关系,这不是个大问题。重点是找到比例适合的宽度和高度。

例如,如果尺寸为2048.0 x 1360.0的图片需要调整大小为320 x 480的分辨率,则结果图像大小应为722.0 x 480.0。

here is the formulae to do that . if w,h is original and x,y are resulting image.
w/h=x/y 
=> 
x=(w/h)*y;  

submitting w=2048,h=1360,y=480 => x=722.0 ( here width>height. if height>width then consider x to be 320 and calculate y)

你可以在这个网页中提交。 ARC

有疑问吗?没关系,这里有一个UIImage的类别将为你完成这件事。

@interface UIImage (UIImageFunctions)
    - (UIImage *) scaleToSize: (CGSize)size;
    - (UIImage *) scaleProportionalToSize: (CGSize)size;
@end
@implementation UIImage (UIImageFunctions)

- (UIImage *) scaleToSize: (CGSize)size
{
    // Scalling selected image to targeted size
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(NULL, size.width, size.height, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast);
    CGContextClearRect(context, CGRectMake(0, 0, size.width, size.height));

    if(self.imageOrientation == UIImageOrientationRight)
    {
        CGContextRotateCTM(context, -M_PI_2);
        CGContextTranslateCTM(context, -size.height, 0.0f);
        CGContextDrawImage(context, CGRectMake(0, 0, size.height, size.width), self.CGImage);
    }
    else
        CGContextDrawImage(context, CGRectMake(0, 0, size.width, size.height), self.CGImage);

    CGImageRef scaledImage=CGBitmapContextCreateImage(context);

    CGColorSpaceRelease(colorSpace);
    CGContextRelease(context);

    UIImage *image = [UIImage imageWithCGImage: scaledImage];

    CGImageRelease(scaledImage);

    return image;
}

- (UIImage *) scaleProportionalToSize: (CGSize)size1
{
    if(self.size.width>self.size.height)
    {
        NSLog(@"LandScape");
        size1=CGSizeMake((self.size.width/self.size.height)*size1.height,size1.height);
    }
    else
    {
        NSLog(@"Potrait");
        size1=CGSizeMake(size1.width,(self.size.height/self.size.width)*size1.width);
    }

    return [self scaleToSize:size1];
}

@end

-- 如果img是UIImage实例,以下是进行此操作的适当调用方法。

img=[img scaleProportionalToSize:CGSizeMake(320, 480)];


你是指anImageView.contentMode = UIViewContentModeScaleAspectFit;吗? - Wayne Lo
yup类似于Content Mode,但不使用任何UI元素,因此可以将缩放后的图像进一步存储到文件或数据库中... - RamaKrishna Chunduri

5

这个修复将数学计算方式改进,使得它能够同时根据原始图像的宽度和高度来缩放至最大尺寸。

- (UIImage *) scaleProportionalToSize: (CGSize)size
{
    float widthRatio = size.width/self.size.width;
    float heightRatio = size.height/self.size.height;

    if(widthRatio > heightRatio)
    {
        size=CGSizeMake(self.size.width*heightRatio,self.size.height*heightRatio);
    } else {
        size=CGSizeMake(self.size.width*widthRatio,self.size.height*widthRatio);
    }

    return [self scaleToSize:size];
}

4
这个修改对我有效:
// The size returned by CGImageGetWidth(imgRef) & CGImageGetHeight(imgRef) is incorrect as it doesn't respect the image orientation!
// CGImageRef imgRef = [image CGImage];
// CGFloat width = CGImageGetWidth(imgRef);
// CGFloat height = CGImageGetHeight(imgRef);
//
// This returns the actual width and height of the photo (and hence solves the problem
CGFloat width = image.size.width; 
CGFloat height = image.size.height;
CGRect bounds = CGRectMake(0, 0, width, height);

0
尝试将bounds的大小设置为整数。
#include <math.h>
....

    if (ratio > 1) {
        bounds.size.width = resolution;
        bounds.size.height = round(bounds.size.width / ratio);
    } else {
        bounds.size.height = resolution;
        bounds.size.width = round(bounds.size.height * ratio);
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接