为何无法在UIImage上绘图?请求排查代码问题
问题排查与解决方案
嘿,我帮你找到问题的根源啦!你遇到的问题是因为Core Graphics 上下文的坐标系和 UIKit 默认的坐标系不一致,导致你画的白色线条其实在图像的可视区域之外,所以最终生成的finalImage看起来和原图完全一样。
问题细节
当你用UIGraphicsBeginImageContext创建绘图上下文后,UIKit 的绘图 API(比如UIImage.draw(at:))会自动适配左上角为原点的坐标系,但直接使用 Core Graphics 的 API(比如CGContext.move(to:)、addLine(to:))时,上下文默认的原点是左下角。你画的从(10,10)到(150,150)的线条,其实是从图像左下角的(10,10)往右上画,这部分区域超出了图像的显示范围(因为图像的Y轴向上延伸),所以最终生成的图片里看不到这条线。
修正后的代码
// 优先使用 UIGraphicsBeginImageContextWithOptions 适配 Retina 屏幕 UIGraphicsBeginImageContextWithOptions(uiImage!.size, false, uiImage!.scale) uiImage?.draw(at: CGPoint(x: 0, y: 0)) let newContext = UIGraphicsGetCurrentContext()! // 关键步骤:翻转坐标系,让 Core Graphics 适配 UIKit 的左上角原点 newContext.translateBy(x: 0, y: uiImage!.size.height) newContext.scaleBy(x: 1.0, y: -1.0) newContext.setLineWidth(2) newContext.setStrokeColor(UIColor.white.cgColor) // 把颜色设置提前,逻辑更清晰 newContext.move(to: CGPoint(x: 10, y: 10)) newContext.addLine(to: CGPoint(x: 150, y: 150)) newContext.strokePath() let finalImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() UIImageWriteToSavedPhotosAlbum(uiImage!, nil, nil, nil) UIImageWriteToSavedPhotosAlbum(finalImage!, nil, nil, nil)
额外优化点
- 替换
UIGraphicsBeginImageContext为UIGraphicsBeginImageContextWithOptions,第三个参数传入原图的scale,生成的图片能适配 Retina 屏幕,避免模糊。 - 将
setStrokeColor的调用提前到创建路径之前,代码逻辑更清晰(虽然顺序不影响结果,但可读性更好)。
内容的提问来源于stack exchange,提问作者Paul K.
相关产品推荐
相关产品推荐

