Konwertuj UIImage na NSData bez użycia UIImagePngrepresentation lub UIImageJpegRepresentation
Muszę przekonwertować UIImage
Na NSData
ale bez użycia UIImagePngRepresentation
lub UIImageJpegRepresentation
, dla obrazów z photolib mogę użyć metody assetlib, jak wspomniano tutaj używając ALAssetsLibrary i ALAsset wyjmij obraz jako NSData, ale dla przechwyconego obrazu , Asset url nie ma stąd w takim przypadku muszę przekonwertować UIImage
bezpośrednio do bajtów z danymi exif , Jak mogę to osiągnąć ? proszę o pomoc
3 answers
H Bastan,
Na podstawie Twojego komentarza:
...Chcę zapisać przechwycony obraz zwracany przez aparat urządzenia, za pomocą metody UIImagepicker delegate w katalogu dokumentu...
Wygląda na to, że Twoim prawdziwym celem jest zapisanie obrazu z danymi EXIF do katalogu documents, a nie uzyskanie interfejsu użytkownika jako obiektu NSData z danymi EXIF. W takim przypadku możesz wykonać następujące czynności w swojej implementacji 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);
From my testy czas wykonania był mniej więcej taki sam lub szybszy niż wykonanie:
NSData *data = UIImageJPEGRepresentation(capturedImage, 1.0);
[data writeToURL:outputURL atomically:YES];
...i możesz zachować dane EXIF!
Możesz również wysłać go do kolejki w tle, jeśli chcesz mieć pewność, że twój interfejs będzie responsywny:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
// Do the image saving here...
});
Ważna uwaga: będziesz musiał dodać ImageIO.framework
i MobileCoreServices.framework
do faz budowania celu i zaimportować je do klasy, w której robisz zapis obrazu:
#import <ImageIO/ImageIO.h>
#import <MobileCoreServices/MobileCoreServices.h>
Inne uwagi Rozumiem, że w tym przypadku nie generujemy straty generacji podczas zapisywania obrazu, jak zaproponowano w przykładzie. Używamy właściwości Cgimage UIImage i zgodnie z dokumentacją:
Podstawowe dane obrazu kwarcowego
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
2013-04-07 04:46:41
Miałem podobny problem, ale ze względów bezpieczeństwa nie chciałem zapisywać danych do domyślnego systemu plików, jak sugerował Wes. Chciałem też mieć możliwość dodawania metadanych do mojego obrazu. Moje rozwiązanie było następujące:
- (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;
}
Aby go użyć, wykonaj następujące czynności:
- (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];
// ...
}
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
2013-09-19 10:40:49
Możesz spróbować czegoś takiego. Nie wiem, czy to najlepsza metoda. Ale warto spróbować. Okryj adres URL obrazu jest dostępny, możesz spróbować initWithContentsOfUrl
NSData *data = [[NSData alloc]initWithContentsOfFile:@"/Users/test/isajf/isajf/test.jpg"];
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
2013-03-06 09:32:07