如何使用 SwiftUI 和 Xcode for macOS/

问题描述 投票:0回答:1

我将数据作为 [UInt8] 存储在数据对象中,以呈现为灰度 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 }
    }
}
xcode macos image swiftui
1个回答
0
投票

你的

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
检查它们是否为零来解决这个问题。但是,在那种情况下,您仍然需要返回一个有效的视图。

© www.soinside.com 2019 - 2024. All rights reserved.