我很难弄清楚如何从CGImageRef获取图像的NSData表示。 我发现的所有答案都使用UIImage或NSImage ,但我的应用程序是跨平台的,所以我只想使用Core Graphics。 Objective-C简单地回答说, CFData是免费桥接到NSData并简单地转换它,但Swift不允许这样做。 我最接近的是:
var image: CGImageRef? = nil //... if let dataProvider: CGDataProviderRef = CGDataProviderCreateWithURL(url) { image = CGImageCreateWithPNGDataProvider(dataProvider, nil, false, CGColorRenderingIntent.RenderingIntentDefault) // works fine //... if let data = CGDataProviderCopyData(CGImageGetDataProvider(image)) as? NSData { // Do something with data, if only it ever got here! } }但演员阵容永远不会成功......
I am having difficulty figuring out how to get an NSData representation of an image from a CGImageRef. All of the answers I've found make use of UIImage or NSImage, but my application is cross-platform, so I want to use only Core Graphics. Objective-C answers state simply that CFData is toll-free bridged to NSData and simply cast it, but Swift will not allow this. The closest I've got is:
var image: CGImageRef? = nil //... if let dataProvider: CGDataProviderRef = CGDataProviderCreateWithURL(url) { image = CGImageCreateWithPNGDataProvider(dataProvider, nil, false, CGColorRenderingIntent.RenderingIntentDefault) // works fine //... if let data = CGDataProviderCopyData(CGImageGetDataProvider(image)) as? NSData { // Do something with data, if only it ever got here! } }but the cast doesn't ever succeed...
最满意答案
CGDataProviderCopyData()返回可选的CFData? ,并且不能转换为非可选NSData 。 但你可以转换/桥接到NSData? 并在可选绑定中使用它:
if let data = CGDataProviderCopyData(CGImageGetDataProvider(image)) as NSData? { // Do something with data ... }这是一个更简单的示例,演示了与CFString和NSString相同的问题:
let cfstr : CFString? = "Hello world" if let nsstr = cfstr as? NSString { print("foo") // not printed } if let nsstr = cfstr as NSString? { print("bar") // printed }但我承认我的解释并不完全令人满意,因为类似的可选演员在其他情况下也适用:
class MyClass { } class MySubclass : MyClass { } let mc : MyClass? = MySubclass() if let msc = mc as? MySubclass { print("yes") // printed }所以这必须与CoreFoundation和Foundation类型之间的免费桥接有关。
CGDataProviderCopyData() returns the optional CFData?, and that cannot be cast to the non-optional NSData. But you can convert/bridge it to NSData? and use that in the optional binding:
if let data = CGDataProviderCopyData(CGImageGetDataProvider(image)) as NSData? { // Do something with data ... }Here is a simpler example demonstrating the same issue with CFString and NSString:
let cfstr : CFString? = "Hello world" if let nsstr = cfstr as? NSString { print("foo") // not printed } if let nsstr = cfstr as NSString? { print("bar") // printed }But I admit that my explanation is not fully satisfying, because a similar optional cast works in other cases:
class MyClass { } class MySubclass : MyClass { } let mc : MyClass? = MySubclass() if let msc = mc as? MySubclass { print("yes") // printed }So this must be related to the toll-free bridging between CoreFoundation and Foundation types.
更多推荐
发布评论