web-dev-qa-db-fra.com

Quand dois-je utiliser UIImageJPEGRepresentation et UIImagePNGRepresentation pour télécharger différents formats d'image sur le serveur?

Dans mon application, je dois envoyer des images de différents formats au serveur (il doit s'agir de tous les formats de fichiers pouvant être lus par la classe UIImage) https://developer.Apple.com/library /ios/#documentation/uikit/reference/UIImage_Class/Reference/Reference.html

Et le problème est: je ne sais pas quand je devrais utiliser chacune de ces méthodes. Bien sûr, il est évident que pour .png images dont j'ai besoin pour utiliser UIImagePNGRepresentation et pour .jpg/.jpegUIImageJPEGRepresentation. Mais qu'en est-il des autres formats (.tiff, .gif , etc.)? Il n'y a que deux méthodes pour les manipulations d'images et autant de formats.

23

Vous dites:

Bien sûr, il est évident que pour les images .png, je dois utiliser UIImagePNGRepresentation et pour .jpg/.jpeg UIImageJPEGRepresentation.

Non, ce n'est pas nécessairement le cas. Si vous avez un "actif numérique" original, plutôt que de créer un UIImage puis d'utiliser l'une de ces deux fonctions pour créer le NSData que vous allez télécharger, vous n'aurez souvent qu'à charger le NSData de l'élément d'origine et contournez l'aller-retour vers un UIImage. Si vous procédez ainsi, vous ne risquez aucune perte de données que la conversion en UIImage, puis à nouveau, peut provoquer.

Il y a cependant quelques considérations supplémentaires:

  1. Métadonnées:

    Ces fonctions UIImageXXXRepresentation suppriment l'image de ses métadonnées. Parfois, c'est une bonne chose (par exemple, vous ne voulez pas télécharger des photos de vos enfants ou des gadgets coûteux, notamment les emplacements GPS où les mécontents pourraient identifier où la photo a été prise). Dans d'autres cas, vous ne voulez pas que les métadonnées soient jetées (par exemple, la date de la prise de vue originale, quelle caméra, etc.).

    Vous devez décider explicitement si vous souhaitez supprimer ou non les métadonnées. Si ce n'est pas le cas, ne faites pas aller-retour votre image via un UIImage, mais utilisez plutôt l'élément d'origine.

  2. Considérations relatives à la perte de qualité d'image et/ou à la taille du fichier:

    Je ne suis particulièrement pas fou de UIImageJPEGRepresentation car c'est un compression avec perte . Ainsi, si vous utilisez une valeur compressionQuality inférieure à 1,0, vous pouvez perdre une certaine qualité d'image (perte de qualité modeste pour des valeurs proches de 1,0, perte de qualité plus importante avec des valeurs compressionQuality plus faibles). Et si vous utilisez un compressionQuality de 1,0, vous atténuez une grande partie de la perte de qualité d'image JPEG, mais le NSData résultant peut souvent être plus grand que l'actif d'origine (au moins si l'original était lui-même , un JPEG ou PNG compressé), ce qui entraîne des téléchargements plus lents.

    UIImagePNGRepresentation n'introduit pas de perte de données basée sur la compression, mais selon l'image, vous pouvez toujours perdre des données (par exemple si le fichier d'origine était un TIFF 48 bits ou utilisait un espace colorimétrique autre que sRGB).

    Il s'agit de savoir si vous êtes d'accord avec une perte de qualité d'image et/ou une taille de fichier plus grande pendant le processus de téléchargement.

  3. Taille de l'image:

    Parfois, vous ne souhaitez pas télécharger l'image en pleine résolution. Par exemple, vous utilisez peut-être un service Web qui souhaite des images ne dépassant pas 800 pixels par côté. Ou si vous téléchargez une miniature, ils peuvent vouloir quelque chose d'encore plus petit (par exemple 32px x 32px). En redimensionnant les images, vous pouvez rendre le téléchargement beaucoup plus petit et donc beaucoup plus rapide (mais avec une perte de qualité évidente). Mais si vous utilisez un algorithme de redimensionnement d'image , la création d'un PNG ou JPEG à l'aide de ces fonctions UIImageXXXRepresentation serait assez courante.

En bref, si j'essaie de minimiser la perte de données/qualité, je téléchargerais l'actif d'origine s'il est dans un format accepté par le serveur, et j'utiliserais UIImagePNGRepresentation (ou UIImageJPGRepresentation avec un paramètre de qualité de 1,0) si l'élément d'origine n'était pas dans un format accepté par le serveur. Mais le choix d'utiliser ces fonctions UIImageXXXRepresentation est une question de vos besoins commerciaux et de ce que le serveur accepte.

50
Rob

Rob souligne beaucoup de très bonnes choses à considérer lors de l'utilisation d'images (+1), mais voici un exemple de la façon de créer des tiff et des gif comme vous l'avez demandé:

Tout d'abord, vous devez créer un lien vers la bibliothèque ImageIO (sous les phases de construction de votre application).

Ensuite, vous devez #import <ImageIO/ImageIO.h> en haut de votre fichier.

Ensuite, le code suivant convertira l'image pour vous:

// Get a reference to the image that you already have stored on disk somehow.
// If it isn't stored on disk, then you can use CGImageSourceCreateWithData() to create it from an NSData representation of your image.
NSURL *url = [[NSBundle mainBundle] URLForResource:@"01" withExtension:@"jpg"];
CGImageSourceRef src = CGImageSourceCreateWithURL((__bridge CFURLRef)(url), NULL);

// Create a URL referencing the Application Support Directory.  We will save the new image there.
NSFileManager *fm = [NSFileManager defaultManager];
NSURL *suppurl = [fm URLForDirectory:NSApplicationSupportDirectory
                            inDomain:NSUserDomainMask
                   appropriateForURL:nil
                              create:YES
                               error:NULL];

// Append the name of the output file to the app support directory
// For tiff change the extension in the next line to .tiff
NSURL *gifURL = [suppurl URLByAppendingPathComponent:@"mytiff.gif"];

// Create the destination for the new image
// For tiff, use @"public.tiff" for the second argument of the next line (instead of @com.compuserve.gif".
CGImageDestinationRef dest = CGImageDestinationCreateWithURL((__bridge CFURLRef)gifURL,
                                                             (CFStringRef)@"com.compuserve.gif",
                                                             1,
                                                             NULL);
CGImageDestinationAddImageFromSource(dest, src, 0, NULL);

// Write the image data to the URL.
bool ok = CGImageDestinationFinalize(dest);
if (!ok)
    NSLog(@"Unable to create gif file.");

// Cleanup
CFRelease(src);
CFRelease(dest);

Cela a été adapté du code dans ce livre .

2
lnafziger