从CGImageMetadata转换为nsdictionary

时间:2017-03-08 10:07:27

标签: ios metadata nsdictionary

我试图将我的360°元数据图像转换为nsdictionary。每当应用程序崩溃时,我试图打印属性的值。我写了这段代码

CGImageSourceRef source = CGImageSourceCreateWithData((__ bridge CFDataRef)imageData,NULL);     NSArray * metadataArray = nil;

if (source) {
    _metaData = CGImageSourceCopyMetadataAtIndex(source, 0, NULL);
    if (_metaData) {
        metadataArray = CFBridgingRelease(CGImageMetadataCopyTags(_metaData));
        CFRelease(_metaData);
    }
    CFRelease(source);
}

NSLog(@"%@",metadataArray[12]);//this is the problem

在输出中,我发现immutableMetadata的类型是CGImageMetadata而不是NSdictionary。我怎样才能转换为nsdictionary?

2 个答案:

答案 0 :(得分:1)

迅速

extension CGImageSource {

    func metadata() -> Dictionary<String, Any>? {

        guard let imageMetadata = CGImageSourceCopyMetadataAtIndex(self, 0, .none) else {
            return .none
        }

        guard let tags = CGImageMetadataCopyTags(imageMetadata) else {
            return .none
        }

        var result = [String: Any]()
        for tag in tags as NSArray {
            let tagMetadata = tag as! CGImageMetadataTag
            if let cfName = CGImageMetadataTagCopyName(tagMetadata) {
                let name = String(cfName)
                let value = CGImageMetadataTagCopyValue(tagMetadata)
                result[name] = value
            }
        }

        return result
    }
}

答案 1 :(得分:0)

我对ImageIO了解不多。它包含CF / CG个内容,可能导致__bridge次使用。

您只对某个值感兴趣,但如果有人正在寻找另一个值,则可以使用该示例代码/研究:
我查看CGImageMetadata.h每次使用与CGImageMetadataTagRef相关的函数时可能会有用。

CGImageSourceRef source = CGImageSourceCreateWithData((CFDataRef)imagedata, NULL);
CGImageMetadataRef imageMetadataRef = CGImageSourceCopyMetadataAtIndex(source, 0, NULL);
NSArray *metadata = CFBridgingRelease(CGImageMetadataCopyTags(imageMetadataRef));
NSLog(@"metadata = %@", metadata);

for (id aRef in metadata)
{
    CGImageMetadataTagRef currentRef = (__bridge CGImageMetadataTagRef)(aRef);
    NSLog(@"Ref: %@", currentRef);
    CGImageMetadataType type = CGImageMetadataTagGetType(currentRef);
    NSLog(@"Type: %d", type);
    CFStringRef nameSpace = CGImageMetadataTagCopyNamespace(currentRef);
    NSLog(@"NameSpace: %@", nameSpace);
    CFStringRef prefix = CGImageMetadataTagCopyPrefix(currentRef);
    NSLog(@"prefix: %@", prefix);
    CFStringRef name = CGImageMetadataTagCopyName(currentRef);
    NSLog(@"name: %@", name);
    CFTypeRef value = CGImageMetadataTagCopyValue(currentRef);
    NSLog(@"Value: %@", value);

    CFStringRef valueTypeStr =  CFCopyTypeIDDescription(CFGetTypeID(value));
    NSLog(@"valueTypeStr: %@", valueTypeStr);

    //Test related to question
    if ([@"GPano" isEqualToString:(__bridge NSString *)prefix] && [@"PoseHeadingDegrees" isEqualToString:(__bridge NSString *)name])
    {
        NSString *str = (__bridge NSString *)value;
        NSLog(@"Str: %@", str);
        NSLog(@"Int: %d", [str intValue]);
    }
}

要知道该值是否可转换为更“已知”的对象,例如NSString(&lt; =&gt; CFString),NSArray(&lt; =&gt; {{ 1}}),CFArray(&lt; =&gt; NSDictionary),我看了CFDictionary(或者您也可以使用相关问题进行“更快速的测试”:{{3} })。

全部“手动”完成,我很惊讶没有从CFStringRef valueTypeStr = CFCopyTypeIDDescription(CFGetTypeID(value));转换为更“已知”的对象(而不是CGImageMetadataTagRef),也许有,我没有'读了struct的整个标题,所以可能会有更快的方法,但我认为即使使用“老派”方法,通过挖掘也可能对另一位有相关问题的用户有用,帮助他/她快速找到他/她正在寻找的东西。

要回答您的初始问题:CGImageMetadata.hCGImageMetadata,如果没有“简单转换”工具,并且采用“挖掘”方法,则不会有多大意义,因为有趣的方法NSDictionary会返回CGImageMetadataCopyTags(或NSArray)。 但由于很多CFArray前缀相同,您可能会感兴趣,通过手动执行以下字典: CGImageMetadataTagRef