1

Mac OS のスクリーン キャプチャ用の glGrab コードを前述の構成に統合しようとしていますが、現在、ウィンドウ内でレンダリングされているすべての青い画面で立ち往生しています。画像テクスチャの作成方法に問題があると思いますが、何が原因かわかりません。私は OpenGL を使い始めてまだ 2 週間しか経っていません。

これらのメソッドは現在廃止されているため、CGLSetFullScreen メソッドを除いて (CGLSetFullScreenOnDisplay でさえも) glGrab コードをそのまま使用しています。したがって、この 1 行のコードは、当分の間コメント アウトされています。

私はしばらくの間、このトピックについていくつかの調査を行っており、stackoverflow で別のスレッドを見つけましたが、それはおそらく完全な答えである可能性がありますが、それでも大いに役立ちました。UIImage を CVImageBufferRef に変換する

glGrab コードへの直接参照はhttp://code.google.com/p/captureme/source/browse/trunk/glGrab.cです。

4

1 に答える 1

1

私の上記の質問に対する答えは以下にあります。したがって、opengl や glGrab はもう必要ありません。Mac OSX に最適化されたものを使用してください。これには、マウス ポインターをキャプチャするためのコードも含まれていませんが、このページにたどり着いた場合は、自分でそれを理解するのに十分賢いと確信しています。または、これを読んでいる人が解決策を知っている場合は、友愛を助けるチャンスです :) また、このコードは CVPixelBufferRef を返します。CGImageRef またはバイトストリームのいずれかをそのまま送り返すことを選択できます。好みに合わせて微調整するだけです。:

void swizzleBitmap(void *data, int rowBytes, int height) {
    int top, bottom;
    void * buffer;
    void * topP;
    void * bottomP;
    void * base;

    top = 0;
    bottom = height - 1;
    base = data;
    buffer = malloc(rowBytes);

    while (top < bottom) {
        topP = (void *)((top * rowBytes) + (intptr_t)base);
        bottomP = (void *)((bottom * rowBytes) + (intptr_t)base);

        bcopy( topP, buffer, rowBytes );
        bcopy( bottomP, topP, rowBytes );
        bcopy( buffer, bottomP, rowBytes );

        ++top;
        --bottom;
    }   
    free(buffer);
}   

CVImageBufferRef grabViaOpenGL() {
    int bytewidth;

    CGImageRef image = CGDisplayCreateImage(kCGDirectMainDisplay);    // Main screenshot capture call

    CGSize frameSize = CGSizeMake(CGImageGetWidth(image), CGImageGetHeight(image));    // Get screenshot bounds

    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                            [NSNumber numberWithBool:NO], kCVPixelBufferCGImageCompatibilityKey,
                            [NSNumber numberWithBool:NO], kCVPixelBufferCGBitmapContextCompatibilityKey,
                            nil];

    CVPixelBufferRef pxbuffer = NULL;
    CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault, frameSize.width,
                                          frameSize.height,  kCVPixelFormatType_32ARGB, (CFDictionaryRef) options,
                                          &pxbuffer);


    CVPixelBufferLockBaseAddress(pxbuffer, 0);
    void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer);

    CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(pxdata, frameSize.width,
                                                 frameSize.height, 8, 4*frameSize.width, rgbColorSpace,
                                                 kCGImageAlphaNoneSkipLast);

    CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image),
                                           CGImageGetHeight(image)), image);

    bytewidth = frameSize.width * 4; // Assume 4 bytes/pixel for now
    bytewidth = (bytewidth + 3) & ~3; // Align to 4 bytes
    swizzleBitmap(pxdata, bytewidth, frameSize.height);     // Solution for ARGB madness

    CGColorSpaceRelease(rgbColorSpace);
    CGImageRelease(image);
    CGContextRelease(context);

    CVPixelBufferUnlockBaseAddress(pxbuffer, 0);

    return pxbuffer;
}
于 2012-07-12T12:34:57.723 に答える