2012-12-20 22 views
6

Attualmente sto lavorando a un progetto di tipo desktop remoto, in particolare sto cercando di fornire il codice di sostituzione per i vecchi metodi obsoleti che sono stati usati in precedenza. L'ho gestito abbastanza bene, per la maggior parte, ma sembra che abbia raggiunto un ostacolo.Accesso al framebuffer OSX 10.7

A partire da OSX 10.7 il metodo chiamata CGDisplayBaseAddress è stato ritirato (1). Precedentemente questo mi dava l'indirizzo di base del framebuffer in memoria, che era usato altrove per vedere quali parti dello schermo erano cambiate e per determinare cosa doveva essere inviato al display remoto. Ora restituisce NULL.

mia soluzione attuale è stata quella di utilizzare CGDisplayCreateImage (2), che mi dà un CGImageRef che posso utilizzare per ottenere un puntatore ai dati grezzi (tramite un oggetto CFDataRef - per il codice vedi sotto) per l'immagine.

È questo il modo migliore per farlo? Sicuramente il loro deve essere un modo migliore di farlo!

Per riassumere: Non voglio fare alcun disegno sullo schermo o qualsiasi cosa sto cercando di ottenere un puntatore al primo byte in memoria che contiene il framebuffer del desktop o (come sto facendo attualmente) il dati di immagine.

Grazie per l'aiuto che puoi dare! :)

codice della soluzione attuale:

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; 

} 

frammento di codice per ottenere il CGImageRef -

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

byte_t è typedef per essere un unsigned char

+0

'CGRegisterScreenRefreshCallback' è leggermente migliore, ma è ancora deprecato in 10.8. Non sono sicuro se c'è qualche sostituzione ... – duskwuff

+0

Sì, potrebbe essere stato utile :) Non so perché stanno rendendo così difficile usare il frambuffer a meno che non ci siano stati alcuni problemi di sicurezza o con loro stanno pianificando di introdurre dei magici astrazione per sostituirlo: P Grazie per il commento! – andrewktmeikle

risposta

2

Dalla mia ricerca sembra che non è più necessario accedere al framebuffer.

Essi modo in cui mi hanno fatto di cui sopra non può essere il modo migliore ma funziona sicuramente per quello che ho bisogno di fare :)

precedenza che avrebbe dovuto bloccare la visualizzazione fare ciò che si voleva fare con esso quindi rilasciarlo, il che a volte potrebbe portare a uno sfarfallio dello schermo quando si rilascia lo schermo.

Il nuovo modo, tramite la creazione dell'immagine, significa che non ha a che fare con niente di tutto questo è sufficiente creare l'immagine e il tuo oro :)

Una cosa che vorrei aggiungere al mio codice esistente è che si deve ricordati di liberare CGImageRef o una perdita di memoria MAJOR.

Per fare questo basta chiamare:

CFRelease(screenShot); 

abbiamo anche bisogno di rilasciare l'oggetto pixelData nello stesso modo.

CFRelease(pixelData); 
Problemi correlati