CGContextRef getting corrupted in plugins
Here's a picture of one of the stranger problems I've had:
I'm using a plugin architecture to draw things in Core Graphics. The host app creates a context that is passed to the plugin, which draws into the context and sends it back. Here this was done multiple times to draw multiple objects (though just for demonstration, it happens even with just one object). The results are converted to CGImageRefs
and placed on a canvas (another CGContext
) which is in turn converted to an NSImage
and displayed.
The problem, as you can see, is that it often returns a slightly corrupted version. It's different every time. The other strange thing is that the boxes are supposed to have 50% alpha, but they don't (except for the top of the second box, which looks like it's about the right color for that). Interestingly, the background (drawn in Core Graphics within the host app) isn'开发者_运维技巧t ever corrupted, so it's not a problem with the CGImage
to NSImage
conversion or anything like that.
The even weirder part is that I've tried having the plugin export an NSImage
directly, and it had the exact same effect, maybe a little worse even. It seems to me like the problem is with drawing anything with Core Graphics in a plugin. Has anybody else run into this, or, even better, has anybody else found a solution?
Here's the host code if it helps:
CGContextRef tC = [TC CreateBitmapContextWithWidth:720 Height:480]; //Sets up context
CGContextSetRGBFillColor(tC, 1.0, 1.0, 1.0, 1.0);
CGContextFillRect(tC, CGRectMake(0, 0, size.width, size.height)); //Draws Background
for(CDObject *cdo in [[TC DocStorage] Objects]){ //Draws each object
CGContextRef pluginContext = [TC CreateBitmapContextWithWidth:cdo.width Height:cdo.height]; //Creates context to send to plugin
[[[TC plugins] objectForKey:[cdo Type]] drawObject:cdo inContext:pluginContext]; //Pass context through appropriate plugin (based on type)
CGImageRef gci = CGBitmapContextCreateImage(pluginContext); //Create image of context
CGContextDrawImage(tC, CGRectMake(cdo.x, cdo.y, CGImageGetWidth(gci), CGImageGetHeight(gci)), gci); //Draw image to canvas
CGImageRelease(gci);
char *bitmapData = CGBitmapContextGetData(pluginContext);
CGContextRelease (pluginContext);
if (bitmapData) free(bitmapData);
}
CGImageRef fi = CGBitmapContextCreateImage(tC); //Get image of canvas
NSImage *tImage = [CGImagetoNSImage(fi) autorelease]; //Use external function to convert to NSImage
CGImageRelease(fi);
char *bitmapData = CGBitmapContextGetData(tC);
CGContextRelease (tC);
if (bitmapData) free(bitmapData);
return tImage; //Return the image to be drawn in a view
And the plugin code:
- (void)drawObject:(CDObject*)cdo inContext:(CGContextRef)ctx {
CGContextSetRGBFillColor(ctx, 1.0, 0.0, 0.0, 0.5);
CGContextFillRect(ctx, CGRectMake(0, 0, cdo.width, cdo.height));}
精彩评论