PDA

View Full Version : [Resolved] CGBitmapContextCreate oddness




tomaki
Mar 14, 2012, 04:20 PM
Hey all,

I seem to be having a pretty weird problem with my Mac quartz graphics project. So basically I have a cgContext initialized like this:

canvasContext = CGBitmapContextCreate(NULL,
dim.width,
dim.height,
8,
0,
CGColorSpaceCreateWithName( kCGColorSpaceGenericRGB),
kCGImageAlphaNoneSkipLast
);

CGContextSetBlendMode(canvasContext, kCGBlendModeNormal); // possibly irrelevant?
CGContextSetRGBFillColor(canvasContext, 1.0, 1.0, 1.0, 1.0);
CGContextFillRect( canvasContext, CGRectMake(0,0,dim.width, dim.height) );

... which should initialize a RGB-context with a generic RGB color profile and then make it white. Initializing the cgContext seems to work, and I can draw it to the screen from my custom NSView drawrect, but I can't seem to be able to modify the contents of that cgContext. No matter what I do, it stays black :confused: Fillrect doesn't work, drawing to it with CGContextDrawLayerAtPoint doesn't work etc.

I've wasted enough time with this bugger already so I thought that I'd ask if anyone else had a clue what might be going on.

Thanks!



KnightWRX
Mar 14, 2012, 05:25 PM
Why are you passing NULL as the first parameter ?

Also, how do you swap this context onto the screen ?

tomaki
Mar 14, 2012, 05:50 PM
Why are you passing NULL as the first parameter ?

From the reference:

"In iOS 4.0 and later, and Mac OS X v10.6 and later, you can pass NULL if you want Quartz to allocate memory for the bitmap. This frees you from managing your own memory, which reduces memory leak issues."


Also, how do you swap this context onto the screen ?

In my custom NSView drawrect:


CGContextDrawImage( [[NSGraphicsContext currentContext] graphicsPort], tmprect, CGBitmapContextCreateImage( canvasContext ));


The variable tmprect is just a normal CGRect with appropriate values.

KnightWRX
Mar 14, 2012, 06:10 PM
From the reference:

"In iOS 4.0 and later, and Mac OS X v10.6 and later, you can pass NULL if you want Quartz to allocate memory for the bitmap. This frees you from managing your own memory, which reduces memory leak issues."




In my custom NSView drawrect:


CGContextDrawImage( [[NSGraphicsContext currentContext] graphicsPort], tmprect, CGBitmapContextCreateImage( canvasContext ));


The variable tmprect is just a normal CGRect with appropriate values.

Maybe you should post the entire drawRect method. How do you know canvasContext is still pointing to your bitmap context ? Is the bitmap context created and modified in the drawRect method directly or elsewhere ?

You've not given us a lot to work with here.

KnightWRX
Mar 14, 2012, 06:50 PM
I got it to work fine using the following code :

- (void)drawRect:(NSRect)dirtyRect
{
CGContextRef cgcontext = CGBitmapContextCreate(NULL, self.bounds.size.width, self.bounds.size.height, 8, 4 * self.bounds.size.width, CGColorSpaceCreateDeviceRGB(), kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedFirst);

CGContextSetRGBFillColor(cgcontext, 1.0, 0.0, 0.0, 1.0);
CGContextFillRect(cgcontext, CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height) );
CGContextDrawImage([[NSGraphicsContext currentContext] graphicsPort], CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height), CGBitmapContextCreateImage(cgcontext));

CGContextRelease(cgcontext);
}


Displays a nice big Red view. Things to check for : your dim variable, is it properly initialized with proper height/width values ? Your bitmap context : is it actually created and not just pointing to null ?

Those were the glaring points I got caught up on (initWithFrame was never called on my custom View so my custom width/height variables were never initialized, and my ColorSpace and flags weren't matching up, resulting in the context not getting created).

Run your code through the debugger, watch the console for error messages and you should see why yours isn't working.

tomaki
Mar 15, 2012, 03:34 AM
I got it to work fine using the following code :


Thanks, so did I! With that code I was able to isolate and fix the problem.

I was kinda hoping ( and assuming ) that the CGBitmapContextCreateImage would create an image which uses the given cgContext as it's own cgcontext. So if I altered the cgcontext, also the contents of the imageRef would change. But instead it creates a duplicate. And because I wasn't running that CGBitmapContextCreateImage after each alteration, I wasn't seeing changes.

Stupid mistake, but those happen every now and then. At least I'm now able to continue coding. So thanks for the help!