CGContextRef 在插件中被损坏

发布于 2024-08-31 21:18:44 字数 2144 浏览 8 评论 0原文

这是我遇到的一个奇怪问题的图片:

screenshot

我正在使用插件架构来绘制内容核心显卡。主机应用程序创建一个传递给插件的上下文,插件绘制上下文并将其发送回。在这里,这是多次完成以绘制多个对象(尽管只是为了演示,即使只有一个对象也会发生)。结果被转换为 CGImageRefs 并放置在画布上(另一个 CGContext ),画布又被转换为 NSImage 并显示。

正如您所看到的,问题在于它经常返回一个稍微损坏的版本。每次都不一样。另一个奇怪的事情是,这些盒子应该有 50% 的 alpha,但它们没有(除了第二个盒子的顶部,它看起来颜色合适)。有趣的是,背景(在主机应用程序内的 Core Graphics 中绘制)从未被损坏,因此 CGImage 到 NSImage 转换或类似的问题不是问题。

更奇怪的是,我尝试让插件直接导出 NSImage ,它具有完全相同的效果,甚至可能更糟。在我看来,问题在于在插件中使用 Core Graphics 绘制任何内容。有其他人遇到过这个问题吗?或者更好的是,有其他人找到解决方案吗?

这是主机代码(如果有帮助):

 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

以及插件代码:

 - (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));}

Here's a picture of one of the stranger problems I've had:

screenshot

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));}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文