Interesting problem creating bitmaps

Problem Description: I'm writing some code for the Microsoft Kinect and have borrowed some of their functions which I wish to modify for my own use. The overall goal of my project is to be able to capture the color video data stream from the kinect and save each frame as a bitmap.

So as to not overwrite a previously saved frame with a new frame when saving to the disk I'm adding the system time into the name of the .bmp file. The problem is that I want to save multiple pictures per-second and the function that Microsoft used to create a unique file stops at seconds and I NEED MILISECONDS.

Here is the function in which the frame processing takes place. (Im only showing important portions of code)

1
2
3
4
5
6
7
8
9
void dcBasics::ProcessColor()
{
	
         WCHAR screenshotPath[MAX_PATH];
         GetScreenshotFileName(&(screenshotPath[0]), _countof(screenshotPath));

         //Write out the bitmap to disk
         hr = SaveBitmapToFile(static_cast<BYTE *>(LockedRect.pBits), dcWidth, dcHeight, 32, screenshotPath); 
}


Here is Microsofts code for GetScreenshotFileName
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
HRESULT GetScreenshotFileName(wchar_t *screenshotName, UINT screenshotNameSize)
{
    wchar_t *knownPath = NULL;
    HRESULT hr = SHGetKnownFolderPath(FOLDERID_Pictures, 0, NULL, &knownPath);

    if (SUCCEEDED(hr))
    {
        // Get the time
        wchar_t timeString[MAX_PATH];
        GetTimeFormatEx(NULL, 0, NULL, L"hh'-'mm'-'ss'-'ms", timeString, _countof(timeString));

        // File name will be KinectSnapshot-HH-MM-SS.wav
        StringCchPrintfW(screenshotName, screenshotNameSize, L"%s\\KinectSnapshot-%s.bmp", knownPath, timeString);
    }

    CoTaskMemFree(knownPath);
    return hr;
}



Here is how I would like to modify it. The issue is getting timeString to play nice with the StringCchPrintfW(). I realize what I'm doing is probably wrong hence the need for help.

1
2
3
4
5
6
7
8
9
10
11
12
void GetScreenshotFileName(wchar_t *screenshotName, UINT screenshotNameSize)
{
    // Get the time
   
    //GetLocalTime(&st);
    wostringstream ss;
    ss << st.wDay  << '-'<< st.wMonth << '-' << st.wYear << "--" << st.wHour << ':' << st.wMinute << ':' << st.wSecond << ':' << st.wMilliseconds;
	wstring timeString = ss.str();

    // File name will be KinectSnapshot-HH-MM-SS-ms.bmp
    StringCchPrintfW(screenshotName, screenshotNameSize, L"%s\\KinectSnapshot-%s.bmp", L"C:\\Users\\John\\Desktop\\KinectPhotos", timeString);
}



Here is bitmap save code. This is where I start running into problems with my timeString variable. My changes always cause a failure at line 40.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
HRESULT CColorBasics::SaveBitmapToFile(BYTE* pBitmapBits, LONG lWidth, LONG lHeight, WORD wBitsPerPixel, LPCWSTR lpszFilePath)
{
    DWORD dwByteCount = lWidth * lHeight * (wBitsPerPixel / 8);

    BITMAPINFOHEADER bmpInfoHeader = {0};

    bmpInfoHeader.biSize        = sizeof(BITMAPINFOHEADER);  // Size of the header
    bmpInfoHeader.biBitCount    = wBitsPerPixel;             // Bit count
    bmpInfoHeader.biCompression = BI_RGB;                    // Standard RGB, no compression
    bmpInfoHeader.biWidth       = lWidth;                    // Width in pixels
    bmpInfoHeader.biHeight      = -lHeight;                  // Height in pixels, negative indicates it's stored right-side-up
    bmpInfoHeader.biPlanes      = 1;                         // Default
    bmpInfoHeader.biSizeImage   = dwByteCount;               // Image size in bytes

    BITMAPFILEHEADER bfh = {0};

    bfh.bfType    = 0x4D42;                                           // 'M''B', indicates bitmap
    bfh.bfOffBits = bmpInfoHeader.biSize + sizeof(BITMAPFILEHEADER);  // Offset to the start of pixel data
    bfh.bfSize    = bfh.bfOffBits + bmpInfoHeader.biSizeImage;        // Size of image + headers

    // Create the file on disk to write to
    HANDLE hFile = CreateFileW(lpszFilePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

    // Return if error opening file
    if (NULL == hFile) 
    {
        return E_ACCESSDENIED;
    }

    DWORD dwBytesWritten = 0;
    
    // Write the bitmap file header
    if ( !WriteFile(hFile, &bfh, sizeof(bfh), &dwBytesWritten, NULL) )
    {
        CloseHandle(hFile);
        return E_FAIL;
    }
    
    // Write the bitmap info header 
    if ( !WriteFile(hFile, &bmpInfoHeader, sizeof(bmpInfoHeader), &dwBytesWritten, NULL) )
    {
        CloseHandle(hFile);
        return E_FAIL;
    }
    
    // Write the RGB Data
    if ( !WriteFile(hFile, pBitmapBits, bmpInfoHeader.biSizeImage, &dwBytesWritten, NULL) )
    {
        CloseHandle(hFile);
        return E_FAIL;
    }    

    // Close the file
    CloseHandle(hFile);
    return S_OK;
}


I didn't read your code, but why not use a counter in your file name:

Ie:
1
2
3
4
int Count=0;
...
Save_File("Picture"+Makestring(++Count));
...


Then all saved pictures will be unique.
Topic archived. No new replies allowed.