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

如何不使用lockFocus方法将小NSImage左上对齐叠加到大NSImage生成新图

重写NSImage图片叠加代码以替代弃用的lockFocus方法

需求:将小图左上对齐叠加在大图上,生成新的NSImage;原代码使用了已弃用的lockFocus/unlockFocus方法,需要替换为兼容分辨率无关绘图的实现。

原代码(含弃用方法)

func combineImages(image1: NSImage, image2: NSImage) -> NSImage {
    let size = NSMakeSize(max(image1.size.width, image2.size.width), max(image1.size.height, image2.size.height))
    let newImage = NSImage(size: size)
    
    newImage.lockFocus()
    
    image2.draw(at: NSPoint(x: 0, y: size.height - image2.size.height), from: NSZeroRect, operation: .sourceOver, fraction: 1.0)
    image1.draw(at: NSZeroPoint, from: NSZeroRect, operation: .sourceOver, fraction: 1.0)
    
    newImage.unlockFocus()

    return newImage
}

弃用说明

此方法与分辨率无关绘图不兼容,不应再使用。

重写后的代码

使用NSImage(size:flipped:drawingHandler)初始化方法替代弃用的锁定焦点逻辑,该方法支持分辨率无关绘图,且代码更简洁:

func combineImages(image1: NSImage, image2: NSImage) -> NSImage {
    // 取两张图片的最大宽高作为最终图片尺寸
    let finalSize = NSSize(
        width: max(image1.size.width, image2.size.width),
        height: max(image1.size.height, image2.size.height)
    )
    
    // 使用绘图闭包创建新图片
    return NSImage(size: finalSize) { drawingRect in
        // 绘制底层大图,左下角对齐到原点
        image1.draw(at: .zero, from: .zero, operation: .sourceOver, fraction: 1.0)
        
        // 计算小图左上对齐的原点坐标:左下角y值为最终高度减去小图高度,确保顶部对齐
        let smallImageOrigin = NSPoint(x: 0, y: finalSize.height - image2.size.height)
        // 绘制左上对齐的小图
        image2.draw(at: smallImageOrigin, from: .zero, operation: .sourceOver, fraction: 1.0)
        
        return true
    }
}

代码说明

  • 采用NSImage的现代初始化方法,通过闭包完成绘图逻辑,无需手动管理焦点锁定
  • 保持原代码的尺寸计算逻辑:取两张图片的最大宽高作为最终图片尺寸
  • 小图左上对齐的坐标计算逻辑与原代码一致,确保叠加效果不变
  • 完全兼容分辨率无关绘图,符合Apple的最新API规范

内容的提问来源于stack exchange,提问作者J. Doe

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 00:13:17