Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

StretchBlt Shrink Corruption

I'm using Windows (both 7 & XP - both 32bit) and coding in C++

I am receiving bitmaps from an external source. These bitmaps are of a fixed resolution (384x288)

After I receive a bitmap, I need to resize it based on a variable sized layout, so I'm currently using StretchBlt to perform these tasks.

If I resize the bitmap to a larger on screen image, this works great.

However, if I shrink the incoming bitmap to a smaller version to place on the screen I get some strange 'boxing' type effect that occurs over the image.

In the following example, the source image is the same for each of the three panels. But the left hand two (resize smaller) both have the boxing/lines effect on them.

enter image description here

For the actual StretchBlt call, I'm doing this:

        memcpy(at_TempPointer[PortNo], // Destination
          (void *)VideoBufferAddress, // Source
          FIXED_IMAGE_WIDTH * FIXED_IMAGE_HEIGHT * BYTES_PER_PIXEL // Number of bytes
          );

    StretchBlt(at_ImageDC[PortNo], // HDC Dest
               0, // X Origin Dest
               0, // Y Origin Dest
               at_Width[PortNo], // Width Dest
               at_Height[PortNo], // Height Dest
               at_GhDC[PortNo], // HDC Source
               0, // X Origin Source
               0, // Y Origin Source
               FIXED_IMAGE_WIDTH, // Width Source
               FIXED_IMAGE_HEIGHT, // Height Source
               SRCCOPY // Graphic Operation
               );

But I'm wondering if perhaps the issue is elsewhere.

Has anyone else had experience of this kind of resizing image corruption that knows how I can fix it?

like image 344
Dave Avatar asked Dec 28 '22 06:12

Dave


2 Answers

Working palette-based OnPaint code that is compatible with VS 2013:

 void CMyView::paint_image(CDC* pDC)
 {

 CPalette * pal = &m_Palette;

    if (pal->m_hObject != NULL && m_Bitmap.m_hObject != NULL)
    {
        if (pDC != NULL)
        {
            CPalette *pOldPalette;
            pOldPalette = pDC->SelectPalette( pal, FALSE );
            pDC->RealizePalette();

            SetStretchBltMode(pDC->GetSafeHdc(), HALFTONE);

            if(flip)
                pDC->StretchBlt( 0, 0, x*zoomx, y*zoomy, m_pMemDC, x, y, -x, -y, SRCCOPY );
            else
                pDC->StretchBlt( 0, 0, x*zoomx, y*zoomy, m_pMemDC, 0, 0, x, y, SRCCOPY );
            pDC->SelectPalette( pOldPalette, TRUE );
        }
        else
        {
            CClientDC m_pWinDC(this);
            OnPrepareDC(&m_pWinDC);
            m_pWinDC.SelectPalette( pal, FALSE );
            m_pWinDC.RealizePalette();

            SetStretchBltMode(m_pWinDC, HALFTONE);

            if(flip)
                m_pWinDC.StretchBlt( 0, 0, x*zoomx, y*zoomy, m_pMemDC, x, y, -x, -y, SRCCOPY );
            else
                m_pWinDC.StretchBlt( 0, 0, x*zoomx, y*zoomy, m_pMemDC, 0, 0, x, y, SRCCOPY );
        }   

      }
  }
like image 20
SChalice Avatar answered Jan 04 '23 20:01

SChalice


Are you setting StretchBlt mode using SetStretchBltMode?

HALFTONE

Maps pixels from the source rectangle into blocks of pixels in the destination rectangle. The average color over the destination block of pixels approximates the color of the source pixels.

After setting the HALFTONE stretching mode, an application must call the SetBrushOrgEx function to set the brush origin. If it fails to do so, brush misalignment occurs.

like image 87
Roman R. Avatar answered Jan 04 '23 21:01

Roman R.