0

これは、24 ビットの BGR イメージを NSView にブリットするために私が思いついた最良のものです。

NSWindow ホストも同じ colorSpace を持つようにすることで、かなりの量の CPU 時間を削減しました。

ここで 4 ~ 5 ピクセルのコピーが行われていると思います。

  1. vImage変換中(必須)
  2. 呼び出しCGDataProviderCreateWithData
  3. 呼び出しCGImageCreate
  4. NSBitmapImageRepビットマップの作成
  5. 最後のブリットでdrawInRect(必須)

誰かがそれを改善するためにチャイムを鳴らしたいですか?

どんな助けでも大歓迎です。

{
   // one-time setup code
   CGColorSpaceRef useColorSpace = nil; 
   int w = 1920;
   int h = 1080;
   [theWindow setColorSpace: [NSColorSpace genericRGBColorSpace]];
   // setup vImage buffers (not listed here)
   // srcBuffer is my 24-bit BGR image (malloc-ed to be w*h*3)
   // dstBuffer is for the resulting 32-bit RGBA image (malloc-ed to be w*h*4)

   ...
   // this is called @ 30-60fps
   if (!useColorSpace)
      useColorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
   vImage_Error err = vImageConvert_BGR888toRGBA8888(srcBuffer, NULL, 0xff, dstBuffer, NO, 0);

   CGDataProviderRef newProvider = CGDataProviderCreateWithData(NULL,dstBuffer->data,w*h*4,myReleaseProvider);
   CGImageRef myImageRGBA = CGImageCreate(w, h, 8, 32, w*4, useColorSpace, kCGBitmapByteOrderDefault | kCGImageAlphaLast, newProvider, NULL, false, kCGRenderingIntentDefault);
   CGDataProviderRelease(newProvider);
   // store myImageRGBA in an array of frames (using NSObject wrappers) for later access (setNeedsDisplay:)
   ... 
}

- (void)drawRect:(NSRect)dirtyRect
{
   // this is called @ 30-60fps
   CGImageRef storedImage = ...;  // retrieve from array
   NSBitmapImageRep *repImg = [[NSBitmapImageRep alloc] initWithCGImage:storedImage];
   CGRect myFrame = CGRectMake(0,0,CGImageGetWidth(storedImage),CGImageGetHeight(storedImage));
   [repImg drawInRect:myFrame fromRect:myFrame operation:NSCompositeCopy fraction:1.0 respectFlipped:TRUE hints:nil];

   // free image from array (not listed here)
}

// this is called when the CGDataProvider is ready to release its data
void myReleaseProvider (void *info, const void *data, size_t size)
{
    if (data)  {
        free((void *)data);
        data=nil;
    }
}
4

1 に答える 1

2

genericRGB の代わりに CGColorSpaceCreateDeviceRGB を使用して、CG 内での色空間の変換を回避します。kCGImageAlphaLast の代わりに kCGImageAlphaNoneSkipLast を使用してください。これは、ブレンドの代わりにコピーを許可するためにアルファが不透明であることがわかっているためです。

これらの変更を行った後、Instruments の時間プロファイルを実行して、時間の経過を表示すると便利です。

于 2014-07-09T20:43:08.183 に答える