Search code examples
c++mfccdccbitmap

Can't Display Bitmap of Higher Resolution than CDC area


Hi there dear gurus and expert coders.

i am not gonna start with im a newbie and don't know much about image programming but unfortunately those are the facts :(

I am trying to display an image from a bitmap pointer *ImageData which is of resolution 1392x1032. I am trying to draw that at an area of resolution or size 627x474.

However, repeated trying doesnt seem to work. It works when I change the bitmap image I created from *ImageData width and height to resolution or size of around 627x474

I really do not know how to solve this after trying all possible solutions from various forums and google.

pDC is a CDC* and memDC is a CDC initialized in an earlier method Anything uninitialized here was initialized in other methods.

Here is my code dear humble gurus. Do provide me with guidance Yoda and Obi-Wan provided to Luke Skywalker.

void DemoControl::ShowImage( void *ImageData )
{


    int Width; //Width of Image From Camera
    int Height; //Height of Image From Camera

    int m_DisplayWidth = 627 ;//width of rectangle area to display
    int m_DisplayHeight = 474;//height of rectangle area to display

    GetImageSize( &Width, &Height ) ; //this will return Width = 1392, Height 1032

    CBitmap bitmap;

    bitmap.CreateBitmap(Width,Height,32,1,ImageData);

    CBitmap* pOldBitmap = memDC.SelectObject((CBitmap*)&bitmap);

    pDC->BitBlt(22, 24, 627, 474, &memDC, 0, 0, SRCCOPY);

    memDC.SelectObject((CBitmap*)pOldBitmap);

    ReleaseDC(pDC);

}

Ok heres some additional parts

I think i should explain how the flow goes.

(a) A class (lets say DemoTestingDlg class) will pass the CDC as below to another class (lets say DemoControl class)

m_Demo = new DemoControl ; 

m_Demo->Initialisation( this, this->GetDC() ) ; 

(b) At the DemoControl class

bool DemoControl::Initialisation( CDemoTestingDlg m_FormControl, CDC m_StaticDisplay ) {

          pDC = m_StaticDisplay ; 
          memDC.CreateCompatibleDC(pDC); 

}

pDC and memDC is as such in the header:

CDC* pDC ; CDC memDC; 

(c) If lets say an image is captured, the image pointer is passed to the DemoTestingDlg class which will subsequently call a showImage method in the Demo Control Class which is the method I wrote in the question. Am i doing it right?

Note: It did show an image if lets say they are of the same size (by they i mean the CDC and bitmap) so i was under the impression that my CDC pointer was passed correctly


Solution

  • StretchBlt is your friend :)

    Edit: OK how do you get pDC? When is your function called? Form OnPaint or DrawItem?

    This is a StretchBlt I do from a DrawItem call in an overriden CStatic.

    HDC hBitmapDC   = CreateCompatibleDC( pDrawItemStruct->hDC );
    
    HBITMAP hBitmap = GetBitmap();
    HGDIOBJ hOld    = SelectObject( hBitmapDC, (HGDIOBJ)hBitmap );
    
    StretchBlt( pDrawItemStruct->hDC, pDrawItemStruct->rcItem.left, pDrawItemStruct->rcItem.top, pDrawItemStruct->rcItem.right, pDrawItemStruct->rcItem.bottom,
                hBitmapDC, 0, 0, 4, 4, SRCCOPY );
    
    SelectObject( hBitmapDC, hOld );
    DeleteObject( hBitmapDC );
    

    Its not using the MFC classes to stretch a 4x4 bitmap into a larger space but works perfectly. My guess is that you aren't doing it in response to a WM_PAINT/WM_DRAWITEM and/or are using the wrong DC.

    Edit re your edit: Do you then call DrawImage from inside an OnPaint or DrawItem call?

    I would have thought you are better off not cacheing that CDC and passing the CDC in each time you wish to draw it.