2012-12-20 50 views
6

Aktualnie pracuję nad projektem typu zdalnego pulpitu, w szczególności próbuję dostarczyć kod zamienny dla starych metod, które były wcześniej używane. Udało mi się to z powodzeniem, w większości przypadków, ale wydaje mi się, że udało mi się dojść do potknięcia.Uzyskiwanie dostępu do bufora ramki OSX 10.7

Od wersji OSX 10.7 wywołano wywołanie metody CGDisplayBaseAddress (1). Poprzednio podawałem adres bazowy bufora ramki w pamięci, który był używany w innym miejscu, aby zobaczyć, które części ekranu się zmieniły i określić, co należy wysłać do zdalnego wyświetlacza. Teraz zwraca NULL.

Moje obecne rozwiązanie polegało na użyciu CGDisplayCreateImage (2), który daje mi CGImageRef, który mogę następnie wykorzystać do uzyskania wskaźnika dla surowych danych (za pomocą obiektu CFDataRef - dla kodu patrz poniżej) dla obrazu.

Czy to najlepszy sposób na zrobienie tego? Z pewnością ich musi być lepszy sposób robienia tego!

Podsumowując: Nie chcę rysować na ekranie ani niczego, co tylko próbuję uzyskać wskaźnik do pierwszego bajtu w pamięci, który zawiera bufor ramki na pulpicie lub (jak obecnie robię) dane obrazu.

Dzięki za pomoc, jaką możesz dać! :)

Aktualny kod rozwiązanie:

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; 

} 

fragment kodu dla uzyskania CGImageRef -

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

byte_t jest typedef'd być unsigned char

+0

'CGRegisterScreenRefreshCallback' jest nieco lepszy, ale nadal jest nieaktualny w wersji 10.8. Nie jestem pewien, czy istnieje jakakolwiek wymiana ... – duskwuff

+0

Tak, to mogło być przydatne :) Nie wiem, dlaczego tak utrudniają używanie frambuffera, chyba że wystąpiły jakieś dziwne problemy z bezpieczeństwem lub planują wprowadzić jakieś magiczne abstrakcja, aby go zastąpić: P Dzięki za komentarz! – andrewktmeikle

Odpowiedz

2

Z moich badań wydaje że nie potrzebujesz już dostępu do bufora ramki.

one sposób w jaki zrobili to powyżej nie może być najlepszym sposobem, ale na pewno działa na co muszę to zrobić :)

wcześniej trzeba by zablokować wyświetlacz robić co chcesz z nim zrobić następnie zwolnij, co może czasem prowadzić do migotania ekranu po zwolnieniu ekranu.

nowy sposób, poprzez kreowanie wizerunku, oznacza, że ​​nie mają do czynienia z żadnym że wystarczy utworzyć swój złoty :)

Jedno Dodam do mojego istniejącego kodu jest to, że musisz wizerunku i pamiętaj o uwolnieniu CGImageRef lub jego MAJOR wycieku pamięci.

W tym celu wystarczy zadzwonić:

CFRelease(screenShot); 

Musimy również zwolnić obiekt pixelData w ten sam sposób.

CFRelease(pixelData);