Swift 5中如何移除网络图片背景并在CollectionView的ImageView中显示轮廓?
实现图片背景移除并显示轮廓的方案
核心思路
通过Core ML本地模型移除图片背景,再利用Core Image滤镜提取前景轮廓,最终在CollectionView的ImageView中展示。
具体实现步骤
1. 导入背景移除模型
使用Apple官方的DeepLabV3模型(可从Core ML模型库获取),将模型文件添加到Xcode项目,并勾选对应target。
2. 图片下载与处理工具方法
// 异步下载图片 func downloadImage(from url: URL, completion: @escaping (UIImage?) -> Void) { URLSession.shared.dataTask(with: url) { data, _, error in guard let data = data, error == nil, let image = UIImage(data: data) else { completion(nil) return } completion(image) }.resume() } // UIImage尺寸扩展,适配模型输入要求 extension UIImage { func resize(to size: CGSize) -> UIImage? { UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale) self.draw(in: CGRect(origin: .zero, size: size)) let resizedImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return resizedImage } } // 移除背景并提取轮廓 func processImageForOutline(_ image: UIImage) -> UIImage? { // 初始化背景移除模型 guard let model = try? DeepLabV3(configuration: .init()) else { return nil } guard let inputImage = image.resize(to: CGSize(width: 513, height: 513)) else { return nil } // 生成背景掩码(白色为前景,黑色为背景) let input = DeepLabV3Input(image: inputImage) guard let output = try? model.prediction(input: input) else { return nil } let maskImage = output.semanticSegmentationMask // 用Core Image提取轮廓 let ciImage = CIImage(cgImage: maskImage.cgImage!) guard let edgeFilter = CIFilter(name: "CIEdges") else { return nil } edgeFilter.setValue(ciImage, forKey: kCIInputImageKey) edgeFilter.setValue(0.5, forKey: kCIInputIntensityKey) guard let edgeImage = edgeFilter.outputImage else { return nil } let cgEdgeImage = CIContext(options: nil).createCGImage(edgeImage, from: edgeImage.extent)! // 返回可设置颜色的模板图 return UIImage(cgImage: cgEdgeImage, scale: image.scale, orientation: image.imageOrientation) .withRenderingMode(.alwaysTemplate) }
3. CollectionView中加载处理后的图片
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ImageCell", for: indexPath) as! ImageCell let imageURL = yourImageURLArray[indexPath.item] downloadImage(from: imageURL) { originalImage in guard let originalImage = originalImage else { return } DispatchQueue.main.async { if let outlineImage = self.processImageForOutline(originalImage) { cell.imageView.image = outlineImage cell.imageView.tintColor = .black // 自定义轮廓颜色 } } } return cell }
优化建议
- 添加图片缓存:用
NSCache存储已处理的轮廓图,避免重复下载和计算 - 后台线程处理:将模型预测和滤镜处理放在全局队列,避免阻塞主线程
- 模型替换:如果
DeepLabV3效果不佳,可替换为更精准的第三方Core ML背景移除模型
内容的提问来源于stack exchange,提问作者SWIFTLopeR
相关产品推荐
相关产品推荐

