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

Swift Mac开发:如何使用CIImage实现多张图片垂直拼接合并

macOS Swift 5 使用CIImage上下拼接多张图片实现方案

核心实现逻辑

  • 完全基于CoreImage框架实现,兼容macOS 11+系统,无UIKit依赖,完美适配你的开发环境
  • 利用坐标位移+内置合成滤镜实现图片拼接,支持任意数量图片批量处理

后续开发步骤代码实现

基于你已编写的图片加载代码,后续拼接流程如下:

import CoreImage
import AppKit // macOS系统需导入AppKit使用NSImage相关能力

// 1. 校验图片加载结果合法性
guard let img1 = img1, let img2 = img2 else {
    print("图片资源加载失败")
    return
}

// 2. 计算拼接后总画布尺寸
let totalWidth = max(img1.extent.width, img2.extent.width)
let totalHeight = img1.extent.height + img2.extent.height
let finalExtent = CGRect(x: 0, y: 0, width: totalWidth, height: totalHeight)

// 3. 对第二张图片做坐标位移,拼接至第一张底部
// 注意:CIImage坐标系原点在左下角,向下拼接需要升高y轴坐标
let moveTransform = CGAffineTransform(translationX: 0, y: img1.extent.height)
guard let movedImg2 = img2.transformed(by: moveTransform) as? CIImage else {
    print("图片坐标位移失败")
    return
}

// 4. 调用合成滤镜完成拼接
guard let compositeFilter = CIFilter(name: "CISourceOverCompositing") else {
    print("合成滤镜创建失败")
    return
}
compositeFilter.setValue(movedImg2, forKey: kCIInputImageKey)
compositeFilter.setValue(img1, forKey: kCIInputBackgroundImageKey)

guard let mergedCIImage = compositeFilter.outputImage else {
    print("图片合成失败")
    return
}

配套工具方法

CIImage转NSImage(用于界面展示/本地存储)

func ciImageToNSImage(_ ciImage: CIImage, targetSize: CGSize) -> NSImage? {
    let imageRep = NSCIImageRep(ciImage: ciImage)
    let resultImage = NSImage(size: targetSize)
    resultImage.addRepresentation(imageRep)
    return resultImage
}

// 调用示例
let finalSize = CGSize(width: totalWidth, height: totalHeight)
if let finalNSImage = ciImageToNSImage(mergedCIImage, targetSize: finalSize) {
    // 可直接赋值给NSImageView展示,或转为PNG/JPG数据写入本地文件
}

通用多图批量拼接方法

func verticalMergeCIImages(_ imageList: [CIImage]) -> CIImage? {
    guard !imageList.isEmpty else { return nil }
    guard imageList.count > 1 else { return imageList.first }
    
    var mergeResult = imageList.first!
    var totalHeight = mergeResult.extent.height
    
    for index in 1..<imageList.count {
        let nextImage = imageList[index]
        // 位移当前图片到已拼接内容的底部
        let transform = CGAffineTransform(translationX: 0, y: totalHeight)
        guard let movedNext = nextImage.transformed(by: transform) as? CIImage else {
            return nil
        }
        // 执行合成
        guard let filter = CIFilter(name: "CISourceOverCompositing") else {
            return nil
        }
        filter.setValue(movedNext, forKey: kCIInputImageKey)
        filter.setValue(mergeResult, forKey: kCIInputBackgroundImageKey)
        guard let newResult = filter.outputImage else {
            return nil
        }
        mergeResult = newResult
        totalHeight += nextImage.extent.height
    }
    return mergeResult
}

注意事项

  • 如果需要所有图片宽度统一,拼接前可使用CILanczosScaleTransform滤镜对宽度不一致的图片做等比缩放,避免拼接后出现错位
  • 合成后的CIImage如果需要保存到本地,可通过NSBitmapImageRep转为对应格式的二进制数据后写入文件

内容的提问来源于stack exchange,提问作者Buzka91

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 02:36:03