Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Saving edited image after zooming, rotating and panning

Tags:

ios

swift

I've created Swift version of this class: https://github.com/bennythemink/ZoomRotatePanImageView/blob/master/ZoomRotatePanImageView.m Works nice. Now I want to save modified image to file. The thing is I want to save it in full resolution and also I want to save area which is only visible to user.

Let me show you simple example:

enter image description here

This is how it looks in my app. Image is one a few samples in iOS simulator. Most of it is out of screen. I want only visible part.

After saving without cropping it looks like this:

enter image description here

So far so good after clipping it'd be nice.

But now let's make some changes:

enter image description here

After saving:

enter image description here

Looks like it's transformed by wrong pivot. How can I fix it?

Here's my code for saving:

UIGraphicsBeginImageContextWithOptions(image.size, false, 0)
let context = UIGraphicsGetCurrentContext()
let transform = imageView.transform
let imageRect = CGRectMake(0, 0, image.size.width, image.size.height)

CGContextSetFillColorWithColor(context, UIColor.blueColor().CGColor) //for debugging
CGContextFillRect(context, imageRect)

CGContextConcatCTM(context, transform)

image.drawInRect(imageRect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()

There's a simpler method to achieve it:

UIGraphicsBeginImageContextWithOptions(imageContainer.bounds.size, false, 0)
self.imageContainer.drawViewHierarchyInRect(imageContainer.bounds, afterScreenUpdates: true)
let screenshot = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext() 

However output image has size of the view not an actual image and I want it in full resolution.

like image 357
Makalele Avatar asked Feb 08 '16 23:02

Makalele


1 Answers

Updated code to work with image of any size :

let boundsScale = imageView.bounds.size.width / imageView.bounds.size.height
let imageScale = image!.size.width / image!.size.height

let size = (image?.size)!

var canvasSize = size

if boundsScale > imageScale {
    canvasSize.width =  canvasSize.height * boundsScale
}else{
    canvasSize.height =  canvasSize.width / boundsScale
}

let xScale = canvasSize.width / imageView.bounds.width
let yScale = canvasSize.height / imageView.bounds.height

let center = CGPointApplyAffineTransform(imageView.center, CGAffineTransformScale(CGAffineTransformIdentity, xScale, yScale))

let xCenter = center.x
let yCenter = center.y

UIGraphicsBeginImageContextWithOptions(canvasSize, false, 0);
let context = UIGraphicsGetCurrentContext()!

//Apply transformation
CGContextTranslateCTM(context, xCenter, yCenter)

CGContextConcatCTM(context, imageView.transform)

CGContextTranslateCTM(context, -xCenter, -yCenter)

var drawingRect : CGRect = CGRectZero
drawingRect.size = canvasSize

//Transaltion
drawingRect.origin.x = (xCenter - size.width*0.5)
drawingRect.origin.y = (yCenter - size.height*0.5)

//Aspectfit calculation
if boundsScale > imageScale {
    drawingRect.size.width =  drawingRect.size.height * imageScale
}else{
    drawingRect.size.height = drawingRect.size.width / imageScale
}

image!.drawInRect(drawingRect)

let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

Simulator screen shot Simulator

Saved image Saved

like image 137
Arun Ammannaya Avatar answered Oct 20 '22 00:10

Arun Ammannaya