You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何无法在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)

额外优化点

  1. 替换UIGraphicsBeginImageContext为UIGraphicsBeginImageContextWithOptions,第三个参数传入原图的scale,生成的图片能适配 Retina 屏幕,避免模糊。
  2. 将setStrokeColor的调用提前到创建路径之前,代码逻辑更清晰(虽然顺序不影响结果,但可读性更好)。

内容的提问来源于stack exchange,提问作者Paul K.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:18:54