【问题标题】:convert from CGImageMetadata to nsdictionary从 CGImageMetadata 转换为 nsdictionary
【发布时间】:2017-03-08 10:07:27
【问题描述】:

我尝试将我的 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??

【问题讨论】:

  • 不清楚。我在你之前的问题上说过CGImageSourceCopyMetadataAtIndex 返回一个CGImageMetadataRef,它可以转换为NSArrayCGImageMetadataCopyTags。给出你想要的样本,因为将数组转换为字典,是否有意义?您不能将这样的事情转换为期望桥接会完成所有工作。
  • 谢谢,我现在明白了,我对返回的 CGImageMetadataRef 类型感到困惑,即 Nsarray。
  • 如果你想要一个字典,你可以做,但你可能必须手动做。我记录了NSArray,它们有很多相似的类型,可以重新组合:“exif”、“tiff”、“xmp”等,但我不知道如何转换它们,检索类似的类型kCGImageMetadataPrefixExif.
  • 我改变了这样的代码: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(来源); } NSLog(@"%@",metadataArray[12]);
  • 它向我展示了所有类似这样的标签行:GPano:PoseHeadingDegrees = 260。我只想获得 260 的值???

标签: ios metadata nsdictionary


【解决方案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
    }
}

【讨论】:

  • 只是想添加以确保标签是字典中的唯一键,您可能想要let cfPrefix = CGImageMetadataTagCopyPrefix(tagMetadata) 然后let name = String(cfPrefix) + "::" + String(cfName)
【解决方案2】:

我对@9​​87654322@ 了解不多。它充满了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 ( CFString)、NSArray ( CFArray)、NSDictionary ( CFDictionary),我查看了CFStringRef valueTypeStr = CFCopyTypeIDDescription(CFGetTypeID(value));(或者您也可以对相关问题进行“快速测试”:Determining what a CFTypeRef is?)。

这一切都是“手动”完成的,我很惊讶没有从 CGImageMetadataTagRef 转换为更“已知”的对象(而不是 struct),也许有,我没有阅读全文CGImageMetadata.h 的标头,因此可能有更快的方法,但我认为即使使用“老派”方法,通过挖掘也可能对其他有相关问题的用户有用,帮助他/她快速找到他/她正在寻找。

回答你最初的问题:CGImageMetadataNSDictionary,如果没有“简单转换”工具,并且使用“挖掘”方法,这将没有多大意义,因为有趣的方法@ 987654341@ 返回NSArray(或CFArray)。 但是由于很多 CGImageMetadataTagRef 前缀是相同的,您可能会感兴趣,手动执行以下字典: @{prefix1:@[stuff10, stuff11, etc.], prefix2:@[stuff20, stuff21, etc.]}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-17
    • 2011-10-24
    • 2010-11-27
    • 2013-09-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多