glReadPixels 与屏幕像素

Posted

技术标签:

【中文标题】glReadPixels 与屏幕像素【英文标题】:glReadPixels with screen pixels 【发布时间】:2017-06-19 15:35:37 【问题描述】:

我正在尝试读取屏幕像素的 RGB 值:

#include "stdafx.h"
#include<windows.h>
#include<stdio.h>
#include <gl\GL.h>

int main(int argc, char** argv)

    GLubyte color[3];
    glReadPixels(800, 800, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &color);

    printf("R:%d G:%d B:%d", color[0], color[1], color[2]);

    while (1);


但我要求的坐标并不重要。它总是返回我 R:204 G:204 B:204

我做错了什么?

【问题讨论】:

你想做什么?您甚至没有创建 OpenGL 上下文... 我正在尝试读取 x=800 y=800 位置像素的 RGB 值 glReadPixels 只能在具有与之关联的 OpenGL 上下文的屏幕中工作。在 glReadPixels 文档中有一条注释:“位于连接到当前 GL 上下文的窗口之外的像素的值未定义”。换句话说,只有在以下情况下,您才能确定您将获得实际的像素值:1. 有一个窗口,并且 2. 将 GL 上下文连接到它。 【参考方案1】:

glReadPixels() 在没有当前 GL 上下文的情况下将无法工作。即使您确实有当前上下文you can't read the system framebuffer that way。

【讨论】:

那么,我该怎么做才能有效地读取屏幕中任何像素的 RGB 值?我需要比 GetPixel 方法更快的方法... 您是否阅读了链接中问题的答案?他们在那里大致解释了为什么你不能使用 glReadPixels 来截屏。如果您在 Windows 上,您可以尝试使用 Win32。您可以将 CreateCompatibleBitmap 与屏幕设备上下文一起用作参数,并将生成的位图复制到内存位图,如下所述:***.com/questions/3291167/…【参考方案2】:

正如其他答案和 cmets 中所述,您只能将 glReadPixels 用于当时实际渲染的 OpenGL 上下文窗口内的像素......正如您提到的,您使用了 @987654324 @ 它暗示你正在使用 GDI。在这种情况下,您尝试从 OpenGL 读取 GDI Canvas 像素,这是不可能的(相反的方法是可能的,但是速度很慢)。所以我建议阅读这篇文章:

How can I access a graphics card's output directly?

您可以在哪里找到这两种方法的示例。如果您尝试从自己的应用程序中获取像素,那么您可以使用不同的 api 然后GetPixel

如果您在 VCL 环境中,请使用 Graphics::TBitmap::ScanLine 属性,如果使用得当,该属性可用于直接像素访问而不受限制或性能损失。

GCC 环境的 MSVC++ 上使用 WinAPI BitBlt 但这有点慢而且不那么优雅(至少从我的观点来看)观点)。

【讨论】:

以上是关于glReadPixels 与屏幕像素的主要内容,如果未能解决你的问题,请参考以下文章

[转]OpenGL 使用 PBO 高速复制屏幕图像到内存或者纹理中

opengl glReadPixels

整个窗口的 glReadPixels (OpenGL)

glReadPixels 的 OpenGL DSA 等效项

glReadPixels 函数返回错误 1282 (GL_INVALID_OPERATION)

Android 屏幕适配屏幕适配基础概念 ② ( 像素 px 与 密度无关像素 dip | 像素 px 与 密度无关像素 dip 在不同屏幕像素密度 dpi 下的换算关系 )