使用平移、旋转和捏合手势编辑后如何保存 UIImage

Posted

技术标签:

【中文标题】使用平移、旋转和捏合手势编辑后如何保存 UIImage【英文标题】:How to save UIImage after Editing with Pan, Rotate and Pinch Gesture 【发布时间】:2017-10-09 11:47:29 【问题描述】:

我正在尝试使用 UIPanGesture、UIRotateGesture 和 UIPinchGesture 来实现编辑图像。编辑后,我希望保存编辑后的 ​​UIImage。

我已经完成了编辑图像功能。

但我不知道如何像原生 ios Camera App 一样完美保存。

平移手势工作正常。

我的问题是旋转和缩放。

如何设置 UIImage 的中心锚点?

当我从变换信息中保存 UIImage 时,UIImage 的结果看起来不同,因为旋转和缩放,然后它总是基于 (0,0) 应用

 @IBAction func showEditedImage(_ sender: Any) 


        let image = preview.image!
        var drawingRect : CGRect = CGRect.zero
        drawingRect.size = preview.frame.size

        let scale = transformedImg.frame.width / (preview.image?.size.width)!
        let height = (preview.image?.size.height)! * scale

        UIGraphicsBeginImageContextWithOptions(CGSize(width: transformedImg.frame.width, height: height), false, 0)

        let context = UIGraphicsGetCurrentContext()
        context!.concatenate(preview.transform)

        image.draw(in: CGRect(x: 0, y: 0, width: transformedImg.frame.width, height: height))
        resultsImg = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext();

        transformedImg.image = resultsImg
    

这是我所有的代码。

import UIKit

class ViewController: UIViewController 


    @IBOutlet weak var preview: UIImageView!
    @IBOutlet weak var frame: UIView!
    @IBOutlet weak var transformedImg: UIImageView!

    //save edited image
    var resultsImg : UIImage!

    override func viewDidLoad() 

        resultsImg = UIImage()
        super.viewDidLoad()
    


       @IBAction func showEditedImage(_ sender: Any) 


    let image = preview.image!
    var drawingRect : CGRect = CGRect.zero
    drawingRect.size = preview.frame.size

    let scale = transformedImg.frame.width / (preview.image?.size.width)!
    let height = (preview.image?.size.height)! * scale

    UIGraphicsBeginImageContextWithOptions(CGSize(width: transformedImg.frame.width, height: height), false, 0)

    let context = UIGraphicsGetCurrentContext()
    context!.concatenate(preview.transform)

    image.draw(in: CGRect(x: 0, y: 0, width: transformedImg.frame.width, height: height))
    resultsImg = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext();

    transformedImg.image = resultsImg


    @IBAction func pinchaction(_ sender: UIPinchGestureRecognizer) 

        preview.transform = preview.transform.scaledBy(x: sender.scale, y: sender.scale)

        sender.scale = 1
    

    @IBAction func rotateaction(_ sender: UIRotationGestureRecognizer) 

        let rotate = sender.rotation
        preview.transform = preview.transform.rotated(by: rotate)


        sender.rotation = 0

    

    @IBAction func panaction(_ sender: UIPanGestureRecognizer) 

        let points = sender.translation(in: self.frame)
        preview.transform = preview.transform.translatedBy(x: points.x, y: points.y)

        let translatedCenter = CGPoint(x:self.frame.center.x + points.x, y:self.frame.center.y + points.y)

        sender.setTranslation(CGPoint.zero, in: self.frame)

    




环境:XCode9 + Swift 4

2017 年 10 月 14 日更新

我的问题解决了

 @IBAction func showEditedImage(_ sender: Any) 

        let image = preview.image!
        var drawingRect : CGRect = CGRect.zero
        drawingRect.size = preview.frame.size

        let scale = transformedImg.frame.width / (preview.image?.size.width)!
        let height = (preview.image?.size.height)! * scale


        UIGraphicsBeginImageContextWithOptions(CGSize(width: transformedImg.frame.width, height: height), false, 0)

        let context = UIGraphicsGetCurrentContext()

        //Set Center Position before Scale, Rotate Image
        context?.translateBy(x: transformedImg.frame.width / 2, y: height / 2)

        //Applied Translate, Scale, Rotate
        context!.concatenate(preview.transform)

        context?.translateBy(x: -(transformedImg.frame.width / 2), y: -(height / 2))

        image.draw(in: CGRect(x: 0, y: 0, width: transformedImg.frame.width, height: height))
        resultsImg = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext();

        transformedImg.image = resultsImg
    

【问题讨论】:

【参考方案1】:

我有一个名为 myView 的 UIIView,具有透明背景,我将 UIImageView 作为子视图添加到 myView 中,然后我在 myView 上应用 UIRotationGestureRecognizer 以便在此处旋转我的图像是我的 UIRotationGestureRecognizer 的 @IBAction 函数......

@IBAction func rotateGesture(sender: UIRotationGestureRecognizer) 
    if let view = sender.view 
        view.transform = CGAffineTransformRotate(view.transform, sender.rotation)
        sender.rotation = 0
    

【讨论】:

【参考方案2】:

我已经在 Swift 2.3 中实现了这个功能,所以你可以在 Swift 4 中转换后使用它。

fun SaveImage()

    if myImageView != nil
    
       // You should hide here your Buttons,Labels, etc.

    let layer = UIApplication.sharedApplication().keyWindow!.layer
    let scale = UIScreen.mainScreen().scale
    UIGraphicsBeginImageContextWithOptions(layer.frame.size, false, scale);

    layer.renderInContext(UIGraphicsGetCurrentContext()!)
    let screenshot = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

       // Now here you can UnHide(Show) your Buttons,Labels,etc
    UIImageWriteToSavedPhotosAlbum(screenshot, nil, nil, nil)
    let alert = UIAlertView(title: "Alert !!",
        message: "Your image has been saved to Photo Library",
        delegate: nil,
        cancelButtonTitle: "OK")
    alert.show()

    
    else
    
        let alert = UIAlertView(title: "Alert !!",
            message: "Please first Select/Capture Image",
            delegate: nil,
            cancelButtonTitle: "OK")
        alert.show()
    


【讨论】:

感谢回复~! 是的,你帮助了我。谢谢,但我的问题是如何将图像的原点设置为中心位置并使用变换方法旋转图像。我尝试旋转变换,但它基于图像的左上角而不是居中旋转。【参考方案3】:

我遇到了类似的问题,不同之处在于我不想以与原始图像相同的比例保存编辑后的图像。

在尝试调整上述解决方案后,我突然想到,对包含旋转/缩放的 UIImageView 的 UIView 进行快照会更容易。

我使用了这里提出的解决方案的一个版本:https://***.com/a/18925301/10449843

在 Swift 4 中:

private func getEditedImage(container: UIView) -> UIImage? 
    UIGraphicsBeginImageContextWithOptions(container.bounds.size, false, 0.0)
    drawHierarchy(in: container.bounds, afterScreenUpdates: true)
    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return image

【讨论】:

以上是关于使用平移、旋转和捏合手势编辑后如何保存 UIImage的主要内容,如果未能解决你的问题,请参考以下文章

旋转后平移手势行为不正确

如果视图注册平移手势,则捏合手势不起作用

手势识别(拖动,旋转,捏合)

快速的触摸和手势

UIImageView 上的捏合、平移和双击手势

同时捏合、拖动和平移