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

SwiftUI实现黑白反转且保留颜色的PDF图片深色适配

适配深色模式的PDF转UIImage渲染方案

针对你需要将PDF转换的UIImage在SwiftUI中适配深色模式(地图背景转黑/深灰,保留原色彩)的需求,这里提供几种可行的实现方案:

方案一:优化SwiftUI图层混合(快速调整)

之前的ZStack方案中黄色变绿是因为.color混合模式导致色相偏移,换成.colorBurn并调整滤镜参数可以修正这个问题,同时保留深色背景和原色彩:

ZStack {
    // 深色灰度底图:反转+去饱和+增强对比度让背景更纯粹
    Image(uiImage: self.mapImage!)
        .resizable()
        .scaledToFill()
        .colorInvert()
        .saturation(0)
        .contrast(1.2)
        .brightness(-0.1)
    
    // 原色彩层:用colorBurn混合模式保留原色相,增强饱和度让色彩更突出
    Image(uiImage: self.mapImage!)
        .resizable()
        .scaledToFill()
        .blendMode(.colorBurn)
        .saturation(1.1)
}
.clipped() // 裁剪超出边界的内容

这个方案不需要额外的CoreImage处理,纯SwiftUI API即可实现,调整contrast、brightness和saturation的数值可以适配不同的PDF内容。

方案二:用CoreImage模拟Affinity的图层组合

SwiftUI的blendMode确实没有"Add"模式,但CoreImage提供了CIAdditionCompositing滤镜,可以完全复刻你在Affinity中实现的效果:

1. 先写几个CoreImage工具函数

// 给图片应用单个CoreImage滤镜
private func applyFilter(to image: UIImage, filter: CIFilter) -> UIImage? {
    guard let ciImage = CIImage(image: image) else { return nil }
    filter.setValue(ciImage, forKey: kCIInputImageKey)
    
    guard let outputCI = filter.outputImage else { return nil }
    let context = CIContext(options: [.useSoftwareRenderer: false])
    guard let outputCG = context.createCGImage(outputCI, from: outputCI.extent) else { return nil }
    return UIImage(cgImage: outputCG)
}

// 生成反转+黑白的图片
private func invertedGrayscaleImage(from image: UIImage) -> UIImage? {
    let invertFilter = CIFilter(name: "CIColorInvert")!
    let grayFilter = CIFilter(name: "CIColorControls")!
    grayFilter.setValue(0, forKey: kCIInputSaturationKey)
    
    guard let inverted = applyFilter(to: image, filter: invertFilter) else { return nil }
    return applyFilter(to: inverted, filter: grayFilter)
}

// 用Add混合模式合成两张图片
private func addComposite(base: UIImage, overlay: UIImage) -> UIImage? {
    guard let baseCI = CIImage(image: base), let overlayCI = CIImage(image: overlay) else { return nil }
    let addFilter = CIFilter(name: "CIAdditionCompositing")!
    addFilter.setValue(baseCI, forKey: kCIInputImageKey)
    addFilter.setValue(overlayCI, forKey: kCIInputBackgroundImageKey)
    
    guard let outputCI = addFilter.outputImage else { return nil }
    let context = CIContext(options: [.useSoftwareRenderer: false])
    guard let outputCG = context.createCGImage(outputCI, from: outputCI.extent) else { return nil }
    return UIImage(cgImage: outputCG)
}

2. 在SwiftUI中处理并渲染

@State private var processedImage: UIImage?

var body: some View {
    Group {
        if let processedImage = processedImage {
            Image(uiImage: processedImage)
                .resizable()
                .scaledToFill()
        } else if let mapImage = mapImage {
            // 加载中可以显示原图或者占位符
            Image(uiImage: mapImage)
                .resizable()
                .scaledToFill()
        }
    }
    .onAppear {
        guard let original = mapImage else { return }
        // 复刻Affinity的三个图层逻辑
        guard let layer3 = invertedGrayscaleImage(from: original),
              let layer2 = addComposite(base: layer3, overlay: layer3),
              let darkenFilter = CIFilter(name: "CIDarkenBlendMode") else { return }
        
        darkenFilter.setValue(CIImage(image: original), forKey: kCIInputImageKey)
        darkenFilter.setValue(CIImage(image: layer2), forKey: kCIInputBackgroundImageKey)
        
        processedImage = applyFilter(to: original, filter: darkenFilter)
    }
}

如果觉得部分文本可读性差,可以在最后给processedImage再叠加一层亮度调整:

// 调整文本可读性
if let processedImage = processedImage {
    Image(uiImage: processedImage)
        .resizable()
        .scaledToFill()
        .brightness(0.1)
        .contrast(1.1)
}

方案三:极简单图层调整

如果不需要完全复刻Affinity的效果,只想快速适配深色模式,可以用单图层的滤镜组合:

Image(uiImage: mapImage!)
    .resizable()
    .scaledToFill()
    .colorInvert()
    .saturation(0.3) // 保留少量色彩,同时灰度化背景
    .colorMultiply(Color.black.opacity(0.8)) // 加深背景
    .brightness(0.1) // 提亮文本
    .blendMode(.screen) // 让彩色内容更醒目

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 02:27:39