6

私は現在、リモート デスクトップ タイプのプロジェクトに取り組んでいます。特に、以前に使用されていた古い廃止されたメソッドの代替コードを提供しようとしています。ほとんどの場合、私はこれを非常にうまく管理しましたが、つまずきのブロックに達したようです.

OSX 10.7 以降、メソッド呼び出し CGDisplayBaseAddress は廃止されました ( 1 )。以前は、これによりメモリ内のフレームバッファのベースアドレスが得られました。これは、画面のどの部分が変更されたかを確認し、リモートディスプレイに送信する必要があるものを判断するために別の場所で使用されていました。現在は NULL を返します。

私の現在の解決策は、CGDisplayCreateImage ( 2 ) を使用することでした。これにより、CGImageRef が得られ、これを使用して、画像の生データへのポインターを取得できます ( CFDataRef オブジェクトを介して - コードについては以下を参照)。

これが最善の方法ですか?確かに彼らはそれを行うためのより良い方法に違いありません!

要約すると、画面への描画や、デスクトップフレームバッファーまたは(現在行っているように)画像データを含むメモリ内の最初のバイトへのポインターを取得しようとしているだけです。

あなたが与えることができるどんな助けにも感謝します! :)

現在のソリューション コード:

CFDataRef copy_image_pixels(CGImageRef inImage) {
    return CGDataProviderCopyData(CGImageGetDataProvider(inImage)); 
}

/**
 ret_byte_buffer is the byte buffer containing the pixel data for the image **/
void *getPixelDataForImage (CGImageRef image) 
{
    //Check image ref is not null
    if (!image){
        NSLog(@"Error - image was null");
        return -1;
    }

    //Gets a CFData reference for the specified image reference
    CFDataRef pixelData = copy_image_pixels(image);
    //Gets a readonly pointer to the image data
    const UInt8 *pointerToData = CFDataGetBytePtr(pixelData); //This returns a read only version
    //Casting to a void pointer to return, expected to be cast to a byte_t *
    CFIndex length_of_buffer = CFDataGetLength(pixelData);
    printf("Size of buffer is %zu\n",length_of_buffer);
    return (void *)pointerToData;

}

CGImageRef を取得するためのコード スニペット -

osx_disp= main_screen_details->main_screenid; //Returns CGDirectDisplayID
CGImageRef screenShot = CGDisplayCreateImage(osx_disp);
byte_t *image_byte_data = getPixelDataForImage(screenShot);

byte_t は unsigned char になるように typedef されています

4

1 に答える 1

2

私の調査によると、フレームバッファにアクセスする必要はもうないようです。

私が上でそれをした彼らのやり方は最善の方法ではないかもしれませんが、それは確かに私がそれをするのに必要なことのために働きます:)

以前は、ディスプレイをロックして、やりたいことを実行してから離す必要がありました。これにより、画面を離したときに画面がちらつくことがありました。

新しい方法は、画像を作成することで、画像とゴールデンを作成するだけで対処する必要がないことを意味します:)

既存のコードに追加することの1つは、CGImageRefまたはその主要なメモリリークを解放することを忘れないでください。

これを行うには、次のように呼び出します。

CFRelease(screenShot);

同様に、pixelDataオブジェクトを解放する必要もあります。

CFRelease(pixelData);
于 2013-01-21T21:24:19.730 に答える