如何为相册选择或拍摄的图片应用滤镜(无需硬编码图片名)
解决滤镜无法应用到用户选择/拍摄图片的问题
我来帮你搞定这个问题!你的核心问题是process()函数里硬编码加载了固定的test图片,完全没用到用户实际选择或拍摄的那张。咱们一步步修改:
第一步:添加变量存储用户选中的图片
在ViewController类里新增一个可选类型的UIImage变量,用来保存用户从相册选的或相机拍的图片:
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate { var FilterName:String? // 新增:存储用户选中的原始图片 var selectedImage: UIImage? // ... 其他代码保持不变 }
第二步:更新图片选择回调,保存选中的图片
在imagePickerController(_:didFinishPickingMediaWithInfo:)方法里,把选中的图片同时赋值给刚才新增的selectedImage变量:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { guard let image = info[.originalImage] as? UIImage else { return } PhotoView.image = image // 新增:保存用户选中的图片 selectedImage = image dismiss(animated: true, completion: nil) }
第三步:修改process()函数,使用用户选中的图片
把原来硬编码加载UIImage("test")的逻辑替换成使用selectedImage,同时加上安全校验避免崩溃:
func process() { // 先校验是否有选中的图片,以及滤镜名称是否有效 guard let image = selectedImage, let filterName = FilterName else { print("没有选中图片或未选择有效滤镜") return } guard let originalCIImage = CIImage(image: image) else { print("无法将UIImage转换为CIImage") return } guard let filter = CIFilter(name: filterName) else { print("无法创建指定滤镜:\(filterName)") return } filter.setDefaults() filter.setValue(originalCIImage, forKey: kCIInputImageKey) if let outputImage = filter.outputImage { // 注意:直接用UIImage(ciImage:)可能显示有问题,建议转成CGImage再创建UIImage let context = CIContext(options: nil) guard let cgImage = context.createCGImage(outputImage, from: outputImage.extent) else { return } let newImage = UIImage(cgImage: cgImage) PhotoView.image = newImage } }
额外优化点:处理滤镜显示问题
原来用UIImage(ciImage: outputImage)直接创建图片可能会有显示异常(比如图片不显示或者尺寸不对),所以我在代码里加了用CIContext把CIImage转成CGImage再创建UIImage的逻辑,这样能保证图片正常显示。
现在你点击滤镜按钮时,就会自动对用户之前选择或拍摄的图片应用滤镜啦!
内容的提问来源于stack exchange,提问作者Modz




