Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ GDI屏幕截图,不同计算机上的结果不同_C++_Windows_Bitmap_Screenshot_Gdi - Fatal编程技术网

C++ GDI屏幕截图,不同计算机上的结果不同

C++ GDI屏幕截图,不同计算机上的结果不同,c++,windows,bitmap,screenshot,gdi,C++,Windows,Bitmap,Screenshot,Gdi,我尝试用GDI截图,然后在FFmpeg中使用它。 屏幕截图运行良好,FFmpeg可以毫无问题地处理它 但是,在一些电脑上,图像不是我想要的,就像你在下面看到的那样 以下是我用来初始化位图的代码: //-- mImageBuffer = new unsigned char[mWxHxS]; memset(mImageBuffer, 0, mWxHxS); //-- hScreenDC = GetDC(0); hMemoryDC = CreateCompatibleDC(hScreenDC); /

我尝试用GDI截图,然后在FFmpeg中使用它。 屏幕截图运行良好,FFmpeg可以毫无问题地处理它

但是,在一些电脑上,图像不是我想要的,就像你在下面看到的那样

以下是我用来初始化位图的代码:

//--
mImageBuffer = new unsigned char[mWxHxS];
memset(mImageBuffer, 0, mWxHxS);
//--
hScreenDC = GetDC(0);
hMemoryDC = CreateCompatibleDC(hScreenDC);
//--
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biBitCount = 24;
bi.bmiHeader.biWidth = mWidth;
bi.bmiHeader.biHeight = mHeight;
bi.bmiHeader.biCompression = BI_RGB;
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biClrUsed = 24;
bi.bmiHeader.biClrImportant = 256;
hBitmap = CreateDIBSection(hMemoryDC, &bi, DIB_RGB_COLORS, &mImageBuffer, 0, 0);
SelectObject(hMemoryDC, hBitmap);
下面是每个屏幕截图:

if(BitBlt(
    hMemoryDC,
    0,
    0,
    mWidth,
    mHeight,
    hScreenDC,
    mPx,
    mPy,
    SRCCOPY | CAPTUREBLT
))
我没有任何错误运行我的应用程序,但这个丑陋的形象,只有在一些计算机上。 我不知道是什么原因导致这些计算机上的差异(都是Win7,Aero-actived…)。 我不明白,因为我的代码遵循我找到的所有示例


请帮帮我

您正在创建独立于设备的位图(CreateDIBSection),然后使用依赖于设备的上下文(CreateCompatibleDC)来处理它。我认为您需要创建与设备相关的位图以与BitBlt兼容,或者使用StretchDIBits来支持与设备无关的图像数据。这在某些计算机上有效而在其他计算机上无效的原因是视频驱动程序确定设备相关图像的格式,该格式可能与设备无关图像的Windows定义相同,也可能不同

下面是一个捕获图像的示例(是的,它不必要地长,但似乎仍然包含良好的信息):


这是关于StretchDIBits的文档,以防您需要DIB:

所以我最终找到了解决方案:

在某些计算机上,BitBlt和StretchBlt似乎不能正确处理32到24位之间的传输

现在,我只在GDI中使用32位,并让FFmpeg和libswscale将我的RGBA图像转换为YUV格式

我的变化:

mWidth = GetDeviceCaps(hScreenDC, HORZRES);
mHeight = GetDeviceCaps(hScreenDC, VERTRES);
mWxHxS = mWidth*mHeight*4;

bi.bmiHeader.biBitCount = 32;
hBitmap = CreateCompatibleBitmap(hScreenDC, mWidth, mHeight);


if(BitBlt(
    hMemoryDC,
    0,
    0,
    mWidth,
    mHeight,
    hScreenDC,
    mPx,
    mPy,
    SRCCOPY | CAPTUREBLT
    ) && GetDIBits(hScreenDC, hBitmap, 0, mHeight, mImageBuffer, &bi, DIB_RGB_COLORS))
    {
    return true;
    }

谢谢你帮我

在我看来,你只是在使用rgb而不是rgba。(这只是我想到的第一件事)对,我只使用rgb通道,但我的理解是通过将biClrUsed设置为24,BitBlt将rgba转换为rgb。此外,在我的计算机上,DC返回32位,但图像正常,我没有这个问题。如何计算
mWxHxS
值?我想这是真正的分辨率,而不是监视器的本机分辨率(不使用VCL,所以我不知道)?从我在文档中发现的情况来看:Width属性不考虑任何停靠在监视器上的任务栏或工具栏。是否系统的任务栏位于左侧或右侧,用于检测输出?
biClrUsed
不应设置为每像素位数。它适用于不使用调色板中所有颜色的基于调色板的图像。除非您使用调色板(颜色表)创建位图,否则应将其设置为0。谢谢Matt,我现在了解问题所在,但我想从设备上下文复制到DIB,StrechDIBits似乎会反转(从DIB到矩形),对吗?链接中的示例保存了一个兼容的DC,如我的代码。。。所以我想我需要找到一个上下文无关的HDC to DIB函数!我尝试使用CreateCompatibleBitmap并使用GetDIBits,但结果总是一样的:
hBitmap=CreateCompatibleBitmap(hScreenDC,mWidth,mHight);如果(获取DIBITS(hScreenDC、hBitmap、0、mHeight、mImageBuffer和bi、DIB_RGB_颜色))