问题
I'm trying to implement edit image using UIPanGesture, UIRotateGesture, and UIPinchGesture. After editing, I wish to save edited UIImage.
I'm done edit image functionality.
But I don't know How to save exactly perfect like native iOS Camera App.
Pan Gesture is working fine.
My problem is Rotate and Scale.
How to set center anchor point of UIImage?
When I saved UIImage from transform information then the result of UIImage is looks different because Rotate and Scale, then It always applied based on (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
}
Here is all of my code.
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)
}
}
Environment : XCode9 + Swift 4
Updated 14 October 2017
I solved my problem
@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:
I have a UIIView named myView with Transparent background and i add UIImageView into myView as subview then i apply UIRotationGestureRecognizer on myView so that rotate my Image here is my @IBAction func of UIRotationGestureRecognizer....
@IBAction func rotateGesture(sender: UIRotationGestureRecognizer) {
if let view = sender.view {
view.transform = CGAffineTransformRotate(view.transform, sender.rotation)
sender.rotation = 0
}
}
回答2:
I have implement this function in Swift 2.3 so you can use it after convert it in 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:
I had a similar problem, with the difference that I didn't want to save the edited image in the same proportions as the original image.
After trying to adapt the solution above, it occurred to me that it would be easier to take a snapshot of the UIView that contains the rotated/zoomed UIImageView.
I used a version of the solution proposed here: https://stackoverflow.com/a/18925301/10449843
In 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
}
来源:https://stackoverflow.com/questions/46645731/how-to-save-uiimage-after-editing-with-pan-rotate-and-pinch-gesture