web-dev-qa-db-fra.com

Comment compresser/redimensionner une image sur le SDK iPhone OS avant de l'envoyer sur un serveur?

Je télécharge actuellement une image sur un serveur utilisant Imgur sur iOS avec le code suivant:

NSData* imageData = UIImagePNGRepresentation(image);
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* fullPathToFile = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"SBTempImage.png"];
[imageData writeToFile:fullPathToFile atomically:NO];

[uploadRequest setFile:fullPathToFile forKey:@"image"];

Le code fonctionne correctement lorsqu'il est exécuté dans le simulateur et lors du téléchargement d'un fichier à partir de la photothèque du simulateur, car je dispose d'une connexion Ethernet rapide. Cependant, le même code a expiré sur l'iPhone lors de la sélection d'une image prise avec l'iPhone. Donc, j'ai essayé en sauvegardant une petite image du Web et en essayant de la télécharger, ce qui a fonctionné.

Cela me porte à croire que les grandes images prises par l'iPhone arrivent à échéance sur le réseau 3G un peu lent. Est-il possible de compresser/redimensionner l'image de l'iPhone avant de l'envoyer?

Merci!

75
joshholat

Cet extrait redimensionnera l'image:

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

La variable newSize est une CGSize et peut être définie comme suit:

CGSize newSize = CGSizeMake(100.0f, 100.0f);
201
Tuan Nguyen

Une solution autonome:

- (UIImage *)compressForUpload:(UIImage *)original scale:(CGFloat)scale
{
    // Calculate new size given scale factor.
    CGSize originalSize = original.size;
    CGSize newSize = CGSizeMake(originalSize.width * scale, originalSize.height * scale);

    // Scale the original image to match the new size.
    UIGraphicsBeginImageContext(newSize);
    [original drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
    UIImage *compressedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return compressedImage;
}

Merci à @Tuan Nguyen.

38
Zorayr

Pour compléter @Tuan Nguyen, c’est peut-être le moyen le plus rapide et le plus élégant de le faire.

Pour créer un lien vers le message de John Muchow sur iphonedevelopertips.com , ajouter une catégorie à un UIImage est un moyen très pratique de faire évoluer très rapidement . 

    UIImage *_image = [[[UIImage alloc] initWithData:SOME_NSDATA] scaleToSize:CGSizeMake(640.0,480.0)];

vous renvoie une image de représentation 640x480 de votre NSDATA (qui pourrait être une image en ligne) sans autre ligne de code.

16
nembleton

Matt Gemmell's MGImageUtilities sont très gentils, redimensionnant efficacement et avec quelques méthodes permettant de réduire les efforts.

7
Matthew Frederick

Dans ce code, 0,5 signifie 50% ...

UIImage *original = image;
UIImage *compressedImage = UIImageJPEGRepresentation(original, 0.5f);
6
Jagandeep Singh

utiliser cette méthode simple NSData *data = UIImageJPEGRepresentation(chosenImage, 0.2f);

4
user3732709

Implémentation rapide de la fonction de Zorayr (avec un léger changement pour inclure des contraintes de hauteur ou de largeur par unités réelles et non à l'échelle):

class func compressForUpload(original:UIImage, withHeightLimit heightLimit:CGFloat, andWidthLimit widthLimit:CGFloat)->UIImage{

    let originalSize = original.size
    var newSize = originalSize

    if originalSize.width > widthLimit && originalSize.width > originalSize.height {

        newSize.width = widthLimit
        newSize.height = originalSize.height*(widthLimit/originalSize.width)
    }else if originalSize.height > heightLimit && originalSize.height > originalSize.width {

        newSize.height = heightLimit
        newSize.width = originalSize.width*(heightLimit/originalSize.height)
    }

    // Scale the original image to match the new size.
    UIGraphicsBeginImageContext(newSize)
    original.drawInRect(CGRectMake(0, 0, newSize.width, newSize.height))
    let compressedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return compressedImage
}
3
PJeremyMalouf
#import <ImageIO/ImageIO.h>
#import <MobileCoreServices/MobileCoreServices.h>

+ (UIImage *)resizeImage:(UIImage *)image toResolution:(int)resolution {
NSData *imageData = UIImagePNGRepresentation(image);
CGImageSourceRef src = CGImageSourceCreateWithData((__bridge CFDataRef)imageData, NULL);
CFDictionaryRef options = (__bridge CFDictionaryRef) @{
                                                       (id) kCGImageSourceCreateThumbnailWithTransform : @YES,
                                                       (id) kCGImageSourceCreateThumbnailFromImageAlways : @YES,
                                                       (id) kCGImageSourceThumbnailMaxPixelSize : @(resolution)
                                                       };
CGImageRef thumbnail = CGImageSourceCreateThumbnailAtIndex(src, 0, options);
CFRelease(src);
UIImage *img = [[UIImage alloc]initWithCGImage:thumbnail];
return img;
}
0
Vineet Ravi
UIImage *image = [UIImage imageNamed:@"image.png"];
NSData *imgData1 = UIImageJPEGRepresentation(image, 1);
NSLog(@"Original --- Size of Image(bytes):%d",[imgData1 length]);

NSData *imgData2 = UIImageJPEGRepresentation(image, 0.5);
NSLog(@"After --- Size of Image(bytes):%d",[imgData2 length]);
image = [UIImage imageWithData:imgData2];
imgTest.image = image;

essayez de convertir JPG en utilisant un facteur d'échelle. Ici, je me sers de 0.5En mon cas:

0
Swatee Salunkhe

Version Swift 2.0 de la méthode Jagandeep Singh mais nécessité de convertir les données en image car NSData? n'est pas converti automatiquement UIImage.

let orginalImage:UIImage = image

let compressedData = UIImageJPEGRepresentation(orginalImage, 0.5)
let compressedImage = UIImage(data: compressedData!)
0
CodeOverRide
NsData *data=UiImageJPEGRepresentation(Img.image,0.2f);
0
iOS Lifee