Save CUSTOM metadata in an image taken from AVFoundation in iOS

前端 未结 1 860
走了就别回头了
走了就别回头了 2020-12-23 23:59

How do I save custom metadata in an image when i get the image using the AVFoundation framework?

I know I can access the properties weather it I have my

相关标签:
1条回答
  • 2020-12-24 00:15

    UIImage and CIImage don't hold all the metadata. In fact, converting it from NSData to either of those two formats will strip a lot of that metadata out, so IMHO, UIImage and CIImage should only be used if you are planning on displaying it in the UI or passing it to CoreImage.

    You can read the image properties like this:

    - (NSDictionary *)getImageProperties:(NSData *)imageData {
        // get the original image metadata
        CGImageSourceRef imageSourceRef = CGImageSourceCreateWithData((__bridge CFDataRef) imageData, NULL);
        CFDictionaryRef properties = CGImageSourceCopyPropertiesAtIndex(imageSourceRef, 0, NULL);
        NSDictionary *props = (__bridge_transfer NSDictionary *) properties;
        CFRelease(imageSourceRef);
    
        return props;
    }
    

    You can then convert your NSDictionary to a NSMutableDictionary:

    NSDictionary *props = [self getImageProperties:imageData];
    NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionaryWithDictionary:props];
    

    After that, add whatever fields you would like. Note that EXIF data is found by grabbing the kCGImagePropertyExifDictionary, GPS data by the kCGImagePropertyGPSDictionary, and so on:

    NSMutableDictionary *exifDictionary = properties[(__bridge NSString *) kCGImagePropertyExifDictionary];
    

    Look at the CGImageProperties header file for all the keys available.

    Okay, so now that you have made whatever changes you needed to the metadata, adding it back takes a couple of more steps:

    // incoming image data
    NSData *imageData;
    
    // create the image ref
    CGDataProviderRef imgDataProvider = CGDataProviderCreateWithCFData((__bridge CFDataRef) imageData);
    CGImageRef imageRef = CGImageCreateWithJPEGDataProvider(imgDataProvider, NULL, true, kCGRenderingIntentDefault);
    
    // the updated properties from above
    NSMutableDictionary *mutableDictionary;
    
    // create the new output data
    CFMutableDataRef newImageData = CFDataCreateMutable(NULL, 0);
    // my code assumes JPEG type since the input is from the iOS device camera
    CFStringRef type = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, (__bridge CFStringRef) @"image/jpg", kUTTypeImage);
    // create the destination
    CGImageDestinationRef destination = CGImageDestinationCreateWithData(newImageData, type, 1, NULL);
    // add the image to the destination
    CGImageDestinationAddImage(destination, imageRef, (__bridge CFDictionaryRef) mutableDictionary);
    // finalize the write
    CGImageDestinationFinalize(destination);
    
    // memory cleanup
    CGDataProviderRelease(imgDataProvider);
    CGImageRelease(imageRef);
    CFRelease(type);
    CFRelease(destination);
    
    // your new image data
    NSData *newImage = (__bridge_transfer NSData *)newImageData;
    

    And there you have it.

    0 讨论(0)
提交回复
热议问题