我正在try 根据每个像素的透明度使用BezierPath绘制图像的轮廓.
然而,我对逻辑有一个问题;我的逻辑也画出了内部轮廓.
我只想用BezierPath绘制外部轮廓.
我得到的(第一个形状是原始图像,第二个是bezierPath
):
我的代码是:
func processImage(_ image: UIImage) -> UIBezierPath? {
guard let cgImage = image.cgImage else {
print("Error: Couldn't get CGImage from UIImage")
return nil
}
let width = cgImage.width
let height = cgImage.height
// Create a context to perform image processing
let colorSpace = CGColorSpaceCreateDeviceGray()
let context = CGContext(data: nil, width: width, height: height, bitsPerComponent: 8, bytesPerRow: width, space: colorSpace, bitmapInfo: CGImageAlphaInfo.none.rawValue)
guard let context = context else {
print("Error: Couldn't create CGContext")
return nil
}
// Draw the image into the context
context.draw(cgImage, in: CGRect(x: 0, y: 0, width: width, height: height))
// Perform Canny edge detection
guard let edgeImage = context.makeImage() else {
print("Error: Couldn't create edge image")
return nil
}
// Create a bezier path for the outline of the shape
let bezierPath = UIBezierPath()
// Iterate over the image pixels to find the edges
for y in 0..<height {
for x in 0..<width {
let pixel = edgeImage.pixel(x: x, y: y)
if pixel > 0 {
let leftPixel = (x > 0) ? edgeImage.pixel(x: x - 1, y: y) : 0
let rightPixel = (x < width - 1) ? edgeImage.pixel(x: x + 1, y: y) : 0
let abovePixel = (y > 0) ? edgeImage.pixel(x: x, y: y - 1) : 0
let belowPixel = (y < height - 1) ? edgeImage.pixel(x: x, y: y + 1) : 0
if leftPixel == 0 || rightPixel == 0 || abovePixel == 0 || belowPixel == 0 {
bezierPath.move(to: CGPoint(x: CGFloat(x), y: CGFloat(y)))
bezierPath.addLine(to: CGPoint(x: CGFloat(x) + 1.0, y: CGFloat(y) + 1.0))
}
}
}
}
return bezierPath
}
extension CGImage {
func pixel(x: Int, y: Int) -> UInt8 {
let data = self.dataProvider!.data
let pointer = CFDataGetBytePtr(data)
let bytesPerRow = self.bytesPerRow
let pixelInfo = (bytesPerRow * y) + x
return pointer![pixelInfo]
}
}