Reputation: 8995
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)
}
}
}
}
}
}
Upvotes: 2
Views: 1382
Reputation: 7439
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:
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
}
}
Upvotes: 2