0

I am using C++ GDI, StretchDIBits to draw images on DC.

Because the original Image is large, and high quality is needed. I use HAFTONE mode, to draw whole image on DC(zoom the image) seems time comsuming.

So I decide to draw partially using StretchDIBits. But there is a serious problem about StretchDIBits.

I can only draw rect in integers to a region in integers(the width and height ,and top left point of x, y are all integers)

    ::SetStretchBltMode(hdc, HALFTONE);
    ::StretchDIBits(hdc,
        realDrawRect.left, 
        realDrawRect.top, 
        realDrawRect.right - realDrawRect.left, 
        realDrawRect.bottom - realDrawRect.top,
        left, 
        top, 
        width, 
        height,
        pImageDIB,
        pImageHead, 
        DIB_RGB_COLORS, SRCCOPY);

if, the Image is 21 * 21 . I now is drawing (5, 5, 7, 7) to DC, at (20, 20, 60,60), the next time I wann to draw at (21, 20, 61, 60). there is not corresponding location at original image. So I can only draw an approximation rect to the DC. Now the problem happening, the image is shaking!!

I am annoyed about that problem. How can I avoid shaking?

user25749
  • 4,825
  • 14
  • 61
  • 83

2 Answers2

0

If the shaking comes from rounding the integer try rounding it down to nearest integer. See this.

Otherwise I would recommend that you switch to GDI+ which is much easier to work with. With GDI+ you can draw a bitmap with floating point precision. See documentation Graphics::DrawImage.

I've switched from GDI to GDI+ in a couple of MFC Active-X projects and it's not hard at all.

Community
  • 1
  • 1
mandrake
  • 1,213
  • 1
  • 14
  • 28
0

This is a normal problem which I have faced when I used stretchDIBits in C++ as well as in C#. To overcome this problem, We had the functionality to correct the width and height of the image before calling stretchDIBits functionality:

if (m_currentImage.Width % 2 != 0) // check for odd number
{
     if (((m_currentImage.Width - 1) / 2) % 2 != 0)
           m_currentImage = m_currentImage.Resize(m_currentImage.Width - 3, m_currentImage.Height - 2, Emgu.CV.CvEnum.Inter.Linear);
     else
           m_currentImage = m_currentImage.Resize(m_currentImage.Width - 1, m_currentImage.Height, Emgu.CV.CvEnum.Inter.Linear);
}
else if ((m_currentImage.Width / 2) % 2 != 0) // else check fraction of width is odd number
     m_currentImage = m_currentImage.Resize(m_currentImage.Width - 2, m_currentImage.Height - 1, Emgu.CV.CvEnum.Inter.Linear);