Bagaimana cara mudah mengubah ukuran / mengoptimalkan ukuran gambar dengan iOS?

114

Aplikasi saya mengunduh sekumpulan file gambar dari jaringan, dan menyimpannya ke disk iPhone lokal. Beberapa dari gambar tersebut berukuran cukup besar (lebarnya lebih dari 500 piksel, misalnya). Karena iPhone bahkan tidak memiliki layar yang cukup besar untuk menampilkan gambar dalam ukuran aslinya, saya berencana mengubah ukuran gambar menjadi sesuatu yang sedikit lebih kecil untuk menghemat ruang / kinerja.

Selain itu, beberapa gambar tersebut adalah JPEG dan tidak disimpan seperti pengaturan kualitas 60% biasanya.

Bagaimana saya bisa mengubah ukuran gambar dengan iPhone SDK, dan bagaimana saya bisa mengubah pengaturan kualitas gambar JPEG?

jpm
sumber

Jawaban:

246

Beberapa saran diberikan sebagai jawaban atas pertanyaan ini . Saya telah menyarankan teknik yang dijelaskan dalam posting ini , dengan kode yang relevan:

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

   return newImage;
}

Untuk penyimpanan gambar, format gambar tercepat yang digunakan dengan iPhone adalah PNG, karena memiliki pengoptimalan untuk format tersebut. Namun, jika Anda ingin menyimpan gambar ini sebagai JPEG, Anda dapat mengambil gambar UII Anda dan melakukan hal berikut:

NSData *dataForJPEGFile = UIImageJPEGRepresentation(theImage, 0.6);

Ini membuat instance NSData yang berisi byte mentah untuk gambar JPEG dengan pengaturan kualitas 60%. Konten dari instance NSData tersebut kemudian dapat ditulis ke disk atau di-cache di memori.

Brad Larson
sumber
1
Pak ... saya menulis logika yang sama tetapi satu garis lurus putih akan muncul (potret) di sisi kanan tolong beri saya solusi
Nag_iphone
1
Hai, bagaimana kita menangani menjaga rasio aspek dan klip terikat saat mengubah ukuran? Dalam kasus saya, saat saya mengubah ukuran gambar yang memiliki rasio berbeda kemudian "ukuran baru", saya mendapatkan gambar yang diubah ukurannya. Terima kasih!
Van Du Tran
1
Ini telah berfungsi di masa lalu, tetapi di iOS5.0.1 dan yang lebih baru, hal ini menyebabkan kebocoran memori. Adakah cara lain untuk mencapai ini?
Usman Nisar
Rekomendasikan menggunakan [image drawInRect: rect blendMode: kCGBlendModeCopy alpha: 1.0] untuk meningkatkan kinerja (jadi gambar tidak harus melakukan penghitungan pencampuran selama menggambar
cdemiris99
Anda harus menggunakan UIGraphicsBeginImageContextWithOptions (size, NO, 0.0); di mana 0.0 akan menggunakan skala layar utama untuk mendukung retina dan di atasnya. Apple menyatakan "Anda sebaiknya menghindari pemanggilan fungsi UIGraphicsBeginImageContext yang memiliki nama serupa (kecuali sebagai pengganti untuk kompatibilitas mundur)".
Brad Goss
65

Cara termudah dan paling mudah untuk mengubah ukuran gambar Anda adalah ini

float actualHeight = image.size.height;
float actualWidth = image.size.width;
float imgRatio = actualWidth/actualHeight;
float maxRatio = 320.0/480.0;

if(imgRatio!=maxRatio){
    if(imgRatio < maxRatio){
        imgRatio = 480.0 / actualHeight;
        actualWidth = imgRatio * actualWidth;
        actualHeight = 480.0;
    }
    else{
        imgRatio = 320.0 / actualWidth;
        actualHeight = imgRatio * actualHeight;
        actualWidth = 320.0;
    }
}
CGRect rect = CGRectMake(0.0, 0.0, actualWidth, actualHeight);
UIGraphicsBeginImageContext(rect.size);
[image drawInRect:rect];
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
lostInTransit
sumber
Ini indah. Saya dapat memangkas gambar yang dikirim ke server dari sekitar 1Mb hingga 100k sambil tetap mempertahankan resolusi layar retina (meskipun saya mengubah nilai 320.0 dan 480.0 menjadi 640.0 dan 1136.0) dan juga melakukan beberapa kompresi JPEG setelah penskalaan: UIImageJPEGRepresentation (img, 0.7f);
Keller
2
Bagaimana jika rasio gambar dan rasio maks ternyata sama? Misalnya, apakah ukuran iamge adalah 3200x4800?
akshay1188
Ini telah berfungsi di masa lalu, tetapi di iOS5.0.1 dan yang lebih baru, hal ini menyebabkan kebocoran memori. Adakah cara lain untuk mencapai ini?
Usman Nisar
25

Metode di atas berfungsi dengan baik untuk gambar kecil, tetapi ketika Anda mencoba mengubah ukuran gambar yang sangat besar, Anda akan segera kehabisan memori dan merusak aplikasi. Cara yang jauh lebih baik adalah menggunakan CGImageSourceCreateThumbnailAtIndexuntuk mengubah ukuran gambar tanpa mendekodekannya sepenuhnya terlebih dahulu.

Jika Anda memiliki jalur ke gambar yang ingin Anda ubah ukurannya, Anda dapat menggunakan ini:

- (void)resizeImageAtPath:(NSString *)imagePath {
    // Create the image source (from path)
    CGImageSourceRef src = CGImageSourceCreateWithURL((__bridge CFURLRef) [NSURL fileURLWithPath:imagePath], NULL);

    // To create image source from UIImage, use this
    // NSData* pngData =  UIImagePNGRepresentation(image);
    // CGImageSourceRef src = CGImageSourceCreateWithData((CFDataRef)pngData, NULL);

    // Create thumbnail options
    CFDictionaryRef options = (__bridge CFDictionaryRef) @{
            (id) kCGImageSourceCreateThumbnailWithTransform : @YES,
            (id) kCGImageSourceCreateThumbnailFromImageAlways : @YES,
            (id) kCGImageSourceThumbnailMaxPixelSize : @(640)
    };
    // Generate the thumbnail
    CGImageRef thumbnail = CGImageSourceCreateThumbnailAtIndex(src, 0, options); 
    CFRelease(src);
    // Write the thumbnail at path
    CGImageWriteToFile(thumbnail, imagePath);
}

Lebih lengkapnya di sini .

Pulkit Goyal
sumber
Terima kasih, solusi ini bekerja dengan sangat baik), Apakah Anda tahu format file lain yang mendukung CGImageSourceselain gambar dan pdf?
sage444
Terima kasih. Saya mencari analog inSampleSizeyang digunakan oleh decoder Android. Dan ini adalah satu-satunya jawaban yang memberikan cara untuk memperkecil gambar dengan cara yang efisien dalam memori.
Stan Mots
Saya mendapatkan hasil yang bagus dengan ini bekerja secara langsung dengan file dalam penyimpanan, juga bekerja dengan gambar dalam memori tetapi tidak secepat (untuk memuat dalam gambar besar ke UIImage kemudian skala).
Kendall Helmstetter Gelner
Tidak berfungsi di ekstensi berbagi. Aplikasi masih mogok dengan gambar yang sangat besar.
George
18

Cara terbaik untuk menskalakan gambar tanpa kehilangan rasio aspek (yaitu tanpa meregangkan gambar) adalah dengan menggunakan metode ini:

//to scale images without changing aspect ratio
+ (UIImage *)scaleImage:(UIImage *)image toSize:(CGSize)newSize {

    float width = newSize.width;
    float height = newSize.height;

    UIGraphicsBeginImageContext(newSize);
    CGRect rect = CGRectMake(0, 0, width, height);

    float widthRatio = image.size.width / width;
    float heightRatio = image.size.height / height;
    float divisor = widthRatio > heightRatio ? widthRatio : heightRatio;

    width = image.size.width / divisor;
    height = image.size.height / divisor;

    rect.size.width  = width;
    rect.size.height = height;

    //indent in case of width or height difference
    float offset = (width - height) / 2;
    if (offset > 0) {
        rect.origin.y = offset;
    }
    else {
        rect.origin.x = -offset;
    }

    [image drawInRect: rect];

    UIImage *smallImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return smallImage;

}

Tambahkan metode ini ke kelas Utility Anda sehingga Anda dapat menggunakannya di seluruh proyek Anda, dan mengaksesnya seperti ini:

xyzImageView.image = [Utility scaleImage:yourUIImage toSize:xyzImageView.frame.size];

Metode ini menangani penskalaan sambil mempertahankan rasio aspek. Ini juga menambahkan indentasi ke gambar jika gambar yang diperkecil memiliki lebar lebih dari tinggi (atau sebaliknya).

codeburn
sumber
8

Jika Anda memiliki kendali atas server, saya sangat menyarankan mengubah ukuran sisi server gambar dengan ImageMagik . Mendownload gambar berukuran besar dan mengubah ukurannya di ponsel akan membuang banyak sumber daya berharga - bandwidth, baterai, dan memori. Semuanya langka di ponsel.

Rog
sumber
2
FTFQ: "Aplikasi saya mengunduh sekumpulan file gambar dari jaringan,"
Rog
Ini bisa menjadi jawaban yang relevan. Pertanyaannya menyatakan bahwa gambar sedang diunduh dari jaringan. Jika OP dapat bekerja dengan sisi server gambar, dia harus. Jika dia tidak bisa, jawaban akan lebih membantu.
Joshua Dance
6

Saya mengembangkan solusi pamungkas untuk penskalaan gambar di Swift.

Anda dapat menggunakannya untuk mengubah ukuran gambar untuk diisi, mengisi aspek, atau menyesuaikan aspek ukuran yang ditentukan.

Anda dapat meratakan gambar ke tengah atau salah satu dari empat tepi dan empat sudut.

Dan juga Anda dapat memangkas ruang ekstra yang ditambahkan jika rasio aspek gambar asli dan ukuran target tidak sama.

enum UIImageAlignment {
    case Center, Left, Top, Right, Bottom, TopLeft, BottomRight, BottomLeft, TopRight
}

enum UIImageScaleMode {
    case Fill,
    AspectFill,
    AspectFit(UIImageAlignment)
}

extension UIImage {
    func scaleImage(width width: CGFloat? = nil, height: CGFloat? = nil, scaleMode: UIImageScaleMode = .AspectFit(.Center), trim: Bool = false) -> UIImage {
        let preWidthScale = width.map { $0 / size.width }
        let preHeightScale = height.map { $0 / size.height }
        var widthScale = preWidthScale ?? preHeightScale ?? 1
        var heightScale = preHeightScale ?? widthScale
        switch scaleMode {
        case .AspectFit(_):
            let scale = min(widthScale, heightScale)
            widthScale = scale
            heightScale = scale
        case .AspectFill:
            let scale = max(widthScale, heightScale)
            widthScale = scale
            heightScale = scale
        default:
            break
        }
        let newWidth = size.width * widthScale
        let newHeight = size.height * heightScale
        let canvasWidth = trim ? newWidth : (width ?? newWidth)
        let canvasHeight = trim ? newHeight : (height ?? newHeight)
        UIGraphicsBeginImageContextWithOptions(CGSizeMake(canvasWidth, canvasHeight), false, 0)

        var originX: CGFloat = 0
        var originY: CGFloat = 0
        switch scaleMode {
        case .AspectFit(let alignment):
            switch alignment {
            case .Center:
                originX = (canvasWidth - newWidth) / 2
                originY = (canvasHeight - newHeight) / 2
            case .Top:
                originX = (canvasWidth - newWidth) / 2
            case .Left:
                originY = (canvasHeight - newHeight) / 2
            case .Bottom:
                originX = (canvasWidth - newWidth) / 2
                originY = canvasHeight - newHeight
            case .Right:
                originX = canvasWidth - newWidth
                originY = (canvasHeight - newHeight) / 2
            case .TopLeft:
                break
            case .TopRight:
                originX = canvasWidth - newWidth
            case .BottomLeft:
                originY = canvasHeight - newHeight
            case .BottomRight:
                originX = canvasWidth - newWidth
                originY = canvasHeight - newHeight
            }
        default:
            break
        }
        self.drawInRect(CGRectMake(originX, originY, newWidth, newHeight))
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }
}

Ada contoh penerapan solusi ini di bawah.

Persegi panjang abu-abu adalah gambar situs target yang akan diubah ukurannya menjadi. Lingkaran biru dalam persegi panjang biru muda adalah gambarnya (saya menggunakan lingkaran karena mudah dilihat saat diskalakan tanpa mempertahankan aspek). Warna oranye terang menandai area yang akan dipangkas jika Anda lewat trim: true.

Aspek pas sebelum dan sesudah penskalaan:

Aspek fit 1 (sebelum) Aspek fit 1 (setelah)

Contoh lain dari aspek kesesuaian :

Aspek fit 2 (sebelum) Aspek fit 2 (setelah)

Aspek pas dengan perataan atas:

Aspek fit 3 (sebelum) Aspek pas 3 (setelah)

Isi aspek :

Aspek isi (sebelum) Pengisian aspek (setelah)

Isi :

Isi (sebelum) Isi (setelah)

Saya menggunakan upscaling dalam contoh saya karena lebih mudah untuk didemonstrasikan tetapi solusi juga berfungsi untuk downscaling seperti yang dipermasalahkan.

Untuk kompresi JPEG Anda harus menggunakan ini:

let compressionQuality: CGFloat = 0.75 // adjust to change JPEG quality
if let data = UIImageJPEGRepresentation(image, compressionQuality) {
  // ...
}

Anda dapat melihat inti saya dengan taman bermain Xcode.

mixel
sumber
3

Untuk Swift 3, kode di bawah menskalakan gambar dengan mempertahankan rasio aspek. Anda dapat membaca lebih lanjut tentang ImageContext di dokumentasi Apple :

extension UIImage {
    class func resizeImage(image: UIImage, newHeight: CGFloat) -> UIImage {
        let scale = newHeight / image.size.height
        let newWidth = image.size.width * scale
        UIGraphicsBeginImageContext(CGSize(width: newWidth, height: newHeight))
        image.draw(in: CGRect(x: 0, y: 0, width: newWidth, height: newHeight))
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return newImage!
    }
}

Untuk menggunakannya, panggil resizeImage()metode:

UIImage.resizeImage(image: yourImageName, newHeight: yourImageNewHeight)
Alexandre Lara
sumber
2

Anda dapat menggunakan kode ini untuk menskalakan gambar dalam ukuran yang dibutuhkan.

+ (UIImage *)scaleImage:(UIImage *)image toSize:(CGSize)newSize
{
    CGSize actSize = image.size;
    float scale = actSize.width/actSize.height;

    if (scale < 1) {
        newSize.height = newSize.width/scale;
    } 
    else {
        newSize.width = newSize.height*scale;
    }

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

    return newImage;
}
Amit Shelgaonkar
sumber
2

Menurut sesi ini, iOS Memory Deep Dive , kami sebaiknya menggunakanImageIO gambar yang diperkecil.

UIImageBuruknya menggunakan gambar downscale.

  • Akan mendekompresi gambar asli ke dalam memori
  • Transformasi ruang koordinat internal mahal

Menggunakan ImageIO

  • ImageIO dapat membaca ukuran gambar dan informasi metadata tanpa mengotori memori.

  • ImageIO dapat mengubah ukuran gambar hanya dengan biaya gambar yang diubah ukurannya.

Tentang Gambar di memori

  • Penggunaan memori terkait dengan dimensi gambar, bukan ukuran file.
  • UIGraphicsBeginImageContextWithOptionsselalu menggunakan SRGBformat rendering, yang menggunakan 4 byte per piksel.
  • Gambar memiliki load -> decode -> render3 fase.
  • UIImage mahal untuk ukuran dan ukuran

Untuk gambar berikut, jika menggunakan UIGraphicsBeginImageContextWithOptions kita hanya perlu 590KB untuk memuat gambar, sedangkan kita membutuhkan 2048 pixels x 1536 pixels x 4 bytes per pixel= 10MB saat decoding masukkan deskripsi gambar di sini

sementara UIGraphicsImageRenderer, diperkenalkan di iOS 10, secara otomatis akan memilih format grafik terbaik di iOS12. Artinya, Anda dapat menghemat 75% memori dengan menggantinya UIGraphicsBeginImageContextWithOptionsdengan UIGraphicsImageRendererjika Anda tidak membutuhkan SRGB.

Ini adalah artikel saya tentang gambar iOS di memori

func resize(url: NSURL, maxPixelSize: Int) -> CGImage? {
    let imgSource = CGImageSourceCreateWithURL(url, nil)
    guard let imageSource = imgSource else {
        return nil
    }

    var scaledImage: CGImage?
    let options: [NSString: Any] = [
            // The maximum width and height in pixels of a thumbnail.
            kCGImageSourceThumbnailMaxPixelSize: maxPixelSize,
            kCGImageSourceCreateThumbnailFromImageAlways: true,
            // Should include kCGImageSourceCreateThumbnailWithTransform: true in the options dictionary. Otherwise, the image result will appear rotated when an image is taken from camera in the portrait orientation.
            kCGImageSourceCreateThumbnailWithTransform: true
    ]
    scaledImage = CGImageSourceCreateThumbnailAtIndex(imageSource, 0, options as CFDictionary)

    return scaledImage
}


let filePath = Bundle.main.path(forResource:"large_leaves_70mp", ofType: "jpg")

let url = NSURL(fileURLWithPath: filePath ?? "")

let image = resize(url: url, maxPixelSize: 600)

atau

// Downsampling large images for display at smaller size
func downsample(imageAt imageURL: URL, to pointSize: CGSize, scale: CGFloat) -> UIImage {
    let imageSourceOptions = [kCGImageSourceShouldCache: false] as CFDictionary
    let imageSource = CGImageSourceCreateWithURL(imageURL as CFURL, imageSourceOptions)!
    let maxDimensionInPixels = max(pointSize.width, pointSize.height) * scale
    let downsampleOptions =
        [kCGImageSourceCreateThumbnailFromImageAlways: true,
        kCGImageSourceShouldCacheImmediately: true,
        // Should include kCGImageSourceCreateThumbnailWithTransform: true in the options dictionary. Otherwise, the image result will appear rotated when an image is taken from camera in the portrait orientation.
        kCGImageSourceCreateThumbnailWithTransform: true,
        kCGImageSourceThumbnailMaxPixelSize: maxDimensionInPixels] as CFDictionary
    let downsampledImage =
        CGImageSourceCreateThumbnailAtIndex(imageSource, 0, downsampleOptions)!
    return UIImage(cgImage: downsampledImage)
}
RY Zheng
sumber
1

Masalah yang mungkin terjadi pada tampilan retina adalah skala gambar diatur oleh ImageCapture atau lebih. Fungsi pengubahan ukuran di atas tidak akan mengubahnya. Dalam kasus ini, pengubahan ukuran tidak akan berfungsi dengan benar.

Pada kode di bawah ini, skala diatur ke 1 (tidak diskalakan) dan gambar yang dikembalikan memiliki ukuran yang Anda harapkan. Ini dilakukan dalam UIGraphicsBeginImageContextWithOptionspanggilan.

-(UIImage *)resizeImage :(UIImage *)theImage :(CGSize)theNewSize {
    UIGraphicsBeginImageContextWithOptions(theNewSize, NO, 1.0);
    [theImage drawInRect:CGRectMake(0, 0, theNewSize.width, theNewSize.height)];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;
}
Vincent
sumber
1

Menambah banyak jawaban di sini, tetapi saya telah mencari solusi yang mengubah ukuran berdasarkan ukuran file, daripada dimensi.

Ini akan mengurangi dimensi dan kualitas gambar hingga mencapai ukuran yang Anda tetapkan.

func compressTo(toSizeInMB size: Double) -> UIImage? {
    let bytes = size * 1024 * 1024
    let sizeInBytes = Int(bytes)
    var needCompress:Bool = true
    var imgData:Data?
    var compressingValue:CGFloat = 1.0

    while (needCompress) {

        if let resizedImage = scaleImage(byMultiplicationFactorOf: compressingValue), let data: Data = UIImageJPEGRepresentation(resizedImage, compressingValue) {

            if data.count < sizeInBytes || compressingValue < 0.1 {
                needCompress = false
                imgData = data
            } else {
                compressingValue -= 0.1
            }
        }
    }

    if let data = imgData {
        print("Finished with compression value of: \(compressingValue)")
        return UIImage(data: data)
    }
    return nil
}

private func scaleImage(byMultiplicationFactorOf factor: CGFloat) -> UIImage? {
    let size = CGSize(width: self.size.width*factor, height: self.size.height*factor)
    UIGraphicsBeginImageContext(size)
    draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
    if let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext() {
        UIGraphicsEndImageContext()
        return newImage;
    }
    return nil
}

Kredit untuk skala berdasarkan jawaban ukuran

Harry Bloom
sumber
1

Versi Swift

func resizeImage(image: UIImage, newWidth: CGFloat) -> UIImage? {

    let scale = newWidth / image.size.width
    let newHeight = CGFloat(200.0)
    UIGraphicsBeginImageContext(CGSize(width: newWidth, height: newHeight))
    image.draw(in: CGRect(x: 0, y: 0, width: newWidth, height: newHeight))

    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    return newImage
}
Softlabsindia
sumber
0

Saya akhirnya menggunakan teknik Brads untuk membuat scaleToFitWidthmetode UIImage+Extensionsjika itu berguna bagi siapa pun ...

-(UIImage *)scaleToFitWidth:(CGFloat)width
{
    CGFloat ratio = width / self.size.width;
    CGFloat height = self.size.height * ratio;

    NSLog(@"W:%f H:%f",width,height);

    UIGraphicsBeginImageContext(CGSizeMake(width, height));
    [self drawInRect:CGRectMake(0.0f,0.0f,width,height)];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return newImage;
}

lalu dimanapun Anda suka

#import "UIImage+Extensions.h"

UIImage *newImage = [image scaleToFitWidth:100.0f];

Juga perlu dicatat, Anda dapat memindahkan ini lebih jauh ke dalam UIView+Extensionskelas jika Anda ingin merender gambar dari UIView

Magoo
sumber
0

Saya hanya ingin menjawab pertanyaan itu untuk programmer Cocoa Swift. Fungsi ini mengembalikan NSImage dengan ukuran baru. Anda dapat menggunakan fungsi itu seperti ini.

        let sizeChangedImage = changeImageSize(image, ratio: 2)






 // changes image size

    func changeImageSize (image: NSImage, ratio: CGFloat) -> NSImage   {

    // getting the current image size
    let w = image.size.width
    let h = image.size.height

    // calculating new size
    let w_new = w / ratio 
    let h_new = h / ratio 

    // creating size constant
    let newSize = CGSizeMake(w_new ,h_new)

    //creating rect
    let rect  = NSMakeRect(0, 0, w_new, h_new)

    // creating a image context with new size
    let newImage = NSImage.init(size:newSize)



    newImage.lockFocus()

        // drawing image with new size in context
        image.drawInRect(rect)

    newImage.unlockFocus()


    return newImage

}
Berharap
sumber
0

Jika gambar Anda ada di direktori dokumen, Tambahkan ekstensi URL ini :

extension URL {
    func compressedImageURL(quality: CGFloat = 0.3) throws -> URL? {
        let imageData = try Data(contentsOf: self)
        debugPrint("Image file size before compression: \(imageData.count) bytes")

        let compressedURL = NSURL.fileURL(withPath: NSTemporaryDirectory() + NSUUID().uuidString + ".jpg")

        guard let actualImage = UIImage(data: imageData) else { return nil }
        guard let compressedImageData = UIImageJPEGRepresentation(actualImage, quality) else {
            return nil
        }
        debugPrint("Image file size after compression: \(compressedImageData.count) bytes")

        do {
            try compressedImageData.write(to: compressedURL)
            return compressedURL
        } catch {
            return nil
        }
    }
}

Pemakaian:

guard let localImageURL = URL(string: "< LocalImagePath.jpg >") else {
    return
}

//Here you will get URL of compressed image
guard let compressedImageURL = try localImageURL.compressedImageURL() else {
    return
}

debugPrint("compressedImageURL: \(compressedImageURL.absoluteString)")

Catatan: - Ubah <LocalImagePath.jpg> dengan jalur gambar jpg lokal Anda.

Mohammad Zaid Pathan
sumber
-1

Jika ada yang masih mencari opsi yang lebih baik

-(UIImage *)scaleImage:(UIImage *)image toSize:(CGSize)targetSize {


    UIImage *sourceImage = image;
    UIImage *newImage = nil;

    CGSize imageSize = sourceImage.size;
    CGFloat width = imageSize.width;
    CGFloat height = imageSize.height;

    CGFloat targetWidth = targetSize.width;
    CGFloat targetHeight = targetSize.height;

    CGFloat scaleFactor = 0.0;
    CGFloat scaledWidth = targetWidth;
    CGFloat scaledHeight = targetHeight;

    CGPoint thumbnailPoint = CGPointMake(0.0,0.0);

    if (CGSizeEqualToSize(imageSize, targetSize) == NO) {

        CGFloat widthFactor = targetWidth / width;
        CGFloat heightFactor = targetHeight / height;

        if (widthFactor < heightFactor)
            scaleFactor = widthFactor;
        else
            scaleFactor = heightFactor;

        scaledWidth  = width * scaleFactor;
        scaledHeight = height * scaleFactor;

        // center the image


        if (widthFactor < heightFactor) {
            thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;
        } else if (widthFactor > heightFactor) {
            thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
        }
    }


    // this is actually the interesting part:

    UIGraphicsBeginImageContext(targetSize);

    CGRect thumbnailRect = CGRectZero;
    thumbnailRect.origin = thumbnailPoint;
    thumbnailRect.size.width  = scaledWidth;
    thumbnailRect.size.height = scaledHeight;

    [sourceImage drawInRect:thumbnailRect];

    newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    if(newImage == nil) NSLog(@"could not scale image");


    return newImage ;

}
Seema Sharma
sumber
-1
- (UIImage *)resizeImage:(UIImage*)image newSize:(CGSize)newSize {
    CGRect newRect = CGRectIntegral(CGRectMake(0, 0, newSize.width, newSize.height));
    CGImageRef imageRef = image.CGImage;

    UIGraphicsBeginImageContextWithOptions(newSize, NO, 0);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
    CGAffineTransform flipVertical = CGAffineTransformMake(1, 0, 0, -1, 0, newSize.height);

    CGContextConcatCTM(context, flipVertical);
    CGContextDrawImage(context, newRect, imageRef);

    CGImageRef newImageRef = CGBitmapContextCreateImage(context);
    UIImage *newImage = [UIImage imageWithCGImage:newImageRef];

    CGImageRelease(newImageRef);
    UIGraphicsEndImageContext();

    return newImage;
}
backbencher
sumber
Harap berikan setidaknya beberapa penjelasan tentang kode dalam jawaban Anda. Dan juga format kode menggunakan editor jawaban agar dapat dibaca.
xpereta
-2

Untuk mengubah ukuran gambar, saya memiliki hasil (grafis) yang lebih baik dengan menggunakan fungsi ini sebagai ganti DrawInRect:

- (UIImage*) reduceImageSize:(UIImage*) pImage newwidth:(float) pWidth
{
    float lScale = pWidth / pImage.size.width;
    CGImageRef cgImage = pImage.CGImage;
    UIImage   *lResult = [UIImage imageWithCGImage:cgImage scale:lScale
                            orientation:UIImageOrientationRight];
    return lResult;
}

Rasio aspek ditangani secara otomatis

Jebu
sumber