如何在Swift中将CGImage保存为数据?

qfe3c7zg  于 2023-02-03  发布在  Swift
关注(0)|答案(1)|浏览(277)

此代码类型检查并编译,但随后崩溃。如何将CGImage保存为Data,以便以后可以再次读取它。

let cgi: CGImage? = ...        
var mData = Data()
let imageDest = CGImageDestinationCreateWithData(mData as! CFMutableData, 
                                                 kUTTypePNG, 1, nil)!
CGImageDestinationAddImage(imageDest, cgi!, nil)
CGImageDestinationFinalize(imageDest)

最后一行崩溃,控制台错误为:

2018-01-17 19:25:43.656664-0500 HelloPencil[2799:3101092] -[_NSZeroData 
  appendBytes:length:]: unrecognized selector sent to instance 0x1c80029c0
2018-01-17 19:25:43.658420-0500 HelloPencil[2799:3101092] *** Terminating app 
  due to uncaught exception 'NSInvalidArgumentException', reason: 
  '-[_NSZeroData appendBytes:length:]: unrecognized selector 
  sent to instance 0x1c80029c0'

DataCFMutableData的转换是Xcode推荐的,但可能是错误的。

ohfgkhjo

ohfgkhjo1#

问题在于创建可变数据的方式。Data不能直接转换为NSMutableData
Data强制转换为CFMutableData的唯一方法是先将其强制转换为NSData,获取其mutableCopy NSMutableData,然后将其强制转换为CFMutableData
NSMutableData免费桥接到CFMutableData
但是在这种情况下,考虑到没有数据需要转换,这样做没有任何意义,只需使用CFDataCreateMutable(nil, 0)初始化一个新的CFMutableData对象:

if let cgi = cgi, 
    let mutableData = CFDataCreateMutable(nil, 0),
    let destination = CGImageDestinationCreateWithData(mutableData, "public.png" as CFString, 1, nil) {
    CGImageDestinationAddImage(destination, cgi, nil)
    if CGImageDestinationFinalize(destination) {
        let data = mutableData as Data
        if let image = UIImage(data: data) {
            print(image.size)
        }
    } else {
        print("Error writing Image")
    }
}

编辑/更新:超码11 ·斯威夫特5.1

extension CGImage {
    var png: Data? {
        guard let mutableData = CFDataCreateMutable(nil, 0),
            let destination = CGImageDestinationCreateWithData(mutableData, "public.png" as CFString, 1, nil) else { return nil }
        CGImageDestinationAddImage(destination, self, nil)
        guard CGImageDestinationFinalize(destination) else { return nil }
        return mutableData as Data
    }
}

相关问题