繁体   English   中英

使用 Swift 保存带有圆角和边框的 UIImage

[英]Saving UIImage with rounded corners and border with 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)


}

带边框的圆形 UIImage:

extension UIImage {
    
    func roundedWithStroke(width: CGFloat = 3) -> UIImage {
        let imageLayer = CALayer()
        let targetSize = CGSize(width: 29, height: 29)

        imageLayer.frame = CGRect(x: 0, y: 0, width: targetSize.width, height: targetSize.height)
        imageLayer.contents = cgImage
        imageLayer.masksToBounds = true
        imageLayer.cornerRadius = targetSize.width / 2
        imageLayer.borderWidth = width
        imageLayer.borderColor = UIColor.mainAccent.cgColor
        
        UIGraphicsBeginImageContextWithOptions(targetSize, false, scale)
        imageLayer.render(in: UIGraphicsGetCurrentContext()!)
        let roundedImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        
        return roundedImage ?? UIImage()
    }
    
}

您可以修改扩展方法以传递您需要的参数。

您当前所做的是更改图像的呈现方式,而不更改图像本身。 您需要创建一个位图上下文(请参阅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)
}
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM