首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用UIBezierPath快速裁剪图像

使用UIBezierPath快速裁剪图像
EN

Stack Overflow用户
提问于 2018-04-16 16:47:26
回答 3查看 2.6K关注 0票数 1

我想从图像中裁剪bezier路径。由于某些原因,图像仍然是未剪裁的。我如何定位路径,使其被正确剪切?

代码语言:javascript
运行
复制
extension UIImage {

func imageByApplyingMaskingBezierPath(_ path: UIBezierPath, _ pathFrame: CGFrame) -> UIImage {

    UIGraphicsBeginImageContext(self.size)
    let context = UIGraphicsGetCurrentContext()!
    context.saveGState()

    path.addClip()
    draw(in: CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height))

    let maskedImage = UIGraphicsGetImageFromCurrentImageContext()!

    context.restoreGState()
    UIGraphicsEndImageContext()

    return maskedImage
}

}

EN

回答 3

Stack Overflow用户

发布于 2018-04-16 17:05:37

您需要将path.cgPath添加到当前上下文中,还需要删除context.saveGState()context.restoreGState()

使用此代码

代码语言:javascript
运行
复制
func imageByApplyingMaskingBezierPath(_ path: UIBezierPath, _ pathFrame: CGRect) -> UIImage {

            UIGraphicsBeginImageContext(self.size)
            let context = UIGraphicsGetCurrentContext()!

            context.addPath(path.cgPath)
            context.clip()
            draw(in: CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height))

            let maskedImage = UIGraphicsGetImageFromCurrentImageContext()!

            UIGraphicsEndImageContext()

            return maskedImage
        }

使用it的

代码语言:javascript
运行
复制
let testPath = UIBezierPath()
testPath.move(to: CGPoint(x: self.imageView.frame.width / 2, y: self.imageView.frame.height))
testPath.addLine(to: CGPoint(x: 0, y: 0))
testPath.addLine(to: CGPoint(x: self.imageView.frame.width, y: 0))
testPath.close()

self.imageView.image = UIImage(named:"Image")?.imageByApplyingMaskingBezierPath(testPath, self.imageView.frame)

结果

票数 4
EN

Stack Overflow用户

发布于 2018-04-16 16:59:51

你可以试着这样做。

代码语言:javascript
运行
复制
 var path = UIBezierPath()
 var shapeLayer = CAShapeLayer()
 var cropImage = UIImage()


 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = touches.first as UITouch?{
        let touchPoint = touch.location(in: self.YourimageView)
        print("touch begin to : \(touchPoint)")
        path.move(to: touchPoint)
    }
}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = touches.first as UITouch?{
        let touchPoint = touch.location(in: self.YourimageView)
        print("touch moved to : \(touchPoint)")
        path.addLine(to: touchPoint)
        addNewPathToImage()
    }
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = touches.first as UITouch?{
        let touchPoint = touch.location(in: self.YourimageView)
        print("touch ended at : \(touchPoint)")
        path.addLine(to: touchPoint)
        addNewPathToImage()
        path.close()
    }
}
 func addNewPathToImage(){
    shapeLayer.path = path.cgPath
    shapeLayer.strokeColor = strokeColor.cgColor
    shapeLayer.fillColor = UIColor.clear.cgColor
    shapeLayer.lineWidth = lineWidth
    YourimageView.layer.addSublayer(shapeLayer)
}
   func cropImage(){

    UIGraphicsBeginImageContextWithOptions(YourimageView.bounds.size, false, 1)
    tempImageView.layer.render(in: UIGraphicsGetCurrentContext()!)
    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    self.cropImage = newImage!
    }


    @IBAction func btnCropImage(_ sender: Any) {
         cropImage()
    }

在特定按钮操作上绘制路径后,只需调用您的imageByApplyingMaskingBezierPath

票数 0
EN

Stack Overflow用户

发布于 2021-01-02 05:42:38

以下是基于UIBezierPath从图像中获取剪辑的Swift代码,它的实现速度非常快。如果图像已经显示在屏幕上,则此方法有效,这种情况最常见。合成的图像将有一个透明的背景,这是大多数人在剪辑照片图像的一部分时想要的。您可以在本地使用得到的裁剪图像,因为您将把它放在我称为imageWithTransparentBackground的UIImage对象中。这段非常简单的代码还向您展示了如何将图像保存到相机胶卷,以及如何将其直接放到粘贴板中,以便用户可以直接将该图像粘贴到文本消息中,粘贴到便笺、电子邮件等中。请注意,为了将图像写入相机胶卷,您需要编辑info.plist并提供原因,以了解“隐私-图片库使用说明”

代码语言:javascript
运行
复制
import Photos // Needed if you save to the camera roll

提供用于裁剪的UIBezierPath。这是我对其中之一的声明。

代码语言:javascript
运行
复制
let clipPath = UIBezierPath()

使用一些命令组合,用您自己的一些逻辑填充clipPath。下面是我在绘图逻辑中使用的一些代码。为aPointOnScreen提供CGPoint等效项,等构建相对于主屏幕的路径,因为self.view是此应用程序的ViewController (对于此代码),并且self.view.layer通过clipPath呈现。

代码语言:javascript
运行
复制
clipPath.move(to: aPointOnScreen)
clipPath.addLine(to: otherPointOnScreen)
clipPath.addLine(to: someOtherPointOnScreen)

clipPath.close()

此逻辑使用所有设备屏幕作为上下文大小。为此声明了一个CGSize。fullScreenX和fullScreenY是我已经捕获了设备宽度和高度的变量。如果你正在裁剪的照片已经放大,并且在整个屏幕上显示的大小足够大,那就更好了。你所看到的就是你所得到的。

代码语言:javascript
运行
复制
let mainScreenSize =  CGSize(width: fullScreenX, height: fullScreenY)

// Get an empty context
UIGraphicsBeginImageContext(mainScreenSize)
// Specify the clip path
clipPath.addClip()
// Render through the clip path from the whole of the screen.
self.view.layer.render(in: UIGraphicsGetCurrentContext()!)
// Get the clipped image from the context
let image : UIImage = UIGraphicsGetImageFromCurrentImageContext()!
// Done with the context, so end it.
UIGraphicsEndImageContext()
                
// The PNG data has the alpha channel for the transparent background
let imageData = image.pngData()
// Below is the local UIImage to use within your code
let imageWithTransparentBackground = UIImage.init(data: imageData!)
// Make the image available to the pasteboard.
UIPasteboard.general.image = imageWithTransparentBackground
// Save the image to the camera roll.
PHPhotoLibrary.shared().performChanges({
                    PHAssetChangeRequest.creationRequestForAsset(from: imageWithTransparentBackground!)
                }, completionHandler: { success, error in
                    if success {
                        //
                    }
                    else if let error = error {
                        //
                    }
                    else {
                        //
                    }
                })
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49853122

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档