C++ VIDEOHDR 到 capVideoStreamCallback 中的图像文件
C++ VIDEOHDR to Image File in capVideoStreamCallback
我一直在研究网络摄像头录像机,当涉及到这个主题时,我有兴趣尝试一切,但有一个我无法解决的问题。
你可能想知道的一切都可以在这里找到
https://msdn.microsoft.com/en-us/library/windows/desktop/dd757677%28v=vs.85%29.aspx 在这里
https://msdn.microsoft.com/en-us/library/windows/desktop/dd757694%28v=vs.85%29.aspx
现在,在这段代码中
if (capSetCallbackOnVideoStream(hCapWnd, capVideoStreamCallback))
{
capCaptureSequenceNoFile(hCapWnd); //Capture
}
我确保捕获的每一帧都发送到 capVideoStreamCallback。
现在我要做的是将帧转换为图像并将其保存在某个地方,这可能没用但很有趣而且肯定是可能的。
这是我的 capVideoStreamCallback 函数(已注释):
LRESULT CALLBACK capVideoStreamCallback(HWND hWnd, LPVIDEOHDR lpVHdr)
{
BYTE *Image;
BITMAPINFO * TempBitmapInfo = new BITMAPINFO;
ULONG Size;
// First we need to get the full size of the image
Size = capGetVideoFormat(hWnd, TempBitmapInfo, sizeof(BITMAPINFO)); //header size
Size += lpVHdr->dwBytesUsed; //bytes used
Image = new BYTE[Size];
memcpy(Image, TempBitmapInfo, sizeof(BITMAPINFO)); //copy the header to Image
// lpVHdr is LPVIDEOHER passed into callback function.
memcpy(Image + sizeof(BITMAPINFO), lpVHdr->lpData, lpVHdr->dwBytesUsed); //copy the data to Image
//write the image
ofstream output("image.dib", ios::binary);
for (int i = 0; i < Size; i++)
{
output << (BYTE)Image[i];
}
output.close();
return (LRESULT)TRUE;
}
因此,关于发送到 capVideoStreamCallback 的每一帧的信息都可以在 lpVHdr 中找到,它是一个结构 (https://msdn.microsoft.com/en-us/library/windows/desktop/dd757688%28v=vs.85%29.aspx),我在这里要做的是获取该信息并将其转换到图像。
我首先通过检索 header 的大小和数据的大小来获取图像的完整大小,然后动态声明一个名为 Image 的 BYTE 数组并复制 header 和使用 memcpy 的图像数据。我终于使用 ofstream 将字节写入文件,仅此而已。
问题是一切正常,但图像因某种原因已损坏,因为无法打开。
我在做什么有什么问题吗?这看起来很合乎逻辑,但它不起作用。
请分享您的想法,感谢阅读。
感谢 http://codeproject.com 的 Frankie-C 的回答,他提醒我在 BITMAP 文件的顶部需要一个 BITMAPFILEHEADER 结构。
您还需要做一些额外的事情来使图像以应有的方式显示,例如翻转字节以获得 BGR 而不是 RGB 等,这里有一个很好的说明:http://tipsandtricks.runicsoft.com/Cpp/BitmapTutorial.htm
我一直在研究网络摄像头录像机,当涉及到这个主题时,我有兴趣尝试一切,但有一个我无法解决的问题。
你可能想知道的一切都可以在这里找到 https://msdn.microsoft.com/en-us/library/windows/desktop/dd757677%28v=vs.85%29.aspx 在这里 https://msdn.microsoft.com/en-us/library/windows/desktop/dd757694%28v=vs.85%29.aspx
现在,在这段代码中
if (capSetCallbackOnVideoStream(hCapWnd, capVideoStreamCallback))
{
capCaptureSequenceNoFile(hCapWnd); //Capture
}
我确保捕获的每一帧都发送到 capVideoStreamCallback。
现在我要做的是将帧转换为图像并将其保存在某个地方,这可能没用但很有趣而且肯定是可能的。
这是我的 capVideoStreamCallback 函数(已注释):
LRESULT CALLBACK capVideoStreamCallback(HWND hWnd, LPVIDEOHDR lpVHdr)
{
BYTE *Image;
BITMAPINFO * TempBitmapInfo = new BITMAPINFO;
ULONG Size;
// First we need to get the full size of the image
Size = capGetVideoFormat(hWnd, TempBitmapInfo, sizeof(BITMAPINFO)); //header size
Size += lpVHdr->dwBytesUsed; //bytes used
Image = new BYTE[Size];
memcpy(Image, TempBitmapInfo, sizeof(BITMAPINFO)); //copy the header to Image
// lpVHdr is LPVIDEOHER passed into callback function.
memcpy(Image + sizeof(BITMAPINFO), lpVHdr->lpData, lpVHdr->dwBytesUsed); //copy the data to Image
//write the image
ofstream output("image.dib", ios::binary);
for (int i = 0; i < Size; i++)
{
output << (BYTE)Image[i];
}
output.close();
return (LRESULT)TRUE;
}
因此,关于发送到 capVideoStreamCallback 的每一帧的信息都可以在 lpVHdr 中找到,它是一个结构 (https://msdn.microsoft.com/en-us/library/windows/desktop/dd757688%28v=vs.85%29.aspx),我在这里要做的是获取该信息并将其转换到图像。
我首先通过检索 header 的大小和数据的大小来获取图像的完整大小,然后动态声明一个名为 Image 的 BYTE 数组并复制 header 和使用 memcpy 的图像数据。我终于使用 ofstream 将字节写入文件,仅此而已。
问题是一切正常,但图像因某种原因已损坏,因为无法打开。
我在做什么有什么问题吗?这看起来很合乎逻辑,但它不起作用。 请分享您的想法,感谢阅读。
感谢 http://codeproject.com 的 Frankie-C 的回答,他提醒我在 BITMAP 文件的顶部需要一个 BITMAPFILEHEADER 结构。
您还需要做一些额外的事情来使图像以应有的方式显示,例如翻转字节以获得 BGR 而不是 RGB 等,这里有一个很好的说明:http://tipsandtricks.runicsoft.com/Cpp/BitmapTutorial.htm