私はグーグルを検索してきましたが、高さ/幅を縮小するか、CoreImage経由でUIImageの外観を編集するライブラリを見つけました。しかし、画像のサイズを縮小する方法を説明する投稿を1つのライブラリで見たり見つけたりしていないため、アップロード時に画像のフルサイズではありません。
これまでのところ私はこれを持っています:
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")
}
12MBの写真を送信しています。これを1 MBに減らすにはどうすればよいですか?ありがとう!
Xcode 9•Swift 4以降
編集/更新:iOS10以降の場合 IGraphicsImageRenderer を使用できます。古いSwift構文チェックの編集履歴。
extension UIImage {
func resized(withPercentage percentage: CGFloat) -> UIImage? {
let canvas = CGSize(width: size.width * percentage, height: size.height * percentage)
return UIGraphicsImageRenderer(size: canvas, format: imageRendererFormat).image {
_ in draw(in: CGRect(Origin: .zero, size: canvas))
}
}
func resized(toWidth width: CGFloat) -> UIImage? {
let canvas = CGSize(width: width, height: CGFloat(ceil(width/size.width * size.height)))
return UIGraphicsImageRenderer(size: canvas, format: imageRendererFormat).image {
_ in draw(in: CGRect(Origin: .zero, size: canvas))
}
}
}
使用法:
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)
これは、画像のサイズを変更するために従った方法です。
-(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];
}
この方法を使用すると、6.5 MBのイメージが104 KBに削減されます。
Swift 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()
}
誰かがサイズ変更を探している場合1MB未満でSwift 3および4を使用します。
ちょうどcopy&pasteこの拡張機能:
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
}
}
そしてse:
let resizedImage = originalImage.resizedTo1MB()
編集:これはブロッキングUIであることに注意してください。したがって、あなたのケースに適していると思われる場合はバックグラウンドスレッドに移動してください。
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
}
}
ここにuser4261201の答えがありますが、Swiftでは、私は現在使用しています:
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)!
}
Swift4.2
let imagedata = yourImage.jpegData(compressionQuality: 0.1)!
NSData
形式で画像をアップロードする場合、これを使用します:
NSData *imageData = UIImageJPEGRepresentation(yourImage, floatValue);
yourImage
はあなたのUIImage
です。 floatvalue
は圧縮値(0.0〜1.0)です。
上記は、画像をJPEG
に変換します。
PNG
useの場合:UIImagePNGRepresentation
注:上記のコードはObjective-Cにあります。 SwiftでNSDataを定義する方法を確認してください。
Tung Famの回答に基づきます。特定のファイルサイズにサイズを変更するには。 0.7 MBのように、このコードを使用できます。
extension UIImage {
func resize(withPercentage percentage: CGFloat) -> UIImage? {
var newRect = CGRect(Origin: .zero, size: CGSize(width: size.width*percentage, height: size.height*percentage))
UIGraphicsBeginImageContextWithOptions(newRect.size, true, 1)
self.draw(in: newRect)
defer {UIGraphicsEndImageContext()}
return UIGraphicsGetImageFromCurrentImageContext()
}
func resizeTo(MB: Double) -> UIImage? {
guard let fileSize = self.pngData()?.count else {return nil}
let fileSizeInMB = CGFloat(fileSize)/(1024.0*1024.0)//form bytes to MB
let percentage = 1/fileSizeInMB
return resize(withPercentage: percentage)
}
}
これは、UIImageのサイズを変更するためにSwift 3で行ったことです。画像サイズを100kb未満に縮小します。それは比例して動作します!
extension UIImage {
class func scaleImageWithDivisor(img: UIImage, divisor: CGFloat) -> UIImage {
let size = CGSize(width: img.size.width/divisor, height: img.size.height/divisor)
UIGraphicsBeginImageContext(size)
img.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return scaledImage!
}
}
使用法:
let scaledImage = UIImage.scaleImageWithDivisor(img: capturedImage!, divisor: 3)
Swiftによって提供される最も簡単な方法は、画像を以下の圧縮データに圧縮することです。Swift 4.2のコード
let imageData = yourImageTobeCompressed.jpegData(compressionQuality: 0.5)
このimageDataを送信してサーバーにアップロードできます。
extension UIImage {
func resized(toValue value: CGFloat) -> UIImage {
if size.width > size.height {
return self.resize(toWidth: value)!
} else {
return self.resize(toHeight: value)!
}
}
Objective-Cでも同じです:
インターフェース:
@interface UIImage (Resize)
- (UIImage *)resizedWithPercentage:(CGFloat)percentage;
- (UIImage *)resizeTo:(CGFloat)weight isPng:(BOOL)isPng jpegCompressionQuality:(CGFloat)compressionQuality;
@end
実装:
#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;
}
使用法 :
#import "UIImage+Resize.h"
UIImage *resizedImage = [self.picture resizeTo:2048 isPng:NO jpegCompressionQuality:1.0];
受け入れられた答えを使用して、プロジェクトで使用する画像のサイズを変更しようとすると、非常にピクセル化されてぼやけてしまいます。ピクセル化やブラーを追加せずに画像のサイズを変更する次のコードになりました。
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
}
これを使用して、必要なサイズを制御できます。
func jpegImage(image: UIImage, maxSize: Int, minSize: Int, times: Int) -> Data? {
var maxQuality: CGFloat = 1.0
var minQuality: CGFloat = 0.0
var bestData: Data?
for _ in 1...times {
let thisQuality = (maxQuality + minQuality) / 2
guard let data = image.jpegData(compressionQuality: thisQuality) else { return nil }
let thisSize = data.count
if thisSize > maxSize {
maxQuality = thisQuality
} else {
minQuality = thisQuality
bestData = data
if thisSize > minSize {
return bestData
}
}
}
return bestData
}
メソッド呼び出しの例:
jpegImage(image: image, maxSize: 500000, minSize: 400000, times: 10)
MaxSizeとminSizeの最大サイズと最小サイズの間でファイルを取得しようとしますが、試行回数だけです。その時間内に失敗すると、nilを返します。