简体   繁体   中英

How can I access the pixels data in SwiftUI Canvas

Trying to access the pixel data on a Canvas , and almost there I think? But I have missed some detail? This compiles but the cgContext.data doesn't seem to be set to a value I can extract here?

The line variable refers to a published array of points.

class Lines:ObservableObject {
  @Published var coordinates:[CGPoint] = []
}

struct ContentView: View {
  @ObservedObject var line = Lines()
  @GestureState var foo = CGPoint.zero
  var body: some View {
  ZStack(alignment: .center) {
    Color.yellow
    .opacity(0.1)

  Canvas { context, size in
    context.withCGContext { cgContext in
      cgContext.setStrokeColor(UIColor.red.cgColor)
      cgContext.setLineWidth(12)
      if line.coordinates.count > 2 {
        cgContext.move(to: line.coordinates[0])
        for p in 1..<line.coordinates.count {
          cgContext.move(to: line.coordinates[p - 1])
          cgContext.addLine(to: line.coordinates[p])
          cgContext.drawPath(using: .eoFillStroke)
        }
        if cgContext.data != nil {
          let rawData:UnsafeMutableRawPointer = cgContext.data!
          let opaquePtr = OpaquePointer(rawData)
          let contextPtr = UnsafeMutablePointer<UInt32>(opaquePtr)
          let pixels = UnsafeMutableBufferPointer<UInt32>(start: contextPtr, count: 256 * 256)
          print("pixels ",pixels.count)
        }
      }
    }
  }
}
}

I think this was discussed before, please see here


First, if you have an empty context then look here, you double check your configuration, Supported Pixel Formats . For 8 bitsPerComponent and RGB color space you have only the few valid alpha options:

支持的像素格式 Apple IOS Swift Ref.

Second, please use the CGBITMAP_CONTEXT_LOG_ERRORS env. variable in your scheme in runtime to debug this.


Since you are using core graphics , build an extension and then get the pixeldata from there, credit to Anna from here .

Just reuse your CGContext inside here and see if that works.

extension UIImage {
    func pixelData() -> [UInt8]? {
        let size = self.size
        let dataSize = size.width * size.height * 4
        var pixelData = [UInt8](repeating: 0, count: Int(dataSize))
        let colorSpace = CGColorSpaceCreateDeviceRGB()
        let context = CGContext(data: &pixelData,
                                width: Int(size.width),
                                height: Int(size.height),
                                bitsPerComponent: 8,
                                bytesPerRow: 4 * Int(size.width),
                                space: colorSpace,
                                bitmapInfo: CGImageAlphaInfo.noneSkipLast.rawValue)
        guard let cgImage = self.cgImage else { return nil }
        context?.draw(cgImage, in: CGRect(x: 0, y: 0, width: size.width, height: size.height))

        return pixelData
    }
 }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM