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

iOS加载WebP格式图片时如何保留透明通道?

问题

从PHPickerViewController传入的NSItemProvider数组中导入图片时,PNG格式能正确保留透明通道,但WebP格式无法保留。已确认saveImage函数不会导致透明性丢失,问题出在item.loadDataRepresentation(forTypeIdentifier: UTType.webP.identifier)调用或Data实例化为UIImage的过程中。相关代码如下:

private func save(itemProviders: [NSItemProvider]) async throws -> Int {
    return try await withCheckedThrowingContinuation({ continuation in
        let group = DispatchGroup()
        var failureCount = 0
        for item in itemProviders {
            // webp format image
            if item.hasItemConformingToTypeIdentifier(UTType.webP.identifier) {
                group.enter()
                item.loadDataRepresentation(forTypeIdentifier: UTType.webP.identifier) { data, error in
                    defer {
                        group.leave()
                    }
                    guard let data, let image = UIImage(data: data) else {
                        return
                    }
                    self.saveImage(image)
                }
            }
            else if item.canLoadObject(ofClass: UIImage.self) {
                // other image formats, including PNG
                group.enter()
                item.loadObject(ofClass: UIImage.self) { (image, error) in
                    defer {
                        group.leave()
                    }
                    guard let image = image as? UIImage else {
                        return
                    }

                    self.saveImage(image)
                }
            }
            else {
                failureCount += 1
            }
        }
        group.notify(queue: .main) {
            continuation.resume(returning: failureCount)
        }
    })
}
解决方案
  • 移除WebP单独处理分支,统一使用loadObject(ofClass: UIImage.self)加载所有图片类型。iOS 14及以上系统的UIImage原生支持WebP解码,通过loadObject加载时会自动保留透明通道。
  • 修改后的代码如下:
private func save(itemProviders: [NSItemProvider]) async throws -> Int {
    return try await withCheckedThrowingContinuation({ continuation in
        let group = DispatchGroup()
        var failureCount = 0
        for item in itemProviders {
            if item.canLoadObject(ofClass: UIImage.self) {
                group.enter()
                item.loadObject(ofClass: UIImage.self) { (image, error) in
                    defer {
                        group.leave()
                    }
                    guard let image = image as? UIImage else {
                        failureCount += 1
                        return
                    }
                    self.saveImage(image)
                }
            } else {
                failureCount += 1
            }
        }
        group.notify(queue: .main) {
            continuation.resume(returning: failureCount)
        }
    })
}
  • 问题根源:直接加载WebP的Data Representation再实例化UIImage时,系统未正确解析透明通道的元数据;而通过loadObject(ofClass: UIImage.self)让系统完成解码流程,能完整保留图片的透明属性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 06:35:27