2013-03-04 7 views
12

में पीएनजी छवियों के लिए कस्टम मेटाडेटा कैसे लिखें, मेरा आवेदन यूआईपीएस्टबोर्ड पर निर्यात के लिए पीएनजी छवियों में कस्टम मेटाडेटा प्रविष्टियां लिखने में सक्षम होना चाहिए।आईओएस

विषय पर विभिन्न पदों को एक साथ जोड़कर, मैं स्रोत के रूप में नीचे दिए गए वर्ग के साथ आने में सक्षम हूं।

एक बटन के साथ copyPressed विधि ट्रिगर, मैं जेपीजी छवियों के साथ कस्टम मेटाडाटा (EXIF) सेट करने में सक्षम हूँ:

Image[6101:907] found jpg exif dictionary 
Image[6101:907] checking image metadata on clipboard 
Image[6101:907] { 
    ColorModel = RGB; 
    Depth = 8; 
    Orientation = 1; 
    PixelHeight = 224; 
    PixelWidth = 240; 
    "{Exif}" =  { 
     ColorSpace = 1; 
     PixelXDimension = 240; 
     PixelYDimension = 224; 
     UserComment = "Here is a comment"; 
    }; 
    "{JFIF}" =  { 
     DensityUnit = 0; 
     JFIFVersion =   (
      1, 
      1 
     ); 
     XDensity = 1; 
     YDensity = 1; 
    }; 
    "{TIFF}" =  { 
     Orientation = 1; 
    }; 
} 

हालांकि मैं पीएनजी मेटाडाटा ठीक पढ़ने में सक्षम हूँ, मैं कर सकते हैं ' इसे लिखने के लिए लग रहे हैं:

Image[6116:907] found png property dictionary 
Image[6116:907] checking image metadata on clipboard 
Image[6116:907] { 
    ColorModel = RGB; 
    Depth = 8; 
    PixelHeight = 224; 
    PixelWidth = 240; 
    "{PNG}" =  { 
     InterlaceType = 0; 
    }; 
} 

हालांकि, दस्तावेज में कुछ भी नहीं पता चलता है यह असफल चाहिए और कई PNG-specific metadata constants की उपस्थिति चलता है कि यह सफल होने चाहिए।

JPG's lossy compression से बचने के लिए मेरे एप्लिकेशन को पीएनजी का उपयोग करना चाहिए।

मैं आईओएस में इन-मेमोरी पीएनजी छवि पर कस्टम मेटाडेटा क्यों सेट नहीं कर सकता?

नोट: मैंने this SO question देखा है, लेकिन यह समस्या को हल नहीं करता है, जो विशेष रूप से पीएनजी छवियों को मेटाडेटा लिखने का तरीका है।

IMViewController.m

#import "IMViewController.h" 
#import <ImageIO/ImageIO.h> 

@interface IMViewController() 

@end 

@implementation IMViewController 

- (IBAction)copyPressed:(id)sender 
{ 
// [self copyJPG]; 
    [self copyPNG]; 
} 

-(void)copyPNG 
{ 
    NSData *pngData = UIImagePNGRepresentation([UIImage imageNamed:@"wow.png"]); 
    CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)pngData, NULL); 
    NSDictionary *metadata = (__bridge NSDictionary *) CGImageSourceCopyPropertiesAtIndex(source, 0, NULL); 
    NSMutableDictionary *mutableMetadata = [metadata mutableCopy]; 
    NSMutableDictionary *dict = [[mutableMetadata objectForKey:(NSString *) kCGImagePropertyPNGDictionary] mutableCopy]; 

    if (dict) { 
     NSLog(@"found png property dictionary"); 
    } else { 
     NSLog(@"creating png property dictionary"); 
     dict = [NSMutableDictionary dictionary]; 
    } 

    // set values on the root dictionary 
    [mutableMetadata setObject:@"Name of Software" forKey:(NSString *)kCGImagePropertyPNGDescription]; 
    [mutableMetadata setObject:dict forKey:(NSString *)kCGImagePropertyPNGDictionary]; 

    // set values on the internal dictionary 
    [dict setObject:@"works" forKey:(NSString *)kCGImagePropertyPNGDescription]; 

    CFStringRef UTI = CGImageSourceGetType(source); 
    NSMutableData *data = [NSMutableData data]; 
    CGImageDestinationRef destination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef) data, UTI, 1, NULL); 

    if (!destination) { 
     NSLog(@">>> Could not create image destination <<<"); 

     return; 
    } 

    CGImageDestinationAddImageFromSource(destination, source, 0, (__bridge CFDictionaryRef) mutableMetadata); 

    BOOL success = CGImageDestinationFinalize(destination); 

    if (!success) { 
     NSLog(@">>> Error Writing Data <<<"); 
    } 

    UIPasteboard *pasteboard = [UIPasteboard generalPasteboard]; 

    [pasteboard setData:data forPasteboardType:@"public.png"]; 
    [self showPNGMetadata]; 
} 

-(void)copyJPG 
{ 
    NSData *jpgData = UIImageJPEGRepresentation([UIImage imageNamed:@"wow.jpg"], 1); 
    CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef) jpgData, NULL); 
    NSDictionary *metadata = (__bridge NSDictionary *) CGImageSourceCopyPropertiesAtIndex(source, 0, NULL); 
    NSMutableDictionary *mutableMetadata = [metadata mutableCopy]; 
    NSMutableDictionary *exif = [[mutableMetadata objectForKey:(NSString *)kCGImagePropertyExifDictionary] mutableCopy]; 

    if (exif) { 
     NSLog(@"found jpg exif dictionary"); 
    } else { 
     NSLog(@"creating jpg exif dictionary"); 
    } 

    // set values on the exif dictionary 
    [exif setObject:@"Here is a comment" forKey:(NSString *)kCGImagePropertyExifUserComment]; 
    [mutableMetadata setObject:exif forKey:(NSString *)kCGImagePropertyExifDictionary]; 

    CFStringRef UTI = CGImageSourceGetType(source); 
    NSMutableData *data = [NSMutableData data]; 
    CGImageDestinationRef destination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef) data, UTI, 1, NULL); 

    if(!destination) { 
     NSLog(@">>> Could not create image destination <<<"); 

     return; 
    } 

    CGImageDestinationAddImageFromSource(destination,source, 0, (__bridge CFDictionaryRef) mutableMetadata); 

    BOOL success = CGImageDestinationFinalize(destination); 

    if (!success) { 
     NSLog(@">>> Could not create data from image destination <<<"); 
    } 

    UIPasteboard *pasteboard = [UIPasteboard generalPasteboard]; 

    [pasteboard setData:data forPasteboardType:@"public.jpeg"]; 
    [self showJPGMetadata]; 
} 

-(void)showJPGMetadata 
{ 
    NSLog(@"checking image metadata on clipboard"); 

    UIPasteboard *pasteboard = [UIPasteboard generalPasteboard]; 
    NSData *data = [pasteboard dataForPasteboardType:@"public.jpeg"]; 

    CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL); 
    NSDictionary *metadata = (__bridge NSDictionary *) CGImageSourceCopyPropertiesAtIndex(source,0,NULL); 

    NSLog(@"%@", metadata); 
} 

-(void)showPNGMetadata 
{ 
    NSLog(@"checking image metadata on clipboard"); 

    UIPasteboard *pasteboard = [UIPasteboard generalPasteboard]; 
    NSData *data = [pasteboard dataForPasteboardType:@"public.png"]; 

    CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL); 
    NSDictionary *metadata = (__bridge NSDictionary *) CGImageSourceCopyPropertiesAtIndex(source,0,NULL); 

    NSLog(@"%@", metadata); 
} 

@end 

उत्तर

4

आप संशोधित मेटाडाटा

[data writeToFile:[NSTemporaryDirectory() stringByAppendingPathComponent:@"test.png"] 
     atomically:YES]; 

साथ अपनी छवि को बचाने के लिए और से खोजक में यह गुण देखने की कोशिश करेंगे। आप देखेंगे कि kCGImagePropertyPNGDescription फ़ील्ड सफलतापूर्वक सेट अप किया गया था।

enter image description here

लेकिन अगर आप इस नई फ़ाइल के मेटाडाटा पढ़ा कोशिश करेंगे, kCGImagePropertyPNGDescription खो जाएगा।

ColorModel = RGB; 
Depth = 8; 
PixelHeight = 1136; 
PixelWidth = 640; 
"{PNG}" =  { 
    InterlaceType = 0; 
}; 

कुछ शोध के बाद मैंने पाया कि पीएनजी में मेटाडेटा नहीं है। लेकिन इसमें XMP metadata हो सकता है। हालांकि ImageIO एक्सएमपी के साथ काम नहीं करता है।
शायद आप ImageMagic या libexif का उपयोग करने का प्रयास कर सकते हैं।

उपयोगी लिंक्स:
PNG Specification
Reading/Writing image XMP on iPhone/Objective-c
Does PNG support metadata fields like Author, Camera Model, etc?
Does PNG contain EXIF data like JPG?
libexif.sourceforge.net

+0

यह जानना अच्छा है। स्पष्ट रूप से आईओएस मेरी विधि का उपयोग कर फाइलों से पीएनजी मेटाडेटा नहीं पढ़ सकता है। अगर मेरे पास पीएनजी मेटाडेटा पढ़ने का कोई तरीका है, तो मेरे पास समाधान हो सकता है। दिए गए आईओएस में kCGImagePropertyPNGDescription जैसे स्थिरांक हैं, मैं बाहरी पुस्तकालयों का उपयोग नहीं करना चाहूंगा और यह जानना चाहूंगा कि वास्तव में आईओएस libs के साथ वास्तव में ऐसा कैसे करें। –

+0

कल्पना कीजिए कि आप छवि में मेटाडेटा जोड़ सकते हैं, क्या आप सुनिश्चित हैं कि अन्य सॉफ़्टवेयर इस जानकारी को पढ़ेगा? किस कारण से आप मेटाडेटा जोड़ना चाहते हैं? –

+0

क्या आपको कोई जवाब मिला? – Crashalot