使用圆角保存UIImage并使用Swift边框

我正在使用imagePickerController从用户库中选择一张图片。 我需要在应用程序中保存带圆角和边框的图片。 保存图像时,它会保存未经改动的图像。 我假设我只改变视图而不是图像本身。 有没有办法将图片保存为视图中可以看到的内容?

@IBOutlet var imageViewer: UIImageView! func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) { var imagePicked = info[UIImagePickerControllerOriginalImage] as UIImage imageViewer.layer.cornerRadius = 10.0 imageViewer.clipsToBounds = true imageViewer.layer.frame = CGRectInset(imageViewer.layer.frame, 20, 20) imageViewer.layer.borderColor = UIColor.purpleColor().CGColor imageViewer.layer.borderWidth = 2.0 imageViewer.image = imagePicked 

感谢您的帮助!

您需要执行的基本操作是:

  • 剪切绘图区域以在没有角落的情况下绘制图像
  • 画出图像
  • 配置笔触颜色等
  • 然后描绘用于剪裁的路径

     func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) { let borderWidth: CGFloat = 2.0 let imagePicked = info[UIImagePickerControllerOriginalImage] as UIImage UIGraphicsBeginImageContextWithOptions(imageViewer.frame.size, false, 0) let path = UIBezierPath(roundedRect: CGRectInset(imageViewer.bounds, borderWidth / 2, borderWidth / 2), cornerRadius: 10.0) let context = UIGraphicsGetCurrentContext() CGContextSaveGState(context) // Clip the drawing area to the path path.addClip() // Draw the image into the context imagePicked.drawInRect(imageViewer.bounds) CGContextRestoreGState(context) // Configure the stroke UIColor.purpleColor().setStroke() path.lineWidth = borderWidth // Stroke the border path.stroke() roundedImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); view.addSubview(UIImageView(image: roundedImage)) picker.dismissViewControllerAnimated(true, completion: nil) } 

在上面的代码中,我将路径插入了笔划宽度的一半,因为笔划是沿着路径的中心绘制的,这意味着一个像素将最终在路径之外。

Paul.s的答案是完美的(⬆️),但由于它只捕获UIImage相对于UIImageView的大小,因此可以降低图像质量。 假设您希望图像在框架内保持其纵横比,并且您希望边框直接位于其边缘,则可以执行此操作以保持整个图像的大小以进行保存:

 func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) { let imagePicked = info[UIImagePickerControllerOriginalImage] as UIImage let borderWidth: CGFloat = 2.0 let cornerRadius:CGFloat = 10.0 // Create a multiplier to scale up the corner radius and border // width you decided on relative to the imageViewer frame such // that the corner radius and border width can be converted to // the UIImage's scale. let multiplier:CGFloat = imagePicked.size.height/imageViewer.frame.size.height > imagePicked.size.width/imageViewer.frame.size.width ? imagePicked.size.height/imageViewer.frame.size.height : imagePicked.size.width/imageViewer.frame.size.width let borderWidthMultiplied:CGFloat = borderWidth * multiplier let cornerRadiusMultiplied:CGFloat = cornerRadius * multiplier UIGraphicsBeginImageContextWithOptions(imagePicked.size, false, 0) let path = UIBezierPath(roundedRect: CGRectInset(CGRectMake(0, 0, imagePicked.size.width, imagePicked.size.height), borderWidthMultiplied / 2, borderWidthMultiplied / 2), cornerRadius: cornerRadiusMultiplied) let context = UIGraphicsGetCurrentContext() CGContextSaveGState(context) // Clip the drawing area to the path path.addClip() // Draw the image into the context imagePicked.drawInRect(CGRectMake(0, 0, imagePicked.size.width, imagePicked.size.height)) CGContextRestoreGState(context) // Configure the stroke UIColor.blackColor().setStroke() path.lineWidth = borderWidthMultiplied // Stroke the border path.stroke() imageViewer.image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); picker.dismissViewControllerAnimated(true, completion: nil) } 

您目前正在做的是更改图像的显示,而不更改图像本身。 您需要创建位图上下文(请参阅UIGraphicsBeginImageContextWithOptions ); 设置圆形直剪裁区域( CGContextEOClip ); 将您的图像绘制到上下文中; 最后,从上下文中获取UIImage( UIGraphicsGetImageFromCurrentImageContext

斯威夫特3:

  func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) { if let image = info[UIImagePickerControllerEditedImage] as? UIImage { let borderWidth: CGFloat = 2.0 UIGraphicsBeginImageContextWithOptions(myImageButton.frame.size, false, 0) let path = UIBezierPath(roundedRect: myImageButton.bounds.insetBy(dx: borderWidth / 2, dy: borderWidth / 2), cornerRadius: 40.0) let context = UIGraphicsGetCurrentContext() context!.saveGState() path.addClip() image.draw(in: myImageButton.bounds) UIColor.gray.setStroke() path.lineWidth = borderWidth path.stroke() let roundedImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() myImageButton.setImage(roundedImage, for: .normal) } }