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

Author: Community, 2013-03-06

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

 17
Author: Wes,
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];

    // ...
}
 21
Author: Taz,
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"];
 0
Author: Anil,
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