Does anyone know why CGContextDrawImage
would be drawing my image upside down? I am loading an image in from my application:
UIImage *image = [UIImage imageNamed:@"testImage.png"];
And then simply asking core graphics to draw it to my context:
CGContextDrawImage(context, CGRectMake(0, 0, 145, 15), image.CGImage);
It renders in the right place, and dimensions, but the image is upside down. I must be missing something really obvious here?
drawInRect
is certainly the way to go. Here's another little thing that will come in way useful when doing this. Usually the picture and the rectangle into which it is going to go don't conform. In that casedrawInRect
will stretch the picture. Here's a quick and cool way to make sure that the picture's aspect ration isn't changed, by reversing the transformation (which will be to fit the whole thing in):Swift 3 CoreGraphics Solution
If you want to use CG for whatever your reason might be, instead of UIImage, this Swift 3 construction based on previous answers did solve the issue for me:
Relevant Quartz2D docs: https://developer.apple.com/library/ios/documentation/2DDrawing/Conceptual/DrawingPrintingiOS/GraphicsDrawingOverview/GraphicsDrawingOverview.html#//apple_ref/doc/uid/TP40010156-CH14-SW4
Even after applying everything I have mentioned, I've still had dramas with the images. In the end, i've just used Gimp to create a 'flipped vertical' version of all my images. Now I don't need to use any Transforms. Hopefully this won't cause further problems down the track.
Quartz2d uses a different co-ordinate system, where the origin is in the lower left corner. So when Quartz draws pixel x[5], y[10] of a 100 * 100 image, that pixel is being drawn in the lower left corner instead of the upper left. Thus causing the 'flipped' image.
The x co-ordinate system matches, so you will need to flip the y co-ordinates.
This means we have translated the image by 0 units on the x axis and by the images height on the y axis. However, this alone will mean our image is still upside down, just being drawn "image.size.height" below where we wish it to be drawn.
The Quartz2D programming guide recommends using ScaleCTM and passing negative values to flip the image. You can use the following code to do this -
Combine the two just before your
CGContextDrawImage
call and you should have the image drawn correctly.Just be careful if your imageRect co-ordinates do not match those of your image, as you can get unintended results.
To convert back the coordinates:
During the course of my project I jumped from Kendall's answer to Cliff's answer to solve this problem for images that are loaded from the phone itself.
In the end I ended up using
CGImageCreateWithPNGDataProvider
instead:This doesn't suffer from the orientation issues that you would get from getting the
CGImage
from aUIImage
and it can be used as the contents of aCALayer
without a hitch.