【问题标题】:How to convert base64 image embedded in XML to UIImage?如何将嵌入在 XML 中的 base64 图像转换为 UIImage?
【发布时间】:2017-09-02 09:04:00
【问题描述】:

如何将嵌入在 XML 中的 base64 数据(如下图所示)转换为 UIImage?

【问题讨论】:

    标签: ios xml swift uiimage base64


    【解决方案1】:

    首先您需要解析 XML。在 iOS 上没有 NSXML,因此您需要使用 NSXMLParser,它是一个原始的事件驱动回调解析器(与您可以在 macOS 中使用的复杂树解析器相对)。

    让我们定义一些示例数据:

    let xmlString =
        "<base64Binary xmlns=\"TestTestTest\">"
        + "/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAA0JCgsKCA0LCgsODg0PEyAVExIS"
        + "EyccHhcgLikxMC4pLSwzOko+MzZGNywtQFdBRkxOUlNSMj5aYVpQYEpRUk//"
        + "2wBDAQ4ODhMREyYVFSZPNS01T09PT09PT09PT09PT09PT09PT09PT09PT09P"
        + "T09PT09PT09PT09PT09PT09PT09PT0//wAARCABAABwDASIAAhEBAxEB/8QA"
        + "GgAAAgMBAQAAAAAAAAAAAAAAAwUCBAYAAf/EACwQAAIBAwMCBAUFAAAAAAAA"
        + "AAECAwAEEQUSITFBBiJhcRMUUYGhFSNCkeH/xAAXAQEBAQEAAAAAAAAAAAAA"
        + "AAADAgQA/8QAHREAAgICAwEAAAAAAAAAAAAAAAECERIhAyIxMv/aAAwDAQAC"
        + "EQMRAD8AvWMQkSViFbaRkkZ4+g9aJeJbwMIljJmZN6ozEZHrQI5JYLOL4UbF"
        + "jJlwnHOKSyzXqssLi4AUnDMd+RnPLVlXZWy4RWKbGuzdOUjJQdSM5xRBa4/n"
        + "n3ryxKmzExBy/JzQpZiX8r4FZnJ3oAPO7LYwrErOXGSR0J/yluq6o1rGlogX"
        + "LKN8mOc0y0hwmlQNu3B5n69qz/iONWmYgg4PIBzitS8Rr49xLBl1aOHBMLBw"
        + "duDnaO3vRbdLiSFXlwWPeu0lhc2aI+d6DB+9WN6W5Ma9BRzlTxSAl6TMgt7a"
        + "3gbyg7nH0znmkGqXSSXDq7qiHqc9a0fiNYJLG1eNCFdyntwax8ypIyI0Y3gY"
        + "3Y6U1V6PD50PtIjYQtMysgY5QHrt7E1NkLOSS3Jplo8lvdaahuR+7H5HI4yR"
        + "0P3FW/k7N+cfmpfE27AknYqvJIv0KNpD543O30Oazb2N2WNwhBHOUzzj61qv"
        + "EdlKbyxt3SZkLbpBFFlQPccZ96OYkaN3RSSQdoaEDnHApFBl50kkIfD1yZpZ"
        + "o1cKAg3AnvmmLSOGI+J/RoPh6xayaVb3Tpd85DBgQdqjsefc0+e1swxAtM+u"
        + "7r+a7CTJm7Z//9k="
        + "</base64Binary>"
    

    现在让我们解析一下。因此,我们需要一个原始委托,如下所示:

    /// Extracts the content of the first <bas64Binary> tag in the XML
    class Base64BinaryExtractor: NSObject, XMLParserDelegate {
    
        private var active: Bool = false
        var base64String: String? = nil
    
        func parser (
                _ parser: XMLParser,
                didStartElement elementName: String,
                namespaceURI: String?,
                qualifiedName qName: String?,
                attributes attributeDict: [String : String] = [:]
            )
        {
            // We must not have a string yet
            guard self.base64String == nil else {
                // If we do, this is a second <bas64Binary> tag or
                // it's a tag within a tag.  We ingore both.
                self.active = false
                return
            }
            // We only care for "<base64Binary>"
            guard elementName == "base64Binary" else { return }
    
            // Time to collect the string
            self.active = true
            self.base64String = ""
        }
    
        func parser (
                _ parser: XMLParser,
                didEndElement elementName: String,
                namespaceURI: String?,
                qualifiedName qName: String?
            )
        {
            // No matter what element, no matter if we were active,
            // we are not active anymore once any tag ends.
            self.active = false
        }
    
    
        func parser (
                _ parser: XMLParser,
                foundCharacters string: String
            )
        {
            // Ignore everything unless we are active
            guard self.active else { return }
            self.base64String!.append(string)
        }
    }
    

    然后实际的解析只是将字符串转换为数据,设置解析器,设置委托并使其运行:

    let xmlData = xmlString.data(using: .utf8)
    // TODO: Check xmlData being nil and handle that!
    let parser = XMLParser(data: xmlData!)
    
    let delegate = Base64BinaryExtractor()
    parser.delegate = delegate
    
    let parseOK = parser.parse()
    // TODO: Check parseOK and handle if not!
    // TODO: Check delegate.base64String being nil and handle!
    

    现在您需要做的就是将 base64 解码为原始数据并从中制作图像:

    let rawData = Data(base64Encoded: delegate.base64String!)
    // TODO:  Check raw data being nil (bad base64!) and hanlde that!
    
    let image = UIImage(data: rawData!)
    

    上面的代码假设rawData包含iOS已知的图像格式的数据(例如PNG、JPEG、TIFF)如果不是这种情况,则需要转换格式,可能使用外部图像库来处理它。

    作为奖励,这里有两个关于 StackOverflow 未来问题的宝贵提示:

    1. 始终提供示例数据。截图并没有删减它,因为我不能用它来测试示例代码。示例数据对试图帮助您的人有很大帮助,因此您将获得更多、更好的答案,如果您提供示例数据,您将更快地获得答案。

    2. 将复杂问题分解为更小的子问题,然后对每个子问题提出一个问题,而不是创建复杂的“涵盖所有内容”的问题,这大大增加了您获得快速准确答复的机会。这也是开发软件的方式:分而治之。把大问题转化为小问题,一次解决一个子问题,如果你把它们都解决了,那么你也把复杂的问题作为一个整体解决了。例如。这个问题可以分解为三个子问题:

      1. 解析 XML 文档以提取特定标签的内容
      2. 将 base64 数据转换为原始数据
      3. 从原始数据创建图像

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-03
      • 1970-01-01
      • 1970-01-01
      • 2016-09-04
      相关资源
      最近更新 更多