如何将嵌入在XML中的base64图像转换为UIImage?

时间:2017-04-07 05:28:54

标签: ios xml swift uiimage base64

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

enter image description here

1 个答案:

答案 0 :(得分:0)

首先,您需要解析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. 从原始数据创建图像