【问题标题】:Access CGImageRef underlying bytes and modify?访问 CGImageRef 底层字节并修改?
【发布时间】:2016-11-01 08:33:28
【问题描述】:

我正在开发一个进行像素级图像处理的 OSX 应用程序。我正在使用以下代码将像素颜色分量 (RGBA) 作为常规字节转换为 uint8 指针。

NSImage *image = self.iv.image;
NSRect imageRect = NSMakeRect(0, 0, image.size.width, image.size.height);
CGImageRef cgImage = [image CGImageForProposedRect:&imageRect context:NULL hints:nil];
NSData *data = (NSData *)CFBridgingRelease(CGDataProviderCopyData(CGImageGetDataProvider(cgImage)));
   uint8 *pixels = (uint8 *)[data bytes];

此时我在以下位置应用了一些字节级别的更改:

 for (int i = 0; i < [data length]; i += 4) { ... }

更改此内存区域似乎对原始CGImageRef 没有任何影响(当时显示在NSImageView 中)。我必须执行以下操作才能看到相应的图像更新:

 CGImageRef newImageRef = CGImageCreate (width,
                                           height,
                                           bitsPerComponent,
                                           bitsPerPixel,
                                           bytesPerRow,
                                           colorspace,
                                           bitmapInfo,
                                           provider,
                                           NULL,
                                           false,
                                           kCGRenderingIntentDefault);

   NSSize size = NSMakeSize(CGImageGetWidth(newImageRef),
                            CGImageGetHeight(newImageRef));

   NSImage * newIm = [[NSImage alloc] initWithCGImage:newImageRef size:size];

   self.iv.image = newIm;

换句话说,我回来修改的字节只是原始字节的副本,大概是CGDataProviderCopyData(CGImageGetDataProvider(cgImage)的结果。

我的问题如下。有没有一种方法可以直接访问 CGImageRef 的底层字节,这样当我修改它们时,图像会在我操作它们时在屏幕上更新?

【问题讨论】:

    标签: macos image-processing core-graphics cgimage


    【解决方案1】:

    没有。 CGImages 是不可变的。它们一经创建就无法更改。

    在您的代码中,对[data bytes] 的调用提供了一个指向const void 的指针。您已经抛弃了const,它可以在没有警告的情况下进行编译,但这违反了设计合同。写入支持数据提供者的缓冲区是不合法的,并且不能保证有效,即使您从中创建了一个新的CGImage

    我还要指出,缓冲区中数据的格式可能与您的预期完全不同。没有充分的理由期望数据是每像素 32 位,RGBA 与 BGRA 与 ARGB 与 ...,或其他任何东西。

    我强烈建议您阅读10.6 AppKit release notes 中有关各种图像对象的部分。向下滚动到“NSImage、CGImage 和 CoreGraphics 阻抗匹配”并通读以下所有与图像相关的部分,直到点击“NSComboBox”。 “NSBitmapImageRep:CoreGraphics 阻抗匹配和性能说明”部分对于您的目的来说是更重要的部分。

    除此之外,您可以维护一个像素缓冲区,以您喜欢的任何格式分配给自己。然后,当你想要一个CGImage 时,从缓冲区创建它,用它绘制,然后丢弃它。任何像素操作都将在该缓冲区上完成。

    【讨论】:

      猜你喜欢
      • 2012-11-25
      • 2018-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多