Post

图片的Base64转换及字符串的Base64转换

前言

在日常业务中,调用三方SDK或前后端传递图片时,经常需要将图片转换为Base64的字符串,以及一些字符串统一转换成base64后放到文件进行简单的加解密

一、图片与base64字符串进行相互转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
extension UIImage {
    // 将图片转表示base64值的字符串
    func base64StrWithPrefix(isPngData: Bool = false, jpegQuality: CGFloat = 1) -> String? {
        if let imgStr = self.base64Str(isPngData: isPngData, jpegQuality: jpegQuality) {
            return "data:image/\(isPngData ? "png" : "jpeg");base64,\(imgStr)"
        }
        return nil
    }
    func base64Str(isPngData: Bool = false, jpegQuality: CGFloat = 1) -> String? {
        // 参数1.0表示不压缩,因为jpeg是有损格式,jpg和jpeg都用这个方法。无损格式PNG使用pngData()方法转换,没有参数,也就是不压缩。
        let imageData: Data? = isPngData ? self.pngData() : self.jpegData(compressionQuality: jpegQuality)
        return imageData?.base64EncodedString(options: Data.Base64EncodingOptions.lineLength64Characters)
    }

    static func base64ToImage(_ str: String?) -> UIImage? {
        let base64Str: String?
        // 去掉姿势的字符串
        if str?.hasPrefix("data:image/") == true {
            base64Str = str?.components(separatedBy: ";base64,").last
        } else {
            base64Str = str
        }
        guard let base64Str = base64Str else {
            return nil
        }
        guard let data = Data(base64Encoded: base64Str, options: .ignoreUnknownCharacters) else {
            return nil
        }
        return UIImage(data: data)
    }
}
extension String {
    var base64ToImage: UIImage? {
        return UIImage.base64ToImage(self)
    }
}
func testBase64Image() {
    let img = UIImage(named: "xxxx")
    let imgPngStr = img?.base64Str(isPngData: true)
    let imgPng1 = UIImage.base64ToImage(imgPngStr)
    let imgPng2 = imgPngStr?.base64ToImage
    let imgPngStrWithPrefix = img?.base64StrWithPrefix(isPngData: true)
    let imgPng3 = UIImage.base64ToImage(imgPngStrWithPrefix)
    let imgPng4 = imgPngStrWithPrefix?.base64ToImage
    
    let imgjpgStr = img?.base64Str(isPngData: false)
    let imgjpg1 = UIImage.base64ToImage(imgjpgStr)
    let imgjpg2 = imgjpgStr?.base64ToImage
    let imgjpgStrWithPrefix = img?.base64StrWithPrefix(isPngData: false)
    let imgjpg3 = UIImage.base64ToImage(imgjpgStrWithPrefix)
    let imgjpg4 = imgjpgStrWithPrefix?.base64ToImage
}

二、普通文本与base64字符串的转换

参考:How can I encode/decode a string to Base64 in Swift?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
extension String {
    func subString(toIndex: Int) -> String {
        if toIndex < 0 {
            return ""
        }
        if toIndex >= self.count {
            return self
        }
        let startIndex = self.startIndex
        let endIndex = self.index(self.startIndex, offsetBy: toIndex+1)
        return String(self[startIndex..<endIndex])
    }
    var formatBase64: String {
        // 对多余的前后的空格去掉
        var text = self.trimmingCharacters(in: CharacterSet.whitespaces)
        // 防止手误,配置的字符串在末尾增加换行符
        while text.count > 2 && text.hasSuffix("\n") {
            // count - 1 是index, index - 1 到倒数第二位,count-2 是倒数第二的index
            text = text.subString(toIndex: text.count-2)
        }
        // 防止长度不够,需要在末尾增加=
        let needAddCount = 4 - (text.count % 4)
        if needAddCount > 0, needAddCount < 4 {
            for _ in (0..<needAddCount) {
                text = text + "="
            }
        }
        return text
    }

    var base64DecodeStr: String? {
        // 将base64编码的字符串解码成普通字符串
        // "aGVsbG9Xb3JsZA==" -> "helloWorld"
        // 1、对base64编码的字符串进行格式化处理,防止有多余的字符串或换行符
        let formatBase64Str = self.formatBase64
        // 2、将base64的字符串转换为utf8编码的data
        // 3、将utf8的data进行base64解码
        if let utf8Data = formatBase64Str.data(using: .utf8),
        let base64Data = Data(base64Encoded: utf8Data, options: Data.Base64DecodingOptions(rawValue: 0)) {
            // 4、将解码后的data还原成字符串
            return String(data: base64Data, encoding: .utf8)
        }
        return nil
    }
    
    var base64EncodeStr: String? {
        // 将普通字符串进行base64编码
        // "helloWorld" -> "aGVsbG9Xb3JsZA=="
        // 1、将字符串转换为utf8转换为data
        let utf8Data = self.data(using: .utf8)
        // 2、将utf8的data进行base64进行编码的字符串
        return utf8Data?.base64EncodedString(options: Data.Base64EncodingOptions(rawValue: 0))
    }
}

func testBase64Str() {
    let str1 = "iOS Developer Tips encoded in Base64"
    let str2 = str1.base64EncodeStr
    let str3 = str2?.base64DecodeStr
    print("str1: \(str1)") // str1: iOS Developer Tips encoded in Base64
    print("str2: \(str2 ?? "")") // str2: aU9TIERldmVsb3BlciBUaXBzIGVuY29kZWQgaW4gQmFzZTY0
    print("str3: \(str3 ?? "")") // str3: iOS Developer Tips encoded in Base64
}
This post is licensed under CC BY 4.0 by the author.