How to stitch two bitmaps together

Hello experts,
  I got a hard question here. I am programming with MFC in VS6. I have three different .bmp files. Based on the input of the user, I want to concatinate(or stitch) two together, or mabey all three, and display the newly constructed bitmap to the user. Any ideas how to do that?
v3203Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

 
Roshan DavisCommented:
1. Load bitmaps into a memory DC
2. Combine the bitmaps using BitBlt function by giving different destination points based on image width/hieght
3. Save combined image to file

You can take reference of following functions to do that

   BOOL LoadBitmapFromBMPFile( LPTSTR szFileName, HBITMAP *phBitmap,
   HPALETTE *phPalette )
   {

   BITMAP  bm;

   *phBitmap = NULL;
   *phPalette = NULL;

   // Use LoadImage() to get the image loaded into a DIBSection
   *phBitmap = (HBITMAP)LoadImage( NULL, szFileName, IMAGE_BITMAP, 0, 0,
               LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE );
   if( *phBitmap == NULL )
     return FALSE;

   // Get the color depth of the DIBSection
   GetObject(*phBitmap, sizeof(BITMAP), &bm );
   // If the DIBSection is 256 color or less, it has a color table
   if( ( bm.bmBitsPixel * bm.bmPlanes ) <= 8 )
   {
   HDC           hMemDC;
   HBITMAP       hOldBitmap;
   RGBQUAD       rgb[256];
   LPLOGPALETTE  pLogPal;
   WORD          i;

   // Create a memory DC and select the DIBSection into it
   hMemDC = CreateCompatibleDC( NULL );
   hOldBitmap = (HBITMAP)SelectObject( hMemDC, *phBitmap );
   // Get the DIBSection's color table
   GetDIBColorTable( hMemDC, 0, 256, rgb );
   // Create a palette from the color tabl
   pLogPal = (LOGPALETTE *)malloc( sizeof(LOGPALETTE) + (256*sizeof(PALETTEENTRY)) );
   pLogPal->palVersion = 0x300;
   pLogPal->palNumEntries = 256;
   for(i=0;i<256;i++)
   {
     pLogPal->palPalEntry[i].peRed = rgb[i].rgbRed;
     pLogPal->palPalEntry[i].peGreen = rgb[i].rgbGreen;
     pLogPal->palPalEntry[i].peBlue = rgb[i].rgbBlue;
     pLogPal->palPalEntry[i].peFlags = 0;
   }
   *phPalette = CreatePalette( pLogPal );
   // Clean up
   free( pLogPal );
   SelectObject( hMemDC, hOldBitmap );
   DeleteDC( hMemDC );
   }
   else   // It has no color table, so use a halftone palette
   {
   HDC    hRefDC;

   hRefDC = GetDC( NULL );
   *phPalette = CreateHalftonePalette( hRefDC );
   ReleaseDC( NULL, hRefDC );
   }
   return TRUE;

   }


//or we can save the dc to diskfile formatted .bmp
int SaveBitmapToFile(HBITMAP hBitmap ,
                               LPSTR lpFileName) // hBitmap we got it above ,remember
{
      //lpFileName the filename
      HDC hDC;

      int iBits;
      //the bytes every pixle hold in the current resolution
      WORD wBitCount;
      WORD dwPaletteSize=0,
      dwBmBitsSize,
      dwDIBSize, dwWritten;
      BITMAP Bitmap;
      BITMAPFILEHEADER bmfHdr;

      BITMAPINFOHEADER bi;

      LPBITMAPINFOHEADER lpbi;

      HANDLE fh, hDib, hPal,hOldPal=NULL;

      hDC = CreateDC("DISPLAY",NULL,NULL,NULL);
      iBits = GetDeviceCaps(hDC, BITSPIXEL) *
      GetDeviceCaps(hDC, PLANES);
      DeleteDC(hDC);

      if (iBits < = 1) wBitCount = 1;
      else if (iBits < = 4) wBitCount = 4;
      else if (iBits < = 8) wBitCount = 8;
      else if (iBits < = 24) wBitCount = 24;
      if (wBitCount < = 8) dwPaletteSize = (1 < < wBitCount) * sizeof(RGBQUAD);

      GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);
      bi.biSize = sizeof(BITMAPINFOHEADER);
      bi.biWidth = Bitmap.bmWidth;
      bi.biHeight = Bitmap.bmHeight;
      bi.biPlanes = 1;
      bi.biBitCount = wBitCount;
      bi.biCompression = BI_RGB;
      bi.biSizeImage = 0;
      bi.biXPelsPerMeter = 0;
      bi.biYPelsPerMeter = 0;
      bi.biClrUsed = 0;
      bi.biClrImportant = 0;

      dwBmBitsSize = ((Bitmap.bmWidth * wBitCount+31)/32)* 4 *Bitmap.bmHeight ;
      
      hDib = GlobalAlloc(GHND,dwBmBitsSize + dwPaletteSize+sizeof(BITMAPINFOHEADER));
      lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
      *lpbi = bi;

      // handle the palette
      hPal = GetStockObject(DEFAULT_PALETTE);

      if (hPal)
      {
            hDC = GetDC(NULL);
            hOldPal = SelectPalette(hDC, hPal, FALSE);
            RealizePalette(hDC);
      }

      GetDIBits(hDC,
                    hBitmap,
                    0,
                    (UINT) Bitmap.bmHeight,
                    (LPSTR)lpbi + sizeof(BITMAPINFOHEADER) + dwPaletteSize,
                    (BITMAPINFOHEADER *)lpbi, DIB_RGB_COLORS);
      
      if (hOldPal)
      {
            SelectPalette(hDC, hOldPal, TRUE);
            RealizePalette(hDC);
            ReleaseDC(NULL, hDC);
      }

      //create the bmp file
      fh = CreateFile(lpFileName,
                              GENERIC_WRITE,
                              0,
                              NULL,
                              CREATE_ALWAYS,
                              FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
                              NULL);

      
      if (fh == INVALID_HANDLE_VALUE) return FALSE;

      //set bmp fileheader
      bmfHdr.bfType = 0x4D42; // "BM"
      dwDIBSize = sizeof(BITMAPFILEHEADER) +
                        sizeof(BITMAPINFOHEADER) +
                        dwPaletteSize +
                        dwBmBitsSize;

      bmfHdr.bfSize = dwDIBSize;
      bmfHdr.bfReserved1 = 0;
      bmfHdr.bfReserved2 = 0;

      bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) +
                                 (DWORD)sizeof(BITMAPINFOHEADER) +
                                 dwPaletteSize;

      // write the bmp header into file
      WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);

      // writhe content
      WriteFile(fh, (LPSTR)lpbi, dwDIBSize, &dwWritten, NULL);

      //clear
      GlobalUnlock(hDib);
      GlobalFree(hDib);
      CloseHandle(fh);
}

void CaptureScreen(LPCTSTR lpszFilePathName)
{
      BITMAPFILEHEADER      bmfHeader;
      BITMAPINFO                  *pbminfo;
      HBITMAP                        hBMP;
      CFile                        oFile;
      
      CDC            *pDC            = GetWindowDC();
      INT            nSizeImage      = 1024 * 768 * 3;
      CHAR      *pBuff            = new CHAR[sizeof(BITMAPINFOHEADER) + nSizeImage];
      pbminfo                        = (BITMAPINFO *)pBuff;
      hBMP                        = (HBITMAP)pDC->GetCurrentBitmap()->m_hObject;

      ZeroMemory(pbminfo, sizeof(BITMAPINFO));
      
      pbminfo->bmiHeader.biSize            = sizeof(BITMAPINFOHEADER);
      
      GetDIBits(pDC->m_hDC,
                    hBMP,
                    0,
                    1,
                    NULL,
                    pbminfo,
                    DIB_RGB_COLORS);

      GetDIBits(pDC->m_hDC,
                    hBMP,
                    0,
                    pbminfo->bmiHeader.biHeight,
                    pBuff + sizeof(BITMAPINFOHEADER),
                    pbminfo,
                    DIB_RGB_COLORS);
      
      ReleaseDC(pDC);

      bmfHeader.bfType            = 0x4d42; /*"BM"*/
      bmfHeader.bfSize            = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + nSizeImage;
      bmfHeader.bfReserved1      = 0;
      bmfHeader.bfReserved2      = 0;
      bmfHeader.bfOffBits            = (DWORD) sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

      oFile.Open(lpszFilePathName, CFile::modeWrite | CFile::modeCreate);

      oFile.Write(&bmfHeader, sizeof(BITMAPFILEHEADER));
      oFile.Write(pBuff, sizeof(BITMAPINFOHEADER) + pbminfo->bmiHeader.biSizeImage);
      delete []pBuff;
      oFile.Close();
}
0

Experts Exchange Solution brought to you by ConnectWise

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.