Search code examples
c++image-processinggdi

DrawText on HBITMAP without "visible" DC?


I need to print a timestamp on webcam frame and tried to do next:

CameraFrameBufferSize = WebCam->GetFrameSize();
CameraFrameBuffer = (unsigned char *)realloc(CameraFrameBuffer, CameraFrameBufferSize);
unsigned char * buf = WebCam->CaptureFrame(); // returns pointer to RGB buffer of frame

HDC hDC = CreateCompatibleDC(NULL);
HFONT font = CreateFont(20, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, RUSSIAN_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, VARIABLE_PITCH, "times");
RECT rect;
rect.left = 0;
rect.right = WebCam->GetFrameWidth();
rect.top = 10;
rect.bottom = 50;

HBITMAP hBitmap = CreateHBITMAPfromByteArray(hDC, WebCam->GetFrameWidth(), WebCam->GetFrameHeight(), 3, buf);

SelectObject(hDC, hBitmap);
SelectObject(hDC, font);
SetBkMode(hDC, TRANSPARENT);
SetTextColor(hDC, RGB(255,255,255));
string Text = GetTime("%Y.%m.%d %H:%M:%S");
DrawTextA(hDC, Text.c_str(), Text.size(), &rect, DT_CENTER | DT_WORDBREAK);

jpge::compress_image_to_jpeg_file_in_memory(CameraFrameBuffer, CameraFrameBufferSize, WebCam->GetFrameWidth() ,WebCam->GetFrameHeight(), 3, buf, CameraCompressor);

CameraFrame = string(reinterpret_cast<char*>(CameraFrameBuffer), CameraFrameBufferSize);
ReleaseDC(NULL, hDC);
DeleteObject(hBitmap);
DeleteObject(font);

CreateHBITMAPfromByteArray is:

HBITMAP CreateHBITMAPfromByteArray(HDC hdc, int Width, int Height, int Colors, unsigned char* pImageData){
    LPBITMAPINFO lpbi = new BITMAPINFO;
    lpbi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    lpbi->bmiHeader.biWidth = Width;
    lpbi->bmiHeader.biHeight = -Height;
    lpbi->bmiHeader.biPlanes = 1;
    lpbi->bmiHeader.biBitCount = Colors*8;
    lpbi->bmiHeader.biCompression = BI_RGB;
    lpbi->bmiHeader.biSizeImage = 0;
    lpbi->bmiHeader.biXPelsPerMeter = 0;
    lpbi->bmiHeader.biYPelsPerMeter = 0;
    lpbi->bmiHeader.biClrUsed = 0;
    lpbi->bmiHeader.biClrImportant = 0;

    return CreateDIBSection(hdc, lpbi, DIB_RGB_COLORS,(void **)&pImageData,NULL,0 );
}

And I'm getting just a frame without text when saving a test image file (string CameraFrame)...

The camera shoots in the background and nothing is displayed on the screen, so I'm not sure about HDC I'm selecting.

In general, I have an RGB buffer of image where the text with transparency must be placed. How to implement that?


Solution

  • It looks like you are compressing (and saving) original camera frame buffer buf, not the bitmap buffer. The usage of CreateDIBSection is wrong as well, because param #4 is an out param that supposed to receive a pointer to the location of the DIB bit values and you are trying to pass a pointer to existing image data there.