2012-12-20 31 views
6

Tôi hiện đang làm việc trên một dự án kiểu máy tính để bàn từ xa, đặc biệt tôi đang cố gắng cung cấp mã thay thế cho các phương pháp không được sử dụng cũ đã được sử dụng trước đó. Tôi đã quản lý khá thành công, phần lớn, nhưng dường như tôi đã đạt đến một trở ngại.Truy cập framebuffer OSX 10.7

Kể từ OSX 10.7, phương thức gọi CGDisplayBaseAddress đã bị ngừng hoạt động (1). Trước đây, điều này đã cho tôi địa chỉ cơ sở của bộ đệm khung trong bộ nhớ, được sử dụng ở nơi khác để xem phần nào của màn hình đã thay đổi và để xác định những gì cần được gửi đến màn hình từ xa. Bây giờ nó trả về NULL.

Giải pháp hiện tại của tôi là sử dụng CGDisplayCreateImage (2), cung cấp cho tôi một CGImageRef mà sau đó tôi có thể sử dụng để lấy con trỏ tới dữ liệu thô (thông qua đối tượng CFDataRef - xem mã bên dưới) cho hình ảnh.

Đây có phải là cách tốt nhất để làm điều đó không? Chắc chắn họ phải là một cách tốt hơn để làm điều đó!

Để tóm tắt: Tôi không muốn vẽ bất kỳ bản vẽ nào lên màn hình hoặc bất kỳ thứ gì tôi chỉ cố gắng đưa con trỏ tới byte đầu tiên trong bộ nhớ chứa bộ đệm khung hình hoặc (như tôi hiện đang làm) dữ liệu hình ảnh.

Cảm ơn bạn đã được trợ giúp! :)

hiện tại đang giải pháp:

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; 

} 

đoạn mã để nhận được CGImageRef -

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

byte_t được typedef'd là một char unsigned

+0

'CGRegisterScreenRefreshCallback' tốt hơn một chút nhưng vẫn bị phản đối trong 10.8. Không chắc chắn nếu có bất kỳ thay thế ... – duskwuff

+0

Vâng, nó có thể có ích :) Tôi không biết tại sao họ đang làm cho nó khó khăn như vậy để sử dụng frambuffer trừ khi có một số vấn đề bảo mật kỳ lạ với nó hoặc họ đang có kế hoạch để giới thiệu một số phép thuật trừu tượng để thay thế nó: P Cảm ơn bạn đã bình luận! – andrewktmeikle

Trả lời

2

Từ nghiên cứu của tôi có vẻ như bạn không cần truy cập vào bộ đệm khung nữa.

Họ cách tôi đã làm nó trên có thể không phải là cách tốt nhất nhưng chắc chắn nó làm việc cho những gì tôi cần nó để làm :)

Trước đây bạn sẽ phải khóa màn hình làm những gì bạn muốn làm gì với nó sau đó phát hành nó, mà đôi khi có thể dẫn đến màn hình nhấp nháy khi bạn phát hành màn hình.

Cách mới, thông qua việc tạo ra các hình ảnh, có nghĩa là bạn không cần phải đối phó với bất kỳ mà chỉ cần tạo hình ảnh và bạn vàng :)

Một điều tôi sẽ thêm vào mã hiện tại của tôi là bạn phải nhớ để giải phóng CGImageRef hoặc rò rỉ bộ nhớ MAJOR của nó.

Để làm được điều này chỉ cần gọi:

CFRelease(screenShot); 

Chúng ta cũng cần để giải phóng đối tượng pixelData trong cùng một cách.

CFRelease(pixelData); 
Các vấn đề liên quan