访问framebuffer OSX 10.7

and*_*kle 6 macos desktop cocoa screen-capture quartz-graphics

我目前正在开发一个远程桌面类型项目,特别是我正在尝试为之前使用的旧的depreceated方法提供替换代码.在大多数情况下,我已经非常成功地完成了这项工作,但我似乎遇到了绊脚石.

从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;

}
Run Code Online (Sandbox Code Playgroud)

用于获取CGImageRef的代码片段 -

osx_disp= main_screen_details->main_screenid; //Returns CGDirectDisplayID
CGImageRef screenShot = CGDisplayCreateImage(osx_disp);
byte_t *image_byte_data = getPixelDataForImage(screenShot);
Run Code Online (Sandbox Code Playgroud)

byte_t的typedef为无符号字符

and*_*kle 2

根据我的研究,您似乎不再需要访问帧缓冲区。

我上面做的方法可能不是最好的方法,但它确实适合我需要它做的事情:)

以前,您必须锁定显示屏执行您想要执行的操作,然后释放它,这有时可能会导致释放屏幕时屏幕闪烁。

通过创建图像的新方法意味着您不必处理任何事情,只需创建图像和您的黄金:)

我要添加到现有代码中的一件事是,您必须记住释放 CGImageRef 或其主要内存泄漏。

为此,只需调用:

CFRelease(screenShot);
Run Code Online (Sandbox Code Playgroud)

我们还需要以同样的方式释放pixelData对象。

CFRelease(pixelData);
Run Code Online (Sandbox Code Playgroud)