如何使用SwiftUI和Xcode for macOS/将cgImage作为ImageView返回

gijlo24d  于 2023-05-19  发布在  Swift
关注(0)|答案(1)|浏览(200)

我将数据作为[UInt8]存储在Data对象中,以渲染为灰度8位图像。我不知道如何从一个cgImage到一个图像视图。下面的代码至少编译到缺少返回值,但我不确定它是否正确。要将图像作为视图返回,需要添加什么?

import SwiftUI

struct ImageView_2: View {
    var data: Data
    
    var body: some View {
        
        let width = 320
        let height = 240
        
        let colorSpace = CGColorSpaceCreateDeviceGray()
        
        let context = CGContext(data: data.castToCPointer(), width: width, height: height, bitsPerComponent: 8, bytesPerRow: width, space: colorSpace, bitmapInfo: CGImageAlphaInfo.alphaOnly.rawValue)
        let imageRef = CGContext.makeImage(context!)
        let imageRep = NSBitmapImageRep(cgImage: imageRef()!)
        let image = imageRep.cgImage

        return
          //  .resizable()
          //  .aspectRatio(contentMode: .fit)
    }  
    
}

数据的扩展:

extension Data {
    func castToCPointer<T>() -> T {
        return self.withUnsafeBytes { $0.pointee }
    }
}
uwopmtnx

uwopmtnx1#

您的castToCPointer是未定义的行为,并且肯定会崩溃,特别是在打开优化时。从withUnsafeBytes闭包外部的Data访问指针是无效的。幸运的是,这也是不必要的。
SwiftUI中的图像视图是Image,并接受NSImage作为输入。
我还没有测试过,但这应该能满足你的要求:

struct ImageView_2: View {
    var data: Data

    var body: some View {

        let width = 320
        let height = 240

        let colorSpace = CGColorSpaceCreateDeviceGray()

        let provider = CGDataProvider(data: data as CFData)!

        let image = CGImage(width: width,
                            height: height,
                            bitsPerComponent: 8,
                            bitsPerPixel: 8 * 1,
                            bytesPerRow: width,
                            space: colorSpace,
                            bitmapInfo: [],
                            provider: provider,
                            decode: nil,
                            shouldInterpolate: false,
                            intent: .defaultIntent)!

        return Image(nsImage: NSImage(cgImage: image,
                                      size: CGSize(width: width, height: height)))
    }
}

请注意,如果数据格式不正确,这里的!用法将崩溃。您可以使用if-let来检查它们是否为nil。在这种情况下,您仍然需要返回一个有效的View。

相关问题