Nikkie
Nikkie

Reputation: 93

Draw image with CGAffineTransform and CGContextDrawImage

I want to draw UIimage with CGAffineTransform but It gives wrong output with CGContextConcatCTM

I have try with below code :

 CGAffineTransform t = CGAffineTransformMake(1.67822, -1.38952, 1.38952, 1.67822, 278.684, 209.129); // transformation of uiimageview
 UIGraphicsBeginImageContext(CGSizeMake(1024, 768));
 CGContextRef imageContext = UIGraphicsGetCurrentContext();
 CGContextDrawImage(imageContext, dragView.frame, dragView.image.CGImage);
 CGContextConcatCTM(imageContext, t);

 NSLog(@"\n%@\n%@", NSStringFromCGAffineTransform(t),NSStringFromCGAffineTransform(CGContextGetCTM(imageContext)));

Output :

  [1.67822, -1.38952, 1.38952, 1.67822, 278.684, 209.129] // imageview transformation
  [1.67822, 1.38952, 1.38952, -1.67822, 278.684, 558.871] // drawn image transformation

CGAffineTransform CGAffineTransformMake (
   CGFloat a,
   CGFloat b,
   CGFloat c,
   CGFloat d,
   CGFloat tx,
   CGFloat ty
);

Parameter b, d and ty changed, How to solve this?

Upvotes: 0

Views: 946

Answers (1)

Peter Hosey
Peter Hosey

Reputation: 96373

There is no problem to solve. Your log output is correct.

Comparing the two matrixes, the difference between the two is this:

  • scale vertically by -1 (which affects two of the first four members)
  • translate vertically by 349.742 (which affects the last member)

I'm going to take a guess and say your view is about 350 points tall. Am I right? Actually, the 349.742 is weird, since you set the context's height to 768. It's almost half (perhaps because the anchor point is centered?), but well short, and cutting off the status bar wouldn't make sense here (and wouldn't account for a 68.516-point difference). So that is a puzzle. But, what follows is still true:

A vertical scale and translate is how you would flip a context. This context has gone from lower-left origin to upper-left origin, or vice versa.

That happened before you concatenated your (unexplained, hard-coded) matrix in. Assuming you didn't flip the context yourself, it probably came that way (I would guess as a UIKit implementation detail).

Concatenation (as in CGContextConcatCTM) does not replace the old transformation matrix with the new one; it is matrix multiplication. The matrix you have afterward is the product of both the matrix you started with and the one you concatenated onto it. The resulting matrix is both flipped and then… whatever your matrix does.

You can see this for yourself by simply getting the CTM before you concatenate your matrix onto it, and logging that. You should see this:

[0, -1, 0, -1, 0, 349.742]

See also “The Math Behind the Matrices” in the Quartz 2D Programming Guide.

Upvotes: 1

Related Questions