ios 压缩图像以减小文件大小
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18681990/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Compress images to reduce file size
提问by Juan González
I'm building an app that lets the user take a photo or select one from the library on the iPhone and upload it to the Parse backend.
我正在构建一个应用程序,允许用户拍照或从 iPhone 上的库中选择一张照片并将其上传到 Parse 后端。
The problem I'm facing is regarding to the size of the file.
我面临的问题与文件的大小有关。
I've read about what big players like Facebook, Twitter, Instagram, and Google do regarding resolution and file size but I can't get close to that.
我读过 Facebook、Twitter、Instagram 和 Google 等大公司在分辨率和文件大小方面的做法,但我无法接近这些。
I'm sure they have the best code and tools to do that but I'll be happy to implement it as good as possible with iOS regular processes.
我确信他们有最好的代码和工具来做到这一点,但我很乐意使用 iOS 常规流程尽可能好地实现它。
This is what I'm doing right now:
这就是我现在正在做的:
- (UIImage *)normalResImageForAsset:(ALAsset*)asset
{
// Convert ALAsset to UIImage
UIImage *image = [self highResImageForAsset:asset];
// Determine output size
CGFloat maxSize = 1024.0f;
CGFloat width = image.size.width;
CGFloat height = image.size.height;
CGFloat newWidth = width;
CGFloat newHeight = height;
// If any side exceeds the maximun size, reduce the greater side to 1200px and proportionately the other one
if (width > maxSize || height > maxSize) {
if (width > height) {
newWidth = maxSize;
newHeight = (height*maxSize)/width;
} else {
newHeight = maxSize;
newWidth = (width*maxSize)/height;
}
}
// Resize the image
CGSize newSize = CGSizeMake(newWidth, newHeight);
UIGraphicsBeginImageContext(newSize);
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// Set maximun compression in order to decrease file size and enable faster uploads & downloads
NSData *imageData = UIImageJPEGRepresentation(newImage, 0.0f);
UIImage *processedImage = [UIImage imageWithData:imageData];
return processedImage;
}
I'm trying to make 1024px the maximun allowed size (both with ot height) to start some restrictions there and then I'm applying maximun compression to reduce size.
我正在尝试将 1024px 设为最大允许大小(均具有 ot 高度)以在那里开始一些限制,然后我应用最大压缩来减小大小。
This works and cuts aproximately 50% of the image size without really damaging JPEGs but it's still a lot. Specially if photos are taken with the phone's camera and uploaded. The processed image can still easly have 1MB size which is way too much.
这有效并减少了大约 50% 的图像大小,而不会真正损坏 JPEG,但它仍然很多。特别是如果照片是用手机的相机拍摄并上传的。处理后的图像仍然很容易有 1MB 大小,这太多了。
I'm guessing that I could be missing some useful step or using the wrong technique.
我猜我可能会遗漏一些有用的步骤或使用错误的技术。
Any feedback would be greatly appreciated.
任何反馈将不胜感激。
回答by codemonkey
I had a similar problem and I also thought that the compression wasn't working. It turned out elsewhere in my code I was writing the file out to disk using different compression. You might be doing the same thing with the data this function returns. A good way to check that indeed the compression is effective is to do something like this:
我有一个类似的问题,我也认为压缩不起作用。结果在我的代码中的其他地方,我使用不同的压缩将文件写入磁盘。您可能会对这个函数返回的数据做同样的事情。检查压缩是否确实有效的一个好方法是执行以下操作:
NSData *imgData1 = UIImageJPEGRepresentation(newImage, 1.0f);
NSLog(@"1.0 size: %d", imgData1.length);
NSData *imgData2 = UIImageJPEGRepresentation(newImage, 0.7f);
NSLog(@"0.7 size: %d", imgData2.length);
NSData *imgData3 = UIImageJPEGRepresentation(newImage, 0.4f);
NSLog(@"0.4 size: %d", imgData3.length);
NSData *imgData4 = UIImageJPEGRepresentation(newImage, 0.0f);
NSLog(@"0.0 size: %d", imgData4.length);
// Don't convert NSData back to UIImage before writing to disk
[imgData4 writeToFile:imagePath atomically:YES];
I'm using an image that is 640x480 and I get file sizes ranging from 325 kB (for 1.0) down to 18 kB (for 0.0)
我使用的是 640x480 的图像,我得到的文件大小从 325 kB(对于 1.0)到 18 kB(对于 0.0)不等
回答by Shrawan
Swift-3 Version of @codeMonkey :-
@codeMonkey 的 Swift-3 版本:-
It work perfectin compression of image .
它在图像压缩方面工作完美。
func compressImage() -> UIImage {
let oldImage = UIImage(named: "background.jpg")
var imageData = Data(UIImagePNGRepresentation(oldImage!)! )
print("***** Uncompressed Size \(imageData.description) **** ")
imageData = UIImageJPEGRepresentation(oldImage!, 0.025)!
print("***** Compressed Size \(imageData.description) **** ")
let image = UIImage(data: imageData)
return image!
}
回答by herry.master
Please Try below answer.
+(UIImage *)compressImage:(UIImage *)image{
float actualHeight = image.size.height;
float actualWidth = image.size.width;
float maxHeight = 1136.0f;
float maxWidth = 640.0f;
float imgRatio = actualWidth/actualHeight;
float maxRatio = maxWidth/maxHeight;
float compressionQuality = 1;//50 percent compression
if (actualHeight > maxHeight || actualWidth > maxWidth){
if(imgRatio < maxRatio){
//adjust width according to maxHeight
imgRatio = maxHeight / actualHeight;
actualWidth = imgRatio * actualWidth;
actualHeight = maxHeight;
}
else if(imgRatio > maxRatio){
//adjust height according to maxWidth
imgRatio = maxWidth / actualWidth;
actualHeight = imgRatio * actualHeight;
actualWidth = maxWidth;
}
else{
actualHeight = maxHeight;
actualWidth = maxWidth;
}
}else{
actualHeight = maxHeight;
actualWidth = maxWidth;
compressionQuality = 1;
}
CGRect rect = CGRectMake(0.0, 0.0, actualWidth, actualHeight);
UIGraphicsBeginImageContext(rect.size);
[image drawInRect:rect];
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
NSData *imageData = UIImageJPEGRepresentation(img, compressionQuality);
UIGraphicsEndImageContext();
return [UIImage imageWithData:imageData];
}