It\'s really a pain, but always when I draw an UIImage in -drawRect:, it\'s upside-down.
When I flip the coordinates, the image draws correctly, but at the cost of a
It's really a pain, but always when I draw an UIImage in -drawRect:, it's upside-down.
Are you telling the UIImage to draw, or getting its CGImage and drawing that?
As noted in “Drawing to a Graphics Context on iPhone OS”, UIImages are aware of the difference in co-ordinate spaces and should draw themselves correctly without you having to flip your co-ordinate space yourself.
You can do that by apply affinetransform on the point you want to convert in UIKit related coordinates. Following is example.
// Create a affine transform object
CGAffineTransform transform = CGAffineTransformMakeScale(1, -1);
// First translate your image View according to transform
transform = CGAffineTransformTranslate(transform, 0, - imageView.bounds.size.height);
// Then whenever you want any point according to UIKit related coordinates apply this transformation on the point or rect.
// To get tranformed point
CGPoint newPointForUIKit = CGPointApplyAffineTransform(oldPointInCGKit, transform);
// To get transformed rect
CGRect newRectForUIKit = CGRectApplyAffineTransform(oldPointInCGKit, transform);
Problem: Origin is at lower-left corner; positive y goes upward (negative y goes downward).
Goal: Origin at upper-left corner; positive y going downward (negative y going upward).
Solution:
The way to do this in code is to translate up by the view bounds' height and scale by (1, -1), in that order.
There are a couple of portions of the Quartz 2D Programming Guide that are relevant to this topic, including “Drawing to a Graphics Context on iPhone OS” and the whole chapter on Transforms. Of course, you really should read the whole thing.
CGImageRef flip (CGImageRef im) {
CGSize sz = CGSizeMake(CGImageGetWidth(im), CGImageGetHeight(im));
UIGraphicsBeginImageContextWithOptions(sz, NO, 0);
CGContextDrawImage(UIGraphicsGetCurrentContext(),
CGRectMake(0, 0, sz.width, sz.height), im);
CGImageRef result = [UIGraphicsGetImageFromCurrentImageContext() CGImage];
UIGraphicsEndImageContext();
return result;
}
Call the above method using the code below: This code deals with getting the left half of an image from an existing UIImageview and setting the thus generated image to a new imageview - imgViewleft
CGContextRef con = UIGraphicsGetCurrentContext();
CGContextDrawImage(con,
CGRectMake(0,0,sz.width/2.0,sz.height),
flip(leftReference));
imgViewLeft = [[UIImageView alloc] initWithImage:UIGraphicsGetImageFromCurrentImageContext()];
The better answer to this problem is to use the UIImage
method drawInRect:
to draw your image. I'm assuming you want the image to span the entire bounds of your view. This is what you'd type in your drawRect:
method.
Instead of:
CGContextRef ctx = UIGraphicsGetCurrentContext();
UIImage *myImage = [UIImage imageNamed:@"theImage.png"];
CGImageRef img = [myImage CGImage];
CGRect bounds = [self bounds];
CGContextDrawImage(ctx, bounds, img);
Write this:
UIImage *myImage = [UIImage imageNamed:@"theImage.png"];
CGRect bounds = [self bounds];
[myImage drawInRect:bounds];