ios 如何调整 UIImage 的大小以减少上传图片的大小
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29137488/
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
How do I resize the UIImage to reduce upload image size
提问by Jay
I've been searching google, and have only come across libraries that either reduce the height/width or some how edit the UIImage appearance via CoreImage. But I have not seen or found one library, post that explains how to reduce image size so when it uploads, it's not the full image size.
我一直在搜索谷歌,并且只遇到过减少高度/宽度或一些如何通过 CoreImage 编辑 UIImage 外观的库。但是我还没有看到或找到一个库,它解释了如何减小图像大小,因此在上传时,它不是完整的图像大小。
so far I have this:
到目前为止,我有这个:
if image != nil {
//let data = NSData(data: UIImagePNGRepresentation(image))
let data = UIImagePNGRepresentation(image)
body.appendString("--\(boundary)\r\n")
body.appendString("Content-Disposition: form-data; name=\"image\"; filename=\"randomName\"\r\n")
body.appendString("Content-Type: image/png\r\n\r\n")
body.appendData(data)
body.appendString("\r\n")
}
and it's sending 12MB photos. How can I reduce this to 1mb? thanks!
它正在发送 12MB 的照片。我怎样才能将其减少到 1mb?谢谢!
回答by Leo Dabus
Xcode 9 ? Swift 4 or later
Xcode 9 ? Swift 4 或更高版本
edit/update: For iOS10+ We can use UIGraphicsImageRenderer. For older Swift syntax check edit history.
编辑/更新:对于 iOS10+ 我们可以使用UIGraphicsImageRenderer。对于较旧的 Swift 语法,请检查编辑历史记录。
extension UIImage {
func resized(withPercentage percentage: CGFloat, isOpaque: Bool = true) -> UIImage? {
let canvas = CGSize(width: size.width * percentage, height: size.height * percentage)
let format = imageRendererFormat
format.opaque = isOpaque
return UIGraphicsImageRenderer(size: canvas, format: format).image {
_ in draw(in: CGRect(origin: .zero, size: canvas))
}
}
func resized(toWidth width: CGFloat, isOpaque: Bool = true) -> UIImage? {
let canvas = CGSize(width: width, height: CGFloat(ceil(width/size.width * size.height)))
let format = imageRendererFormat
format.opaque = isOpaque
return UIGraphicsImageRenderer(size: canvas, format: format).image {
_ in draw(in: CGRect(origin: .zero, size: canvas))
}
}
}
Usage:
用法:
let image = UIImage(data: try! Data(contentsOf: URL(string:"http://i.stack.imgur.com/Xs4RX.jpg")!))!
let thumb1 = image.resized(withPercentage: 0.1)
let thumb2 = image.resized(toWidth: 72.0)
回答by user4261201
This is the way which i followed to resize image.
这是我调整图像大小所遵循的方式。
-(UIImage *)resizeImage:(UIImage *)image
{
float actualHeight = image.size.height;
float actualWidth = image.size.width;
float maxHeight = 300.0;
float maxWidth = 400.0;
float imgRatio = actualWidth/actualHeight;
float maxRatio = maxWidth/maxHeight;
float compressionQuality = 0.5;//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;
}
}
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];
}
Using this method my image having 6.5 MB reduced to 104 KB.
使用这种方法,我的 6.5 MB 图像减少到 104 KB。
Swift 4 code:
斯威夫特 4 代码:
func resize(_ image: UIImage) -> UIImage {
var actualHeight = Float(image.size.height)
var actualWidth = Float(image.size.width)
let maxHeight: Float = 300.0
let maxWidth: Float = 400.0
var imgRatio: Float = actualWidth / actualHeight
let maxRatio: Float = maxWidth / maxHeight
let compressionQuality: Float = 0.5
//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
}
}
let rect = CGRect(x: 0.0, y: 0.0, width: CGFloat(actualWidth), height: CGFloat(actualHeight))
UIGraphicsBeginImageContext(rect.size)
image.draw(in: rect)
let img = UIGraphicsGetImageFromCurrentImageContext()
let imageData = img?.jpegData(compressionQuality: CGFloat(compressionQuality))
UIGraphicsEndImageContext()
return UIImage(data: imageData!) ?? UIImage()
}
回答by Tung Fam
In case someone is looking for resizingimage to less than 1MBwith Swift 3 and 4.
如果有人正在寻找使用Swift 3 和 4 将图像大小调整到小于 1MB 的情况。
Just copy&pastethis extension:
只需复制并粘贴此扩展名:
extension UIImage {
func resized(withPercentage percentage: CGFloat) -> UIImage? {
let canvasSize = CGSize(width: size.width * percentage, height: size.height * percentage)
UIGraphicsBeginImageContextWithOptions(canvasSize, false, scale)
defer { UIGraphicsEndImageContext() }
draw(in: CGRect(origin: .zero, size: canvasSize))
return UIGraphicsGetImageFromCurrentImageContext()
}
func resizedTo1MB() -> UIImage? {
guard let imageData = UIImagePNGRepresentation(self) else { return nil }
var resizingImage = self
var imageSizeKB = Double(imageData.count) / 1000.0 // ! Or devide for 1024 if you need KB but not kB
while imageSizeKB > 1000 { // ! Or use 1024 if you need KB but not kB
guard let resizedImage = resizingImage.resized(withPercentage: 0.9),
let imageData = UIImagePNGRepresentation(resizedImage)
else { return nil }
resizingImage = resizedImage
imageSizeKB = Double(imageData.count) / 1000.0 // ! Or devide for 1024 if you need KB but not kB
}
return resizingImage
}
}
And use:
并使用:
let resizedImage = originalImage.resizedTo1MB()
Edit:Please note it's blocking UI, so move to background threadif you think it's the right way for your case.
编辑:请注意它会阻塞 UI,因此如果您认为它适合您的情况,请移至后台线程。
回答by Jagdeep
same as Leo Answer but little edits for SWIFT 2.0
与 Leo Answer 相同,但对 SWIFT 2.0 进行了少量编辑
extension UIImage {
func resizeWithPercentage(percentage: CGFloat) -> UIImage? {
let imageView = UIImageView(frame: CGRect(origin: .zero, size: CGSize(width: size.width * percentage, height: size.height * percentage)))
imageView.contentMode = .ScaleAspectFit
imageView.image = self
UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, false, scale)
guard let context = UIGraphicsGetCurrentContext() else { return nil }
imageView.layer.renderInContext(context)
guard let result = UIGraphicsGetImageFromCurrentImageContext() else { return nil }
UIGraphicsEndImageContext()
return result
}
func resizeWithWidth(width: CGFloat) -> UIImage? {
let imageView = UIImageView(frame: CGRect(origin: .zero, size: CGSize(width: width, height: CGFloat(ceil(width/size.width * size.height)))))
imageView.contentMode = .ScaleAspectFit
imageView.image = self
UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, false, scale)
guard let context = UIGraphicsGetCurrentContext() else { return nil }
imageView.layer.renderInContext(context)
guard let result = UIGraphicsGetImageFromCurrentImageContext() else { return nil }
UIGraphicsEndImageContext()
return result
}
}
回答by Jay
Here is user4261201's answer but in swift, that I am currently using:
这是 user4261201 的答案,但很快,我目前正在使用:
func compressImage (_ image: UIImage) -> UIImage {
let actualHeight:CGFloat = image.size.height
let actualWidth:CGFloat = image.size.width
let imgRatio:CGFloat = actualWidth/actualHeight
let maxWidth:CGFloat = 1024.0
let resizedHeight:CGFloat = maxWidth/imgRatio
let compressionQuality:CGFloat = 0.5
let rect:CGRect = CGRect(x: 0, y: 0, width: maxWidth, height: resizedHeight)
UIGraphicsBeginImageContext(rect.size)
image.draw(in: rect)
let img: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
let imageData:Data = UIImageJPEGRepresentation(img, compressionQuality)!
UIGraphicsEndImageContext()
return UIImage(data: imageData)!
}
回答by Maulik Patel
Swift4.2
斯威夫特4.2
let imagedata = yourImage.jpegData(compressionQuality: 0.1)!
回答by Bista
If you are uploading image in NSData
format, use this :
如果您以NSData
格式上传图像,请使用以下命令:
NSData *imageData = UIImageJPEGRepresentation(yourImage, floatValue);
yourImage
is your UIImage
.
floatvalue
is compression value(0.0 to 1.0)
yourImage
是你的UIImage
。
floatvalue
是压缩值(0.0 到 1.0)
The above is to convert image to JPEG
.
以上是将图像转换为JPEG
.
For PNG
use : UIImagePNGRepresentation
对于PNG
使用:UIImagePNGRepresentation
Note : Above code is in Objective-C. Please check how to define NSData in Swift.
注意:上面的代码是在 Objective-C 中的。请检查如何在 Swift 中定义 NSData。
回答by Kiran Dube
I think the easiest way is provided by swift itself to compress the image into compressed data below is the code in swift 4.2
我认为 swift 本身提供的最简单的方法是将图像压缩成压缩数据,下面是 swift 4.2 中的代码
let imageData = yourImageTobeCompressed.jpegData(compressionQuality: 0.5)
let imageData = yourImageTobeCompressed.jpegData(compressionQuality: 0.5)
and you can send this imageData to upload to server.
你可以发送这个 imageData 上传到服务器。
回答by Thomas Mary
Same in Objective-C :
在 Objective-C 中相同:
interface :
界面 :
@interface UIImage (Resize)
- (UIImage *)resizedWithPercentage:(CGFloat)percentage;
- (UIImage *)resizeTo:(CGFloat)weight isPng:(BOOL)isPng jpegCompressionQuality:(CGFloat)compressionQuality;
@end
implementation :
执行 :
#import "UIImage+Resize.h"
@implementation UIImage (Resize)
- (UIImage *)resizedWithPercentage:(CGFloat)percentage {
CGSize canvasSize = CGSizeMake(self.size.width * percentage, self.size.height * percentage);
UIGraphicsBeginImageContextWithOptions(canvasSize, false, self.scale);
[self drawInRect:CGRectMake(0, 0, canvasSize.width, canvasSize.height)];
UIImage *sizedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return sizedImage;
}
- (UIImage *)resizeTo:(CGFloat)weight isPng:(BOOL)isPng jpegCompressionQuality:(CGFloat)compressionQuality {
NSData *imageData = isPng ? UIImagePNGRepresentation(self) : UIImageJPEGRepresentation(self, compressionQuality);
if (imageData && [imageData length] > 0) {
UIImage *resizingImage = self;
double imageSizeKB = [imageData length] / weight;
while (imageSizeKB > weight) {
UIImage *resizedImage = [resizingImage resizedWithPercentage:0.9];
imageData = isPng ? UIImagePNGRepresentation(resizedImage) : UIImageJPEGRepresentation(resizedImage, compressionQuality);
resizingImage = resizedImage;
imageSizeKB = (double)(imageData.length / weight);
}
return resizingImage;
}
return nil;
}
Usage :
用法 :
#import "UIImage+Resize.h"
UIImage *resizedImage = [self.picture resizeTo:2048 isPng:NO jpegCompressionQuality:1.0];
回答by Bernard
When I try to use the accepted answer to resize an image for use in my project it comes out very pixelated and blurry. I ended up with this piece of code to resize images without adding pixelation or blur:
当我尝试使用公认的答案来调整我的项目中使用的图像大小时,它会非常像素化和模糊。我最终使用了这段代码来调整图像大小而不添加像素化或模糊:
func scale(withPercentage percentage: CGFloat)-> UIImage? {
let cgSize = CGSize(width: size.width * percentage, height: size.height * percentage)
let hasAlpha = true
let scale: CGFloat = 0.0 // Use scale factor of main screen
UIGraphicsBeginImageContextWithOptions(cgSize, !hasAlpha, scale)
self.draw(in: CGRect(origin: CGPoint.zero, size: cgSize))
let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
return scaledImage
}