Convertir UIImage en NSData sans utiliser Uiimagepngreprésentation ou Uiimagejpegreprésentation
je dois convertir UIImage
en NSData
mais sans utiliser UIImagePngRepresentation
ou UIImageJpegRepresentation
, pour les images de photolib je peux utiliser la méthode assetlib comme mentionné ici en utilisant ALAssetsLibrary et ALAsset prendre L'Image comme NSData , mais pour l'image capturée , l'url assset n'est pas là donc dans ce cas , je dois convertir UIImage
directement en octets avec exif data, comment puis-je accomplir cela ? s'il vous plaît aider
3 réponses
H Bastan,
basé sur votre commentaire:
...Je veux sauver le retour d'image capturé par appareil photo, par la méthode uiimagepicker delegate dans le répertoire de document...
il ressemble à votre réel objectif est de sauver l'image avec des données EXIF au répertoire de documents et de ne pas spécifiquement obtenir L'UIImage comme un objet NSData avec les données EXIF. Dans ce cas, vous pouvez faire ce qui suit dans votre mise en œuvre de imagePickerController:didFinishPickingMediaWithInfo:
// Get your image.
UIImage *capturedImage = [info objectForKey:UIImagePickerControllerOriginalImage];
// Get your metadata (includes the EXIF data).
NSDictionary *metadata = [info objectForKey:UIImagePickerControllerMediaMetadata];
// Create your file URL.
NSFileManager *defaultManager = [NSFileManager defaultManager];
NSURL *docsURL = [[defaultManager URLsForDirectory:NSDocumentDirectory
inDomains:NSUserDomainMask] lastObject];
NSURL *outputURL = [docsURL URLByAppendingPathComponent:@"imageWithEXIFData.jpg"];
// Set your compression quuality (0.0 to 1.0).
NSMutableDictionary *mutableMetadata = [metadata mutableCopy];
[mutableMetadata setObject:@(1.0) forKey:(__bridge NSString *)kCGImageDestinationLossyCompressionQuality];
// Create an image destination.
CGImageDestinationRef imageDestination = CGImageDestinationCreateWithURL((__bridge CFURLRef)outputURL, kUTTypeJPEG , 1, NULL);
if (imageDestination == NULL ) {
// Handle failure.
NSLog(@"Error -> failed to create image destination.");
return;
}
// Add your image to the destination.
CGImageDestinationAddImage(imageDestination, capturedImage.CGImage, (__bridge CFDictionaryRef)mutableMetadata);
// Finalize the destination.
if (CGImageDestinationFinalize(imageDestination) == NO) {
// Handle failure.
NSLog(@"Error -> failed to finalize the image.");
}
CFRelease(imageDestination);
D'après mes tests, le temps d'exécution était à peu près le même ou plus rapide que le temps d'exécution:
NSData *data = UIImageJPEGRepresentation(capturedImage, 1.0);
[data writeToURL:outputURL atomically:YES];
...et tu peux garder les données D'EXIF!
vous pouvez également l'envoyer dans une file d'attente en arrière-plan si vous voulez vous assurer que votre interface reste réactive:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
// Do the image saving here...
});
Note importante: vous aurez besoin de ajoutez le ImageIO.framework
et le MobileCoreServices.framework
aux phases de construction de votre cible et importez - les dans la classe où vous effectuez la sauvegarde d'image:
#import <ImageIO/ImageIO.h>
#import <MobileCoreServices/MobileCoreServices.h>
autres notes Je crois comprendre que dans ce cas, nous ne créons pas une perte de génération lorsque nous sauvegardons l'image telle que proposée dans l'exemple. Nous utilisons la propriété CGImage D'UIImage et comme la documentation l'indique:
les données D'image de Quartz sous-jacentes
j'ai eu un problème similaire, mais pour des raisons de SÉCURITÉ Je ne voulais pas écrire les données dans le système de fichiers par défaut comme suggéré par Wes. Je voulais aussi pouvoir ajouter des métadonnées à mon image. Ma solution était la suivante:
- (NSData *)dataFromImage:(UIImage *)image metadata:(NSDictionary *)metadata mimetype:(NSString *)mimetype
{
NSMutableData *imageData = [NSMutableData data];
CFStringRef uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, (__bridge CFStringRef)mimetype, NULL);
CGImageDestinationRef imageDestination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)imageData, uti, 1, NULL);
if (imageDestination == NULL)
{
NSLog(@"Failed to create image destination");
imageData = nil;
}
else
{
CGImageDestinationAddImage(imageDestination, image.CGImage, (__bridge CFDictionaryRef)metadata);
if (CGImageDestinationFinalize(imageDestination) == NO)
{
NSLog(@"Failed to finalise");
imageData = nil;
}
CFRelease(imageDestination);
}
CFRelease(uti);
return imageData;
}
pour l'utiliser, vous feriez ce qui suit:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
NSDictionary *metadata = [info objectForKey:UIImagePickerControllerMediaMetadata];
NSString *mimeType = @"image/jpeg"; // ideally this would be dynamically set. Not defaulted to a jpeg!
// you could add to the metadata dictionary (after converting it to a mutable copy) if you needed to.
// convert to NSData
NSData *imageData = [self dataFromImage:image metadata:metadata mimetype:mimeType];
// ...
}
Vous pouvez essayer quelque chose comme cela. Vous ne savez pas si c'est la meilleure méthode. Mais vaut le coup. Incase L'URL de l'image est disponible, vous pouvez essayer initWithContentsOfUrl
NSData *data = [[NSData alloc]initWithContentsOfFile:@"/Users/test/isajf/isajf/test.jpg"];