Macos 访问帧缓冲区OSX 10.7

Macos 访问帧缓冲区OSX 10.7,macos,cocoa,desktop,quartz-graphics,screen-capture,Macos,Cocoa,Desktop,Quartz Graphics,Screen Capture,我目前正在处理一个远程桌面类型的项目,特别是我正在尝试为以前使用的旧的不推荐的方法提供替换代码。我在很大程度上成功地做到了这一点,但我似乎遇到了一个绊脚石 从OSX 10.7开始,方法调用CGDisplayBaseAddress已被弃用()。在此之前,这为我提供了内存中帧缓冲区的基址,用于查看屏幕的哪些部分已更改,并确定需要发送到远程显示器的内容。现在它返回NULL 我目前的解决方案是使用CGDisplayCreateImage(),它给了我一个CGImageRef,然后我可以使用它来获取指向图

我目前正在处理一个远程桌面类型的项目,特别是我正在尝试为以前使用的旧的不推荐的方法提供替换代码。我在很大程度上成功地做到了这一点,但我似乎遇到了一个绊脚石

从OSX 10.7开始,方法调用CGDisplayBaseAddress已被弃用()。在此之前,这为我提供了内存中帧缓冲区的基址,用于查看屏幕的哪些部分已更改,并确定需要发送到远程显示器的内容。现在它返回NULL

我目前的解决方案是使用CGDisplayCreateImage(),它给了我一个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的类型定义为无符号字符,似乎您不再需要访问帧缓冲区

他们的方式我已经做了上面可能不是最好的方式,但它肯定为我所需要的工作:)

以前,您必须锁定显示器,然后释放它,这有时会导致屏幕在释放屏幕时闪烁

通过创建图像的新方法意味着您无需处理任何这些问题,只需创建图像和黄金:)

我要添加到现有代码中的一件事是,您必须记住释放CGImageRef,否则它会导致严重的内存泄漏

要做到这一点,只需拨打:

CFRelease(screenShot);
我们还需要以同样的方式释放pixelData对象

CFRelease(pixelData);

CGRegisterScreenRefreshCallback
稍好一些,但在10.8中仍然不推荐使用。不确定是否有替代品……是的,它可能很有用:)我不知道为什么他们让frambuffer如此难以使用,除非它有一些奇怪的安全问题,或者他们计划引入一些神奇的抽象来替代它:P谢谢你的评论!