上传到服务器之前,如何在iOS上压缩/调整图像大小?


75

我目前正在使用Imgur在iOS上使用以下代码将图像上传到服务器:

NSData* imageData = UIImagePNGRepresentation(image);
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* fullPathToFile = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"SBTempImage.png"];
[imageData writeToFile:fullPathToFile atomically:NO];

[uploadRequest setFile:fullPathToFile forKey:@"image"];

当我在模拟器中运行并从模拟器的图片库上传文件时,该代码可以正常工作,因为我处于快速以太网连接中。但是,选择使用iPhone拍摄的图像时,相同的代码在iPhone上超时。因此,我通过从网络上保存一个小图像并尝试将其上传的方式进行了尝试,该方法可以正常工作。

这使我相信iPhone拍摄的大图像正在通过速度较慢的3G网络超时。有没有办法在发送之前压缩/调整iPhone中的图像大小?

Answers:


-36

您应该可以通过执行以下操作来制作较小的图像

UIImage *small = [UIImage imageWithCGImage:original.CGImage scale:0.25 orientation:original.imageOrientation];

(对于四分之一大小的图像),然后将较小的图像转换为PNG或您需要的任何格式。


52
这会更改缩放后的图像的报告大小,但实际上不会更改图像数据。在原始图像和缩放后的图像上生成的NSData的数据长度实际上是相同的。
Joshua Sullivan

13
这行不通!这不应该是公认的答案!我只是在我的应用程序中实现了它,只是发现压缩到原始图像大小的25%的图像仍具有与原始字节相同的字节大小。我不知道为什么会有这么多的投票或这个无效的答案!
迈克尔

不起作用。缩放图像,但保留完整尺寸的数据。
2013年

再次,不起作用。请删除/更新此答案,以免浪费更多时间。
Zorayr

它不会更改文件大小,因为UIImage的深层副本是CGImage,并且调整大小不会更改图像。请参阅Apple文档,以更改文件大小,然后使用缩放后的版本创建新图像。了解什么是指针。还应该知道,按比例缩小然后放大会导致图像丢失,如果您将其用于重要的事情,则以后看起来会很模糊。压缩并使用JPegCompress或任何调用该函数的函数并将其发送。
尼克·特纳

202

此代码段将调整图像的大小:

UIGraphicsBeginImageContext(newSize);
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

变量newSize是a CGSize,可以这样定义:

CGSize newSize = CGSizeMake(100.0f, 100.0f);

1
这实际上是可行的解决方案(图像数据大小从145k变为30k)。
Joshua Sullivan

9
“ newSize”是CGSize,例如。CGSize newSize = CGSizeMake(100.0f,100.0f);
德克斯特(Dexter)2012年

大!不要急于使用压缩技术,这是最简单,最有效的解决方法:)
DivineDesert 2013年

但这会改变图像的大小,如果我需要将图像上传到原始规格的服务器上,那将不起作用,对吗?
Nuzhat Zari

这是ImageSize的大小“ newSize”吗?
Stephan Boner

38

一个独立的解决方案:

- (UIImage *)compressForUpload:(UIImage *)original scale:(CGFloat)scale
{
    // Calculate new size given scale factor.
    CGSize originalSize = original.size;
    CGSize newSize = CGSizeMake(originalSize.width * scale, originalSize.height * scale);

    // Scale the original image to match the new size.
    UIGraphicsBeginImageContext(newSize);
    [original drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
    UIImage *compressedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return compressedImage;
}

感谢@Tuan Nguyen。


16

为了补充@Tuan Nguyen,这也许是最快,最优雅的方法。

要链接到iphonedevelopertips.com上John Muchow的帖子,在UIImage中添加类别是一种非常便捷的方法,可以非常快速地进行缩放。刚打电话

    UIImage *_image = [[[UIImage alloc] initWithData:SOME_NSDATA] scaleToSize:CGSizeMake(640.0,480.0)];

返回您的NSDATA的640x480表示图像(可能是在线图像),而无需任何其他代码行。


1
它实际上按比例缩小了像素。因此,这也减小了图片所拍摄的大小。但是它本身并没有进行“重新压缩”。如果这就是您在这里提到的。
nembleton



4

用这个简单的方法 NSData *data = UIImageJPEGRepresentation(chosenImage, 0.2f);


3

Zorayr函数的快速实现(略有变化,以实际单位(不按比例缩放)包括高度或宽度约束):

class func compressForUpload(original:UIImage, withHeightLimit heightLimit:CGFloat, andWidthLimit widthLimit:CGFloat)->UIImage{

    let originalSize = original.size
    var newSize = originalSize

    if originalSize.width > widthLimit && originalSize.width > originalSize.height {

        newSize.width = widthLimit
        newSize.height = originalSize.height*(widthLimit/originalSize.width)
    }else if originalSize.height > heightLimit && originalSize.height > originalSize.width {

        newSize.height = heightLimit
        newSize.width = originalSize.width*(heightLimit/originalSize.height)
    }

    // Scale the original image to match the new size.
    UIGraphicsBeginImageContext(newSize)
    original.drawInRect(CGRectMake(0, 0, newSize.width, newSize.height))
    let compressedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return compressedImage
}

2
这个解决方案很好,但是不适用于正方形图像。因为originalSize.width> originalSize.height和originalSize.height> originalSize.width,所以最好将其更改为> = :-)
rcpfuchs

0
#import <ImageIO/ImageIO.h>
#import <MobileCoreServices/MobileCoreServices.h>

+ (UIImage *)resizeImage:(UIImage *)image toResolution:(int)resolution {
NSData *imageData = UIImagePNGRepresentation(image);
CGImageSourceRef src = CGImageSourceCreateWithData((__bridge CFDataRef)imageData, NULL);
CFDictionaryRef options = (__bridge CFDictionaryRef) @{
                                                       (id) kCGImageSourceCreateThumbnailWithTransform : @YES,
                                                       (id) kCGImageSourceCreateThumbnailFromImageAlways : @YES,
                                                       (id) kCGImageSourceThumbnailMaxPixelSize : @(resolution)
                                                       };
CGImageRef thumbnail = CGImageSourceCreateThumbnailAtIndex(src, 0, options);
CFRelease(src);
UIImage *img = [[UIImage alloc]initWithCGImage:thumbnail];
return img;
}

0

Swift 2.0版本的Jagandeep Singh方法,但是由于NSData需要将数据转换为图像?不会自动转换为UIImage。

let orginalImage:UIImage = image

let compressedData = UIImageJPEGRepresentation(orginalImage, 0.5)
let compressedImage = UIImage(data: compressedData!)

0
NsData *data=UiImageJPEGRepresentation(Img.image,0.2f);

1
详细说明这样的答案通常会很有帮助。提供到文档的链接,该文档的引号,以及对代码为何能回答问题的解释。
乍得

0
UIImage *image = [UIImage imageNamed:@"image.png"];
NSData *imgData1 = UIImageJPEGRepresentation(image, 1);
NSLog(@"Original --- Size of Image(bytes):%d",[imgData1 length]);

NSData *imgData2 = UIImageJPEGRepresentation(image, 0.5);
NSLog(@"After --- Size of Image(bytes):%d",[imgData2 length]);
image = [UIImage imageWithData:imgData2];
imgTest.image = image;

尝试按比例因子转换JPG。在这里,我使用的是0.5:原始---图片大小(字节):85KB及之后---图片大小(字节):23KB


-1
-(UIImage *) resizeImage:(UIImage *)orginalImage resizeSize:(CGSize)size
{
CGFloat actualHeight = orginalImage.size.height;
CGFloat actualWidth = orginalImage.size.width;
//  if(actualWidth <= size.width && actualHeight<=size.height)
//  {
//      return orginalImage;
//  }
float oldRatio = actualWidth/actualHeight;
float newRatio = size.width/size.height;
if(oldRatio < newRatio)
{
    oldRatio = size.height/actualHeight;
    actualWidth = oldRatio * actualWidth;
    actualHeight = size.height;
}
else
{
    oldRatio = size.width/actualWidth;
    actualHeight = oldRatio * actualHeight;
    actualWidth = size.width;
}

CGRect rect = CGRectMake(0.0,0.0,actualWidth,actualHeight);
UIGraphicsBeginImageContext(rect.size);
[orginalImage drawInRect:rect];
orginalImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return orginalImage;
 }

这是方法调用

 UIImage *compimage=[appdel resizeImage:imagemain resizeSize:CGSizeMake(40,40)];      

它返回该图像,您可以在任何地方显示该图像。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.