Jak zmienić rozmiar interfejsu użytkownika, aby zmniejszyć rozmiar przesłanego obrazu

Szukałem w google i natknąłem się tylko na biblioteki, które albo zmniejszają wysokość/szerokość, albo edytują wygląd UIImage za pomocą CoreImage. Ale nie widziałem ani nie znalazłem jednej biblioteki, post, który wyjaśnia, jak zmniejszyć rozmiar obrazu, więc po przesłaniu nie jest to Pełny rozmiar obrazu.

Póki co mam to:

        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")
    }

I wysyła 12MB zdjęć. Jak mogę zredukować to do 1mb? dzięki!

 48
Author: Moritz, 2015-03-19

8 answers

Xcode 8.2.1 * Swift 3.0.2

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 resized(toWidth width: CGFloat) -> UIImage? {
        let canvasSize = CGSize(width: width, height: CGFloat(ceil(width/size.width * size.height)))
        UIGraphicsBeginImageContextWithOptions(canvasSize, false, scale)
        defer { UIGraphicsEndImageContext() }
        draw(in: CGRect(origin: .zero, size: canvasSize))
        return UIGraphicsGetImageFromCurrentImageContext()
    }
}

Użycie:

let myPicture = UIImage(data: try! Data(contentsOf: URL(string:"http://i.stack.imgur.com/Xs4RX.jpg")!))!

let myThumb1 = myPicture.resized(withPercentage: 0.1)
let myThumb2 = myPicture.resized(toWidth: 72.0)
 129
Author: Leo Dabus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-06 02:33:11

W ten sposób zmieniłem Rozmiar obrazu.

 -(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];

}

Przy użyciu tej metody mój obraz o 6,5 MB zmniejszył się do 104 KB.

Kod 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 = UIImageJPEGRepresentation(img!, CGFloat(compressionQuality))
    UIGraphicsEndImageContext()
    return UIImage(data: imageData!) ?? UIImage()
}
 55
Author: user4261201,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-30 04:47:26

W przypadku, gdy ktoś szuka zmiany rozmiaruna mniej niż 1MBza pomocą Swift 3 i 4.

Po Prostu Skopiuj i wklej to rozszerzenie:

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
}
}

I użycie:

let resizedImage = originalImage.resizedTo1MB()
 17
Author: Tung Fam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-15 21:55:29

To samo co Leo Answer ale małe edycje dla 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
    }
}
 13
Author: Jagdeep,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-26 08:41:15

Oto odpowiedź user4261201, ale w swifcie, którego obecnie używam:

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)!

}
 4
Author: Jay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-23 17:27:24

Jeśli przesyłasz obraz w formacie NSData, Użyj tego :

NSData *imageData = UIImageJPEGRepresentation(yourImage, floatValue);

yourImage jest Twoim UIImage. floatvalue jest wartością kompresji(0,0 do 1,0)

Powyżej jest konwersja obrazu do JPEG.

Dla PNGużycie: UIImagePNGRepresentation

Uwaga: powyższy kod znajduje się w Objective-C. Sprawdź jak zdefiniować NSData w języku Swift.

 2
Author: Bista,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-19 05:49:26

To jest to, co zrobiłem w swift 3 do zmiany rozmiaru interfejsu. Zmniejsza rozmiar obrazu do mniej niż 100KB. Działa proporcjonalnie!

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!
    }
}

Użycie:

let scaledImage = UIImage.scaleImageWithDivisor(img: capturedImage!, divisor: 3)
 0
Author: AKNinan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-06 09:47:56

Zmień rozmiar interfejsu Użytkownika za pomocą .resizeToMaximumBytes

 -1
Author: user3777906,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-25 19:44:49