gpt4 book ai didi

macos - 将所有 NSWindows 捕获为事件图像,例如 Mac OS X 中的 Mission Control

转载 作者:行者123 更新时间:2023-12-04 12:21:15 24 4
gpt4 key购买 nike

我正在寻找聚合所有窗口的实时表示。很像 Mission Control (Exposé),我想非常快速地访问任何给定 NSWindow 或屏幕的图像缓冲区。理想情况下,我想在我自己的 OpenGL 上下文中合成这些实时图像,以便我可以操纵它们(缩放和移动 Windows 屏幕截图)。

太慢的事情:

  • CGDisplayCreateImage
  • CGWindowListCreateImage
  • CGDisplayIDToOpenGLDisplayMask & CGLCreateContext & CGBitmapContextCreate

  • 还有其他想法吗?我正在尝试实现 60 fps 的捕获/合成/输出,但使用这些方法中的任何一种我能得到的最好的结果是 ~5 fps(在捕获整个屏幕的视网膜显示器上)。

    最佳答案

    不幸的是,我还没有找到快速捕获单个窗口的帧缓冲区的方法,但我想出了下一个最好的方法。这是一种将整个屏幕的实时 View 快速捕获到 OpenGL 中的方法:

    AVFoundation 设置

    _session = [[AVCaptureSession alloc] init];
    _session.sessionPreset = AVCaptureSessionPresetPhoto;
    AVCaptureScreenInput *input = [[AVCaptureScreenInput alloc] initWithDisplayID:kCGDirectMainDisplay];
    input.minFrameDuration = CMTimeMake(1, 60);
    [_session addInput:input];
    AVCaptureVideoDataOutput *output = [[AVCaptureVideoDataOutput alloc] init];
    [output setAlwaysDiscardsLateVideoFrames:YES];
    [output setSampleBufferDelegate:self queue:dispatch_get_main_queue()];
    [_session addOutput:output];
    [_session startRunning];

    在每个 AVCaptureVideoDataOutput框架
    - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
    CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
    const size_t bufferWidth = CVPixelBufferGetWidth(pixelBuffer);
    const size_t bufferHeight = CVPixelBufferGetHeight(pixelBuffer);

    CVOpenGLTextureRef texture;
    CVOpenGLTextureCacheCreateTextureFromImage(kCFAllocatorDefault, _textureCache, pixelBuffer, NULL, &texture);
    CVOpenGLTextureCacheFlush(_textureCache, 0);

    // Manipulate and draw the texture however you want...
    const GLenum target = CVOpenGLTextureGetTarget(texture);
    const GLuint name = CVOpenGLTextureGetName(texture);

    // ...

    glEnable(target);
    glBindTexture(target, name);

    CVOpenGLTextureRelease(texture);
    }

    清理
    [_session stopRunning];
    CVOpenGLTextureCacheRelease(_textureCache);

    获得 AVCaptureVideoDataOutput 的其他一些实现之间的巨大区别将图像作为纹理导入 OpenGL 是他们可能使用 CVPixelBufferLockBaseAddress , CVPixelBufferGetBaseAddress , glTexImage2D , 和 CVPixelBufferUnlockBaseAddress .这种方法的问题是它通常非常冗余和缓慢。 CVPixelBufferLockBaseAddress将确保它即将交给您的内存不是 GPU 内存,并将其全部复制到通用 CPU 内存。这是不好的!毕竟,我们只是用 glTexImage2D 将它复制回 GPU。 .

    因此,我们可以利用 CVPixelBuffer已在 GPU 内存中,带有 CVOpenGLTextureCacheCreateTextureFromImage .

    我希望这对其他人有帮助... CVOpenGLTextureCache套件的文档非常详细,它的 iOS 对应版本 CVOpenGLESTextureCache只是稍微好一点的记录。

    在 20% CPU 下以 60fps 捕获 2560x1600 桌面!

    关于macos - 将所有 NSWindows 捕获为事件图像,例如 Mac OS X 中的 Mission Control,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22623801/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com