Image flickers when Invalidate() is called.
-
Hi all, I was able to display an raw image (8bit per pixel) using StretchDIBits method. However, my OnPaint() is called alot so the image is flickering like crazy. How can I get rid of this flickering business. I've read tutorials on double buffering, however, I still don't understand how to apply it to this case where the image is from an array of bytes. Thanks,
-
Hi all, I was able to display an raw image (8bit per pixel) using StretchDIBits method. However, my OnPaint() is called alot so the image is flickering like crazy. How can I get rid of this flickering business. I've read tutorials on double buffering, however, I still don't understand how to apply it to this case where the image is from an array of bytes. Thanks,
First store your Image in MemoryDC. then call Invalidaterect(); You will get code in KRUGLANSKI.
-
Hi all, I was able to display an raw image (8bit per pixel) using StretchDIBits method. However, my OnPaint() is called alot so the image is flickering like crazy. How can I get rid of this flickering business. I've read tutorials on double buffering, however, I still don't understand how to apply it to this case where the image is from an array of bytes. Thanks,
If the window flickers it must mean that something else is being drawn to it between each of your StretchDIBits calls (otherwise you'd just be blitting the same image over the top of itself and you'd see no flicker). Probably what's causing the flicker is that your window's background is being erased as part of the repaint. However, if your image fills the window this erasing is entirely unnecessary and you should prevent it. An easy way to do this is to trap the WM_ERASEBKGND message and return zero -you should then find that that flickering goes away.
-
If the window flickers it must mean that something else is being drawn to it between each of your StretchDIBits calls (otherwise you'd just be blitting the same image over the top of itself and you'd see no flicker). Probably what's causing the flicker is that your window's background is being erased as part of the repaint. However, if your image fills the window this erasing is entirely unnecessary and you should prevent it. An easy way to do this is to trap the WM_ERASEBKGND message and return zero -you should then find that that flickering goes away.
Hi, I have tried to override OnEraseBkgnd, the problem still occurs. I am writing and ViewLCD application for a camera (just like a digital camera with an LCD at the back to view the scene that the camera is pointing to). Thanks,
-
Hi, I have tried to override OnEraseBkgnd, the problem still occurs. I am writing and ViewLCD application for a camera (just like a digital camera with an LCD at the back to view the scene that the camera is pointing to). Thanks,
Well, the flicker will only appear if something other than your bitmap is being drawn between your updates - the obvious candidate is erasing the backrgound but is there anything else in your WM_PAINT processing that might be causing this?
-
Well, the flicker will only appear if something other than your bitmap is being drawn between your updates - the obvious candidate is erasing the backrgound but is there anything else in your WM_PAINT processing that might be causing this?
This is all in my OnPaint() of a CChildView: CPaintDC dc(this); // device context for painting CDC* pDC = &dc; // Convert to context device pointer HDC hdc = pDC->GetSafeHdc(); // Prepare Header for image BITMAPINFO *m_pBitmapInfo; m_pBitmapInfo = (BITMAPINFO*)new char[sizeof(BITMAPINFO) + sizeof(RGBQUAD)*256]; // Load header m_pBitmapInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); m_pBitmapInfo->bmiHeader.biWidth = ImX; m_pBitmapInfo->bmiHeader.biHeight = -ImY; m_pBitmapInfo->bmiHeader.biPlanes = 1; m_pBitmapInfo->bmiHeader.biBitCount = 8; m_pBitmapInfo->bmiHeader.biCompression = BI_RGB; m_pBitmapInfo->bmiHeader.biSizeImage = 0; m_pBitmapInfo->bmiHeader.biXPelsPerMeter = 0; m_pBitmapInfo->bmiHeader.biYPelsPerMeter = 0; m_pBitmapInfo->bmiHeader.biClrUsed = 256; m_pBitmapInfo->bmiHeader.biClrImportant = 0; int i; for ( i = 0; i < 256; i++ ) { m_pBitmapInfo->bmiColors[i].rgbBlue = i; m_pBitmapInfo->bmiColors[i].rgbGreen = i; m_pBitmapInfo->bmiColors[i].rgbRed = i; m_pBitmapInfo->bmiColors[i].rgbReserved = 0; } // Stretch pixels out to screen StretchDIBits(hdc, xCord,yCord,ImX,ImY, 0,0,ImX,ImY, img, //------->>> Pointer to array of bits, a CChildView variable member. m_pBitmapInfo, DIB_RGB_COLORS, SRCCOPY);
-
This is all in my OnPaint() of a CChildView: CPaintDC dc(this); // device context for painting CDC* pDC = &dc; // Convert to context device pointer HDC hdc = pDC->GetSafeHdc(); // Prepare Header for image BITMAPINFO *m_pBitmapInfo; m_pBitmapInfo = (BITMAPINFO*)new char[sizeof(BITMAPINFO) + sizeof(RGBQUAD)*256]; // Load header m_pBitmapInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); m_pBitmapInfo->bmiHeader.biWidth = ImX; m_pBitmapInfo->bmiHeader.biHeight = -ImY; m_pBitmapInfo->bmiHeader.biPlanes = 1; m_pBitmapInfo->bmiHeader.biBitCount = 8; m_pBitmapInfo->bmiHeader.biCompression = BI_RGB; m_pBitmapInfo->bmiHeader.biSizeImage = 0; m_pBitmapInfo->bmiHeader.biXPelsPerMeter = 0; m_pBitmapInfo->bmiHeader.biYPelsPerMeter = 0; m_pBitmapInfo->bmiHeader.biClrUsed = 256; m_pBitmapInfo->bmiHeader.biClrImportant = 0; int i; for ( i = 0; i < 256; i++ ) { m_pBitmapInfo->bmiColors[i].rgbBlue = i; m_pBitmapInfo->bmiColors[i].rgbGreen = i; m_pBitmapInfo->bmiColors[i].rgbRed = i; m_pBitmapInfo->bmiColors[i].rgbReserved = 0; } // Stretch pixels out to screen StretchDIBits(hdc, xCord,yCord,ImX,ImY, 0,0,ImX,ImY, img, //------->>> Pointer to array of bits, a CChildView variable member. m_pBitmapInfo, DIB_RGB_COLORS, SRCCOPY);
Looks OK to me, although I'd set up the BitmapInfo record outside the paint processing. If ImX, ImY change between calls you can set just them. This would get that nasty for loop out of there! Anyhow, back to the flicker - the other possibility is that your WindowClass (that's class as in WNDCLASSEX) has a background brush defined. In this case I seem to recall that BeginPaint will erase the background without raising a WM_ERASEBKGND message.