How to dynamically update gdiplus bitmap object in MFC?
-
I have a MFC dialog application in which I have a gdiplus object that I use to draw images in real-time. Works fine if I don't want to do any changes to this object or its associated variables. But when I try to update them at runtime, it starts to increase my memory consumption. So, my question is, how to safely update a gdiplus object at runtime. Here is my code
// Variables declaration in header file
LONG Width;
LONG Height;
LONG bpp;
LONG Stride;
BITMAPINFO* bmi;
BYTE* pDIBSectionBits;
HBITMAP hbm;
Graphics* imagedisp;
Bitmap* offscreenBitmap;
CWnd* Display;
CStatic m_ImageDisp;// Source file
OnInitDialog()
{
......
Width = 512;
Height = 512;
bpp = 8;
Stride = ((Width * bpp + 31L) & (~31L)) / 8L;
......
}InitParams()
{
SetImageColor();Display = GetDlgItem(IDH_IMAGE);
this->GetClientRect(&m_disp_rect);
Display->GetClientRect(&m_disp_rect);
m_ImageDisp.GetClientRect(&m_disp_rect);
imagedisp = new Graphics(m_ImageDisp.GetDC()->GetSafeHdc());
}SetImageColor()
{
m_BUpdate = false;
if (bmi != NULL)
{
delete bmi;
bmi = NULL;
}
bmi = (BITMAPINFO *)new BYTE[sizeof(BITMAPINFO) + UCHAR_MAX * sizeof(RGBQUAD)];
bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi->bmiHeader.biWidth = Width;
bmi->bmiHeader.biHeight = Height;
bmi->bmiHeader.biPlanes = 1;
bmi->bmiHeader.biBitCount = (WORD)bpp;
bmi->bmiHeader.biCompression = BI_RGB;
bmi->bmiHeader.biSizeImage = 0;//Stride * abs(Height);
bmi->bmiHeader.biXPelsPerMeter = 0;
bmi->bmiHeader.biYPelsPerMeter = 0;
bmi->bmiHeader.biClrUsed = 0;
bmi->bmiHeader.biClrImportant = 0;
memcpy(bmi->bmiColors, USECOLORMAP?summercmap:greyscale, 256*sizeof(RGBQUAD));
hbm = ::CreateDIBSection(NULL, bmi, DIB_RGB_COLORS, (void**)&pDIBSectionBits, NULL, 0);
if (offscreenBitmap != NULL)
{
delete offscreenBitmap;
offscreenBitmap = NULL;
}
offscreenBitmap = new Bitmap(bmi, pDIBSectionBits);
m_BUpdate = true;
}OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
if (m_BUpdate)
{
BYTE *pCurRowPixel = (BYTE *)(pDIBSectionBits);
memcpy(pCurRowPixel, ImgBuff, Width*Height);imagedisp->DrawImage(offscreenBitmap, 0, 0, Width, Height);
}
}So whenever the user clicks a button to change between grayscale and color pallette, SetImageColor() is called. When I monitor the memory usage while clicking that button, I see its changing the way I ex
-
I have a MFC dialog application in which I have a gdiplus object that I use to draw images in real-time. Works fine if I don't want to do any changes to this object or its associated variables. But when I try to update them at runtime, it starts to increase my memory consumption. So, my question is, how to safely update a gdiplus object at runtime. Here is my code
// Variables declaration in header file
LONG Width;
LONG Height;
LONG bpp;
LONG Stride;
BITMAPINFO* bmi;
BYTE* pDIBSectionBits;
HBITMAP hbm;
Graphics* imagedisp;
Bitmap* offscreenBitmap;
CWnd* Display;
CStatic m_ImageDisp;// Source file
OnInitDialog()
{
......
Width = 512;
Height = 512;
bpp = 8;
Stride = ((Width * bpp + 31L) & (~31L)) / 8L;
......
}InitParams()
{
SetImageColor();Display = GetDlgItem(IDH_IMAGE);
this->GetClientRect(&m_disp_rect);
Display->GetClientRect(&m_disp_rect);
m_ImageDisp.GetClientRect(&m_disp_rect);
imagedisp = new Graphics(m_ImageDisp.GetDC()->GetSafeHdc());
}SetImageColor()
{
m_BUpdate = false;
if (bmi != NULL)
{
delete bmi;
bmi = NULL;
}
bmi = (BITMAPINFO *)new BYTE[sizeof(BITMAPINFO) + UCHAR_MAX * sizeof(RGBQUAD)];
bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi->bmiHeader.biWidth = Width;
bmi->bmiHeader.biHeight = Height;
bmi->bmiHeader.biPlanes = 1;
bmi->bmiHeader.biBitCount = (WORD)bpp;
bmi->bmiHeader.biCompression = BI_RGB;
bmi->bmiHeader.biSizeImage = 0;//Stride * abs(Height);
bmi->bmiHeader.biXPelsPerMeter = 0;
bmi->bmiHeader.biYPelsPerMeter = 0;
bmi->bmiHeader.biClrUsed = 0;
bmi->bmiHeader.biClrImportant = 0;
memcpy(bmi->bmiColors, USECOLORMAP?summercmap:greyscale, 256*sizeof(RGBQUAD));
hbm = ::CreateDIBSection(NULL, bmi, DIB_RGB_COLORS, (void**)&pDIBSectionBits, NULL, 0);
if (offscreenBitmap != NULL)
{
delete offscreenBitmap;
offscreenBitmap = NULL;
}
offscreenBitmap = new Bitmap(bmi, pDIBSectionBits);
m_BUpdate = true;
}OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
if (m_BUpdate)
{
BYTE *pCurRowPixel = (BYTE *)(pDIBSectionBits);
memcpy(pCurRowPixel, ImgBuff, Width*Height);imagedisp->DrawImage(offscreenBitmap, 0, 0, Width, Height);
}
}So whenever the user clicks a button to change between grayscale and color pallette, SetImageColor() is called. When I monitor the memory usage while clicking that button, I see its changing the way I ex
do you ever call DeleteObject on the result from that CreadeDIBSection ? (you should)
-
do you ever call DeleteObject on the result from that CreadeDIBSection ? (you should)
Thanks Chris, that solved my memory leak issue.
PKNT