Click here to Skip to main content
15,886,799 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I've been working on a Webcam video recorder and I got interested in trying everything when it comes to this topic but there's this problem that I can't solve.

Everything that you might wonder about can be found here https://msdn.microsoft.com/en-us/library/windows/desktop/dd757677%28v=vs.85%29.aspx and here https://msdn.microsoft.com/en-us/library/windows/desktop/dd757694%28v=vs.85%29.aspx

Now, in this code
C++
if (capSetCallbackOnVideoStream(hCapWnd, capVideoStreamCallback))
{
    capCaptureSequenceNoFile(hCapWnd); //Capture
}

I make sure that every frame that gets captured is sent to capVideoStreamCallback.

Now what I'm trying to do is transform a frame to an image and save it somewhere, this might be useless but it's interesting and it is surely possible.


Here is my capVideoStreamCallback function (it's commented):
C++
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);
    output.write((char*)Image, Size);
    output.close();

    return (LRESULT)TRUE;
}

So, the information about every frame that gets sent to capVideoStreamCallback can be found in lpVHdr which is a structure (https://msdn.microsoft.com/en-us/library/windows/desktop/dd757688%28v=vs.85%29.aspx) and what I'm trying to do here is to take that information and transform it to an image.

I first start by getting the full size of the image by retrieving the size of the header and the size of the data and then I dynamically declared a BYTE Array called Image and copied the header and the data to Image using memcpy. I finally used ofstream to write the bytes to a file and that's pretty much it.

The problem is that everything works just fine but the image is somehow corrupted because it cannot be opened.

What is wrong in what I'm doing? It seems so logical but it's not working. Please share your ideas and thanks for reading.
Posted
Updated 17-Jul-15 16:18pm
v4

1 solution

A bitmap file have one header more respect the memory bitmap: The BITMAPFILEHEADER[^].
Take a look to docs, and add it at very beginning of the file ;).
For more info just googling you can find many examples on the net.
 
Share this answer
 
v2
Comments
MarioAda 19-Jul-15 20:31pm    
You were actually right Frankie-C, thanks for posting, I forgot to add the BITMAPFILEHEADER, there was also few extra stuff that I had to do such as flipping the bytes to get BGR instead of RGB etc, here's a nice tut explaining that: http://tipsandtricks.runicsoft.com/Cpp/BitmapTutorial.html[^]
Frankie-C 20-Jul-15 4:16am    
You're welcome.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900