Question

I am trying to apply some transformations on images using a CGContextRef. I am using CGContextTranslateCTM, CGContextScaleCTM and CGContextRotateCTM functions, but to keep things simple lets focus on just the first. I was wondering why the following code produces exactly the original image?! Am I missing something?

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

CGContextRef g = CGBitmapContextCreate((void*) pixelData, 
                                                       width, 
                                                       height, 
                                                       RGBA_8_BIT, 
                                                       bytesPerRow, 
                                                       colorSpace, 

                                                   kCGImageAlphaPremultipliedLast);

CGContextSetShouldAntialias(g, YES);

CGContextSetInterpolationQuality(g, kCGInterpolationHigh);

CGContextTranslateCTM( g,translateX, translateY );


CGImageRef tempImg  = CGBitmapContextCreateImage (g);
CGContextDrawImage( g, CGRectMake (0, 0, width, height), tempImg );
CGContextRelease(g);
CGColorSpaceRelease( colorSpace );

Also, after translating, how to draw another image over this one but with partial transparency (eg alpha = 0.5).

I searched alot but didn't find an answer, any help is appreciated... :)

Please note that I am creating the context from pixelData, and that tempImg is created after the translation. There is nothing wrong in the initialization, as the original image is being currently produced, but the issue is with the translation I suppose..

Was it helpful?

Solution

Transformations to the graphics state only affect subsequent drawing operations - they don't change the existing image data. If you want to apply transforms to an image, try something like this:

  1. Create an empty CGContext (on iPhone, use UIGraphicsBeginImageContext)
  2. Translate, scale, or rotate it's graphics state
  3. Draw existing image into it.
  4. Get image from new CGContext (on iPhone, use UIGraphicsGetImageFromCurrentImageContext)

When you perform step 3, the existing image is drawn into your new graphics context with the transformations applied. The trick here is that in order to apply the transformations, we have to actually draw something.

You can do some really cool things with transformations this way. You can draw half your image, apply some transforms, and draw some more.

OTHER TIPS

As noted in other answers, transformations only apply to subsequent drawing operations; they don't affect the pixel buffer you started with.

So you need a drawing operation. The solution is to create a CGImage; drawing that image is a drawing operation, so it will be subject to the current transformation matrix (CTM).

Step-by-step:

  1. Create the context with empty pixel data. (If you pass NULL for the buffers, Quartz should create them for you. That works on the Mac, anyway.)
  2. Create the image with the pixel data you want to draw transformed.
  3. Transform the CTM in the context.
  4. Draw the image.

You have to call CGBitmapContextCreateImage() after you draw the image.

Then you can draw another image on top of the first one and call CGBitmapContextCreateImage() again to get the second image. You can set the alpha using CGContextSetAlpha(ctx, alphaValue);

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top