Solved

save view as image

Posted on 2001-07-05
22
566 Views
Last Modified: 2013-11-20
how to save the current view as image(bmp, gif etc..)?
0
Comment
Question by:sedgwick
  • 8
  • 5
  • 4
  • +2
22 Comments
 
LVL 12

Expert Comment

by:migel
Comment Utility
Hi!
you have to copy view appearance to the bitmap and then store it on the disk.
IMHO OnDraw calling will be simplest method:
1.Create memory DC
2.Create bitmap with view sizes
3. select 2 into the 1
4. call OnDraw with created DC
5. Slect old bitmap bak to the memory DC
6. Now your bitmap stores View image
7. To store bitmap onto the disk you must use DIB sections so read MSDN :-) (or www.codeguru.com - gdi sections there are several tpopics about dibs)

8.To store image in the different formats you have to use image processing library (see www.codeguru.com also)
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
See also http://www.codeproject.com/bitmap/screencapture.asp on how to capture the contents of a window.

More interesting for you might be http://www.codeguru.com/bitmap/window_to_file.shtml ('Writing a window image to a BMP file')
0
 
LVL 2

Expert Comment

by:MadYugoslav
Comment Utility
HBITMAP GetViewBitmap(CView* View, int x, int y, int W, int H)
{
   CDC* pDC;
   CDC tDC;
   HBITMAP Bitmap, oBitmap;

   pDC=View->GetDC();
   tDC.CreateCompatibleDC(pDC);

   Bitmap=CreateCompatibleBitmap(pDC->m_hDC, W, H);
   oBitmap=(HBITMAP )SelectObject(tDC.m_hDC, Bitmap);
   tDC.BitBlt(0, 0, W, H, pDC, x, y, SRCCOPY);

   SelectObject(tDC.m_hDC, oBitmap);
   View->ReleaseDC(pDC);

   return(Bitmap);
}
0
 
LVL 42

Author Comment

by:sedgwick
Comment Utility
MadYugoslav: and no that i have the HBITMAP how can use it to do the saving part?
0
 
LVL 42

Author Comment

by:sedgwick
Comment Utility
    CFileDialog dlgFile( false );
     dlgFile.m_ofn.lpstrTitle  = "Save Spectrum as an Image";

     // set directory
     CString strPath = GetDocument()->GetPathName();
     int start = strPath.ReverseFind('\\') + 1;
     CString strDir( strPath.Left(start) );
     dlgFile.m_ofn.lpstrInitialDir = strDir;

     // set type
     dlgFile.m_ofn.lpstrDefExt = "";
     dlgFile.m_ofn.lpstrFilter = "Bitmap File (*.bmp)\0*.bmp\0Tiff File (*.tif)\0*.tif\0Gif File (*.gif)\0*.gif\0Jpeg File(*.jpg)\0*.jpg\0\0";
     dlgFile.m_ofn.nFilterIndex = 1;

     // show dialog
     if ( dlgFile.DoModal() != IDOK )
          return;

     // get file name; if no extension then add one
     CString strFileName = dlgFile.GetPathName();
     if (strFileName.Find('.') < 0) { // no extension
          switch ( dlgFile.m_ofn.nFilterIndex ) {
          case 1:
               strFileName += "bmp";
               break;
          case 2:
               strFileName += "tif";
               break;
          case 3:
               strFileName += "gif";
               break;
          case 4:
               strFileName += "jpg";
               break;
          }    
     }

     CRect rect;
     GetClientRect(&rect);
     CSpectraAnalisysGuiApp* pApp = (CSpectraAnalisysGuiApp*)AfxGetApp();
     HBITMAP hBitmap = pApp->GetViewBitmap(this, rect.TopLeft().x, rect.TopLeft().y, rect.Width(), rect.Height());

now, how to save to the file?
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
Did you check out http://www.codeguru.com/bitmap/window_to_file.shtml ('Writing a window image to a BMP file') ?
0
 
LVL 12

Expert Comment

by:migel
Comment Utility
Here is class to handle DIBs in the MFC:
// header

#ifndef __DIBITMAP_H
#define __DIBITMAP_H

#include "stdafx.h"

class CDIBitmap
    {
public:
    BOOL AssignDDP(HBITMAP);
    CDIBitmap(HBITMAP hbm);
    ~CDIBitmap();
    CDIBitmap();

    BOOL    Draw(CDC& dc, CRect& rc);
    BOOL       Save(CFile& File);
    BOOL       Load(CFile& File);
      void    RealizeDIBPalette(HDC hDC, LPBITMAPINFO lpbmi);
      WORD    DIBNumColors();
      WORD    PaletteSize();
      DWORD   DIBHeight() {return wDIBHeight;}
      DWORD   DIBWidth()  {return wDIBWidth;}

protected:
    void ResetDIB();
      HBITMAP DIBToBitmap();
      LPSTR    FindDIBBits();
      HPALETTE CreateDIBPalette();
      HANDLE   BitmapToDIB(HBITMAP hBitmap);
      HPALETTE GetSystemPalette ();
      void     InitBitmapInfoHeader (LPBITMAPINFOHEADER lpBmInfoHdr,
                                            DWORD dwWidth,
                                            DWORD dwHeight,
                                              int nBPP);
private:
    LPSTR lpbi;

   HANDLE      hDIB;                // Handle to the DIB
   HPALETTE    hPal;                // Handle to the bitmap's palette.
   HBITMAP     hBitmap;             // Handle to the DDB.

   WORD        wDIBType;            // DIB's type - RGB, RLE4, RLE8, PM
   WORD        wDIBBits;            // Bits per pixel
   WORD        wDIBWidth;           // Print width of the DIB
   WORD        wDIBHeight;          // Print height of the DIB
   };


#endif //__DIBITMAP_H

//implementation

#include "stdafx.h"
#include "dibitmap.h"

#define WIDTHBYTES(bits)      (((bits) + 31) / 32 * 4)
#define IS_WIN30_DIB(lpbi)  ((*(LPDWORD) (lpbi)) == sizeof (BITMAPINFOHEADER))
#define PALVERSION   0x300
#define DIB_HEADER_MARKER   ((WORD) ('M' << 8) | 'B')

void CDIBitmap::RealizeDIBPalette(HDC, LPBITMAPINFO)
{
}

LPSTR CDIBitmap::FindDIBBits()

{
   return (lpbi + *(LPDWORD)lpbi + PaletteSize ());
}


HANDLE CDIBitmap::BitmapToDIB(HBITMAP hBmp)
{
   BITMAP             Bitmap;
   BITMAPINFOHEADER   bmInfoHdr;
   LPBITMAPINFOHEADER lpbmInfoHdr;
   LPSTR              lpBits;
   HDC                hMemDC;
   HPALETTE           hOldPal = NULL;

      // Do some setup -- make sure the Bitmap passed in is valid,
      //  get info on the bitmap (like its height, width, etc.),
      //  then setup a BITMAPINFOHEADER.

   if (!hBmp)
      return NULL;

   if (!GetObject (hBmp, sizeof (Bitmap), (LPSTR) &Bitmap))
      return NULL;

   InitBitmapInfoHeader (&bmInfoHdr,
                         Bitmap.bmWidth,
                         Bitmap.bmHeight,
                         4);


      // Now allocate memory for the DIB.  Then, set the BITMAPINFOHEADER
      //  into this memory, and find out where the bitmap bits go.
    lpbi = (LPSTR)&bmInfoHdr;

   hDIB = GlobalAlloc (GHND, sizeof (BITMAPINFOHEADER) + PaletteSize()+bmInfoHdr.biSizeImage);

   if (!hDIB)
      return NULL;

   lpbmInfoHdr  = (LPBITMAPINFOHEADER) GlobalLock (hDIB);
   *lpbmInfoHdr = bmInfoHdr;
   lpbi = (LPSTR)lpbmInfoHdr;
   lpBits  = (LPSTR)lpbmInfoHdr + lpbmInfoHdr->biSize + PaletteSize();


      // Now, we need a DC to hold our bitmap.  If the app passed us
      //  a palette, it should be selected into the DC.

   hMemDC       = GetDC (NULL);

   if (hPal)
      {
      hOldPal = SelectPalette (hMemDC, hPal, FALSE);
      RealizePalette (hMemDC);
      }



      // We're finally ready to get the DIB.  Call the driver and let
      //  it party on our bitmap.  It will fill in the color table,
      //  and bitmap bits of our global memory block.

   if (!GetDIBits (hMemDC,
                   hBmp,
                   0,
                   Bitmap.bmHeight,
                   lpBits,
                   (LPBITMAPINFO) lpbmInfoHdr,
                   DIB_RGB_COLORS))
      {
      GlobalUnlock (hDIB);
      GlobalFree (hDIB);
      hDIB = NULL;
      }
   else
      GlobalUnlock (hDIB);


      // Finally, clean up and return.

   if (hOldPal)
      SelectPalette (hMemDC, hOldPal, FALSE);

   ReleaseDC (NULL, hMemDC);

   return hDIB;
}

HPALETTE CDIBitmap::CreateDIBPalette()

{
   LPLOGPALETTE     lpPal;
   HANDLE           hLogPal;
   int              i, wNumColors;
   LPBITMAPINFO     lpbmi;
   LPBITMAPCOREINFO lpbmc;
   BOOL             bWinStyleDIB;

   if (!hDIB)
      return NULL;

   lpbi         = (LPSTR)GlobalLock (hDIB);
   lpbmi        = (LPBITMAPINFO) lpbi;
   lpbmc        = (LPBITMAPCOREINFO) lpbi;
   wNumColors   = DIBNumColors ();
   bWinStyleDIB = IS_WIN30_DIB (lpbi);

   if (wNumColors)
      {
      hLogPal = GlobalAlloc (GHND, sizeof (LOGPALETTE) +
                             sizeof (PALETTEENTRY) * wNumColors);

      if (!hLogPal)
         {
//         DIBError (ERR_CREATEPAL);
         GlobalUnlock (hDIB);
         return NULL;
         }

      lpPal = (LPLOGPALETTE) GlobalLock (hLogPal);

      lpPal->palVersion    = PALVERSION;
      lpPal->palNumEntries = wNumColors;

      for (i = 0;  i < wNumColors;  i++)
         {
         if (bWinStyleDIB)
            {
            lpPal->palPalEntry[i].peRed   = lpbmi->bmiColors[i].rgbRed;
            lpPal->palPalEntry[i].peGreen = lpbmi->bmiColors[i].rgbGreen;
            lpPal->palPalEntry[i].peBlue  = lpbmi->bmiColors[i].rgbBlue;
            lpPal->palPalEntry[i].peFlags = 0;
            }
         else
            {
            lpPal->palPalEntry[i].peRed   = lpbmc->bmciColors[i].rgbtRed;
            lpPal->palPalEntry[i].peGreen = lpbmc->bmciColors[i].rgbtGreen;
            lpPal->palPalEntry[i].peBlue  = lpbmc->bmciColors[i].rgbtBlue;
            lpPal->palPalEntry[i].peFlags = 0;
            }
         }

      hPal = CreatePalette (lpPal);

//      if (!hPal)
//         DIBError (ERR_CREATEPAL);

      GlobalUnlock (hLogPal);
      GlobalFree   (hLogPal);
   }

   GlobalUnlock (hDIB);

   return hPal;
}

void CDIBitmap::InitBitmapInfoHeader(LPBITMAPINFOHEADER lpBmInfoHdr, DWORD dwWidth, DWORD dwHeight, int nBPP)

{


   memset (lpBmInfoHdr, 0, sizeof (BITMAPINFOHEADER));

   lpBmInfoHdr->biSize      = sizeof (BITMAPINFOHEADER);
   lpBmInfoHdr->biWidth     = dwWidth;
   lpBmInfoHdr->biHeight    = dwHeight;
   lpBmInfoHdr->biPlanes    = 1;

   if (nBPP <= 1)
      nBPP = 1;
   else if (nBPP <= 4)
      nBPP = 4;
   else if (nBPP <= 8)
      nBPP = 8;
   else
      nBPP = 24;

   lpBmInfoHdr->biBitCount  = nBPP;
      wDIBHeight = dwHeight;
      wDIBWidth = dwWidth;
      wDIBType =  BI_RGB;
      wDIBBits = nBPP;
      lpBmInfoHdr->biSizeImage = WIDTHBYTES (dwWidth * nBPP) * dwHeight;
}

WORD CDIBitmap::DIBNumColors()

{
   WORD wBitCount;


      // If this is a Windows style DIB, the number of colors in the
      //  color table can be less than the number of bits per pixel
      //  allows for (i.e. lpbi->biClrUsed can be set to some value).
      //  If this is the case, return the appropriate value.

   if (IS_WIN30_DIB (lpbi))
      {
      DWORD dwClrUsed;

      dwClrUsed = ((LPBITMAPINFOHEADER) lpbi)->biClrUsed;

      if (dwClrUsed)
         return (WORD) dwClrUsed;
      }


      // Calculate the number of colors in the color table based on
      //  the number of bits per pixel for the DIB.

   if (IS_WIN30_DIB (lpbi))
      wBitCount = ((LPBITMAPINFOHEADER) lpbi)->biBitCount;
   else
      wBitCount = ((LPBITMAPCOREHEADER) lpbi)->bcBitCount;

   switch (wBitCount)
      {
      case 1:
         return 2;

      case 4:
         return 16;

      case 8:
         return 256;

      default:
         return 0;
      }
}

WORD CDIBitmap::PaletteSize()
{
   if (IS_WIN30_DIB (lpbi))
      return (DIBNumColors () * sizeof (RGBQUAD));
   else
      return (DIBNumColors () * sizeof (RGBTRIPLE));
}

BOOL CDIBitmap::Load(CFile& File)

{
      BITMAPFILEHEADER   bmfHeader;
      LPBITMAPINFOHEADER lpbih;
      DWORD              dwBitsSize;
      LPSTR              pDIB;


      // get length of DIB in bytes for use when reading

      // Go read the DIB file header and check if it's valid.

      if ((File.Read ((void*) &bmfHeader, sizeof (bmfHeader)) != sizeof (bmfHeader)) ||
          (bmfHeader.bfType != DIB_HEADER_MARKER))
        {
      //      DIBError (ERR_NOT_DIB);
        return NULL;
        }

      dwBitsSize = bmfHeader.bfSize;


      hDIB = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT, dwBitsSize - sizeof(BITMAPFILEHEADER));

      if (hDIB == 0)
       {
      //     DIBError (ERR_MEMORY);
       return NULL;
       }

      pDIB = (LPSTR)GlobalLock (hDIB);
      lpbih = (LPBITMAPINFOHEADER )pDIB;
      // Go read the bits.

      if (!File.Read(pDIB, dwBitsSize - sizeof(BITMAPFILEHEADER)))
        {
        GlobalUnlock (hDIB);
        GlobalFree   (hDIB);
      //      DIBError (ERR_READ);
        return NULL;
        }

      wDIBHeight = lpbih->biHeight;
      wDIBWidth = lpbih->biWidth;
      wDIBType =  BI_RGB;
      wDIBBits = lpbih->biBitCount*lpbih->biPlanes;

      GlobalUnlock (hDIB);
      hPal = CreateDIBPalette();
      hBitmap = DIBToBitmap();
      return TRUE;
}


BOOL CDIBitmap::Save(CFile& File)
{
    BITMAPFILEHEADER      hdr;
    LPBITMAPINFOHEADER  lpbih;

    if (!hDIB)
      return FALSE;

    lpbi = (LPSTR)GlobalLock (hDIB);
      lpbih = (LPBITMAPINFOHEADER)lpbi;
    /* Fill in the fields of the file header */
    hdr.bfType            = DIB_HEADER_MARKER;
    hdr.bfSize            = GlobalSize(hDIB) + sizeof (BITMAPFILEHEADER);
    hdr.bfReserved1 = 0;
    hdr.bfReserved2 = 0;
    hdr.bfOffBits   = (DWORD)sizeof(BITMAPFILEHEADER) + lpbih->biSize + PaletteSize();

    /* Write the file header */
    File.Write((LPSTR)&hdr, sizeof (BITMAPFILEHEADER));

    /* Write the DIB header and the bits */
    File.Write((LPSTR)lpbi, GlobalSize(hDIB));

    GlobalUnlock (hDIB);
    return TRUE;
}

HBITMAP CDIBitmap::DIBToBitmap()
{
  LPSTR    lpDIBHdr, lpDIBBits;
   HDC      hDC;
   HPALETTE hOldPal = NULL;

   if (!hDIB)
      return NULL;

   lpDIBHdr  = lpbi = (LPSTR) GlobalLock (hDIB);

   lpDIBBits = FindDIBBits ();
   hDC       = GetDC (NULL);

   if (!hDC)
      {
      GlobalUnlock (hDIB);
      return NULL;
      }

   if (hPal)
      hOldPal = SelectPalette (hDC, hPal, FALSE);

   RealizePalette (hDC);

   hBitmap = CreateDIBitmap (hDC,
                             (LPBITMAPINFOHEADER) lpDIBHdr,
                             CBM_INIT,
                             lpDIBBits,
                             (LPBITMAPINFO) lpDIBHdr,
                             DIB_RGB_COLORS);

//   if (!hBitmap)
//      DIBError (ERR_CREATEDDB);

   if (hOldPal)
      SelectPalette (hDC, hOldPal, FALSE);

   ReleaseDC (NULL, hDC);
   GlobalUnlock (hDIB);

   return hBitmap;
}


BOOL CDIBitmap::Draw(CDC&dc, CRect& rc)

{
   HDC      hMemDC;
   HBITMAP  hOldBitmap;
   HPALETTE hOldPal1 = NULL;
   HPALETTE hOldPal2 = NULL;


   hMemDC = CreateCompatibleDC (dc.m_hDC);

   if (!hMemDC)
      return FALSE;

   if (hPal)
      {
      hOldPal1   = SelectPalette (hMemDC, hPal, FALSE);
      hOldPal2   = SelectPalette (dc.m_hDC, hPal, FALSE);
      // Assume the palette's already been realized (no need to
      //  call RealizePalette().  It should have been realized in
      //  our WM_QUERYNEWPALETTE or WM_PALETTECHANGED messages...
      }

   hOldBitmap = (HBITMAP)SelectObject (hMemDC, hBitmap);

   SetStretchBltMode (dc.m_hDC, COLORONCOLOR);

   BitBlt (dc.m_hDC,
              rc.left,
              rc.top,
              rc.right - rc.left,
              rc.bottom - rc.top,
              hMemDC,
              0,0,
              SRCCOPY);

   SelectObject (hMemDC, hOldBitmap);

   if (hOldPal1)
      SelectPalette (hMemDC, hOldPal1, FALSE);

   if (hOldPal2)
      SelectPalette (dc.m_hDC, hOldPal2, FALSE);

   DeleteDC (hMemDC);
   return TRUE;
}

CDIBitmap::CDIBitmap()

{
      hPal = NULL;
      hDIB = NULL;
      hBitmap = NULL;
      lpbi = NULL;
      wDIBBits = wDIBHeight = wDIBType = wDIBWidth = 0;
}

CDIBitmap::~CDIBitmap()
{
      if (hPal)
            DeleteObject(hPal);
      if (hBitmap)
            DeleteObject(hBitmap);
      if (hDIB)
            GlobalFree(hDIB);
}

CDIBitmap::CDIBitmap(HBITMAP hbm)

{
}

BOOL CDIBitmap::AssignDDP(HBITMAP hBmp)
{
      if (!hBmp)
            return NULL;

      ResetDIB();
      /* get the current palette */
      hPal = GetSystemPalette();
      BitmapToDIB(hBmp);
      hBitmap = DIBToBitmap();
return TRUE;
}

void CDIBitmap::ResetDIB()
{
      if (hPal)
            DeleteObject(hPal);
      if (hBitmap)
            DeleteObject(hBitmap);
      if (hDIB)
            GlobalFree(hDIB);
}

HPALETTE CDIBitmap::GetSystemPalette ()
{
   HDC           hDC;
   HPALETTE      hPal = NULL;
   HANDLE        hLogPal;
   LPLOGPALETTE  lpLogPal;
   int           i, nColors;


      // Find out how many palette entries we want.

   hDC = GetDC (NULL);
   if (!hDC)
      {
//      DIBError (ERR_GETDC);
      return NULL;
      }

      // Find out the number of palette entries on this
      //  defice.

   nColors = GetDeviceCaps (hDC, SIZEPALETTE);

      // For non-palette devices, we'll use the # of system
      //  colors for our palette size.

   if (!nColors)
      nColors = GetDeviceCaps (hDC, NUMCOLORS);

   ReleaseDC (NULL, hDC);

      // Allocate room for the palette and lock it.

   hLogPal = GlobalAlloc (GHND, sizeof (LOGPALETTE) +
                           nColors * sizeof (PALETTEENTRY));

   if (!hLogPal)
      {
//      DIBError (ERR_CREATEPAL);
      return NULL;
      }

   lpLogPal = (LPLOGPALETTE) GlobalLock (hLogPal);

   lpLogPal->palVersion    = PALVERSION;
   lpLogPal->palNumEntries = nColors;

   for (i = 0;  i < nColors;  i++)
      {
      lpLogPal->palPalEntry[i].peBlue  = 0;
      *((LPWORD) (&lpLogPal->palPalEntry[i].peRed)) = i;
      lpLogPal->palPalEntry[i].peFlags = PC_EXPLICIT;
      }

      // Go ahead and create the palette.  Once it's created,
      //  we no longer need the LOGPALETTE, so free it.

   hPal = CreatePalette (lpLogPal);

   GlobalUnlock (hLogPal);
   GlobalFree (hLogPal);

   return hPal;
}
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
OK, assuming that my comment again got buried under a huge pile of code, here it is again: Did you check out http://www.codeguru.com/bitmap/window_to_file.shtml ('Writing a window image to a BMP file') ? (Why reinvent the wheel?)
0
 
LVL 2

Accepted Solution

by:
MadYugoslav earned 100 total points
Comment Utility
You have code for saving bitmap in file MSDN.
Graphics and Multimedia Code Samples: Platform SDK: SAVEBMP.C

Here is the code:

SAVEBMP.C
/******************************Module*Header*******************************\
* Module Name: savebmp.c
*
*
* Created: 06-Jan-1992 10:59:36
*
* Copyright 1993 - 1998 Microsoft Corporation
*
* Contains the main routine, SaveBitmapFile, for saving a DDB into file
* in DIB format.
*
* Dependencies:
*
*   (#defines)
*   (#includes)
*       #include <windows.h>
*       #include "jtypes.h"
*
\**************************************************************************/
#include <windows.h>
#include "julia.h"
 
extern HPALETTE ghPal;
extern HWND ghwndMain;
extern char   gtext[256];
BOOL SaveBitmapFile(HDC, HBITMAP, PSTR);
// void ErrorOut(char errstring[30]);
 
/******************************Public*Routine******************************\
* SaveBitmapFile
*
*
* Effects: Save pInfo->hBmpSaved into disk specified by pszFileName
*
* Warnings: assumes hBmpSaved is not selected into window's DC other than
*           pInfo->hwnd's DC
*
\**************************************************************************/
 
BOOL SaveBitmapFile(HDC hDC, HBITMAP hBmp, PSTR pszFileName)
{
    int         hFile;
    OFSTRUCT    ofReOpenBuff;
    HBITMAP     hTmpBmp, hBmpOld;
    BOOL        bSuccess;
    BITMAPFILEHEADER    bfh;
    PBITMAPINFO pbmi;
    PBYTE       pBits;
    BITMAPINFO  bmi;
    PBYTE pjTmp, pjTmpBmi;
    ULONG sizBMI;
 
 
    bSuccess = TRUE;
#if 0
    if (ghPal) {
        SelectPalette(hDC, ghPal, FALSE);
        RealizePalette(hDC);
    }
#endif
    if (!hBmp) {
        MessageBox(ghwndMain,  
       GetStringRes (IDS_NO_BITMAP_TO_SAVE),
   NULL, MB_OK);
        return FALSE;
    }
 
    //
    // Let the graphics engine to retrieve the dimension of the bitmap for us
    // GetDIBits uses the size to determine if it's BITMAPCOREINFO or BITMAPINFO
    // if BitCount != 0, color table will be retrieved
    //
    bmi.bmiHeader.biSize = 0x28;              // GDI need this to work
    bmi.bmiHeader.biBitCount = 0;             // don't get the color table
    if ((GetDIBits(hDC, hBmp, 0, 0, (LPSTR)NULL, &bmi, DIB_RGB_COLORS)) == 0) {
       return FALSE;
    }
 
    //
    // Now that we know the size of the image, alloc enough memory to retrieve
    // the actual bits
    //
    if ((pBits = (PBYTE)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
                bmi.bmiHeader.biSizeImage)) == NULL) {
        return FALSE;
    }
 
    //
    // Note: 24 bits per pixel has no color table.  So, we don't have to
    // allocate memory for retrieving that.  Otherwise, we do.
    //
    pbmi = &bmi;                                      // assume no color table
 
    switch (bmi.bmiHeader.biBitCount) {
        case 24:                                      // has color table
            sizBMI = sizeof(BITMAPINFOHEADER);
            break;
        case 16:
        case 32:
            sizBMI = sizeof(BITMAPINFOHEADER)+sizeof(DWORD)*3;
            break;
        default:
            sizBMI = sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*(1<<bmi.bmiHeader.biBitCount);
            break;
 
    }
 
    //
    // Allocate memory for color table if it is not 24bpp...
    //
    if (sizBMI != sizeof(BITMAPINFOHEADER)) {
        ULONG       sizTmp;
        //
        // I need more memory for the color table
        //
        if ((pbmi = (PBITMAPINFO)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, sizBMI )) == NULL) {
            bSuccess = FALSE;
            goto ErrExit1;
        }
        //
        // Now that we've a bigger chunk of memory, let's copy the Bitmap
        // info header data over
        //
        pjTmp = (PBYTE)pbmi;
        pjTmpBmi = (PBYTE)&bmi;
        sizTmp = sizeof(BITMAPINFOHEADER);
 
        while(sizTmp--)
        {
            *(((PBYTE)pjTmp)++) = *((pjTmpBmi)++);
        }
    }
 
    //
    // Let's open the file and get ready for writing
    //
    if ((hFile = OpenFile(pszFileName, (LPOFSTRUCT)&ofReOpenBuff,
                 OF_CREATE | OF_WRITE)) == -1) {
        MessageBox(ghwndMain, GetStringRes(IDS_FILE_OPEN_FAILED),  
   NULL, MB_OK);
        goto ErrExit2;
    }
 
    //
    // But first, fill in the info for the BitmapFileHeader
    //
    bfh.bfType = 0x4D42;                            // 'BM'
    bfh.bfSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizBMI+
        pbmi->bmiHeader.biSizeImage;
    bfh.bfReserved1 =
    bfh.bfReserved2 = 0;
    bfh.bfOffBits = sizeof(BITMAPFILEHEADER)+sizBMI;
 
    //
    // Write out the file header now
    //
    if (_lwrite(hFile, (LPSTR)&bfh, sizeof(BITMAPFILEHEADER)) == -1) {
        bSuccess = FALSE;
        goto ErrExit3;
    }
 
    //
    // Bitmap can't be selected into a DC when calling GetDIBits
    // Assume that the hDC is the DC where the bitmap would have been selected
    // if indeed it has been selected
    //
    if (hTmpBmp = CreateCompatibleBitmap(hDC, pbmi->bmiHeader.biWidth, pbmi->bmiHeader.biHeight)) {
        hBmpOld = SelectObject(hDC, hTmpBmp);
        if ((GetDIBits(hDC, hBmp, 0, pbmi->bmiHeader.biHeight, (LPSTR)pBits, pbmi, DIB_RGB_COLORS))==0){
            bSuccess = FALSE;
            goto ErrExit4;
        }
    } else {
        MessageBox(ghwndMain,  
GetStringRes (IDS_BITMAP_NOT_CREATED),
NULL, MB_OK);
        bSuccess = FALSE;
        goto ErrExit3;
    }
 
    //
    // Now write out the BitmapInfoHeader and color table, if any
    //
    if (_lwrite(hFile, (LPSTR)pbmi, sizBMI) == -1) {
        bSuccess = FALSE;
        goto ErrExit4;
    }
 
    //
    // write the bits also
    //
    if (_lwrite(hFile, (LPSTR)pBits, pbmi->bmiHeader.biSizeImage) == -1) {
        bSuccess = FALSE;
        goto ErrExit4;
    }
 
 
ErrExit4:
    SelectObject(hDC, hBmpOld);
    DeleteObject(hTmpBmp);
ErrExit3:
    _lclose(hFile);
ErrExit2:
    GlobalFree(pbmi);
ErrExit1:
    GlobalFree(pBits);
    return bSuccess;
}
 
 
#if 0  
/************************************************************************
 * void ErrorOut(char errstring[30])
 *
 * Purpose: Print out an meainful error code by means of
 *  GetLastError and printf
 *
 * Inputs:  errstring - the action that failed, passed by the
 *      calling proc.
 *
 * Returns: none
 *
 * Calls:   GetLastError
 *
 * History:
 * 09-13-91 Pete Grey   Created.
 *
\************************************************************************/
 
 
void ErrorOut(char errstring[30])
{
DWORD Error;
CHAR  str[80];
 
Error= GetLastError();
wsprintf((LPSTR) str, "Error on %s = %d\n", errstring, Error);
OutputDebugString(str);
}
 
#endif
0
 
LVL 42

Author Comment

by:sedgwick
Comment Utility
thanks migel and MadYugoslav for your help, but it seems that it doesn't save properly.
i used both comments and apparently it saved an empty view (or image).

maybe i'm missing something here,
first i tryied this one:
CMyView::SaveAsImage()
{
     CFile file(strFileName.GetBuffer(0), CFile::modeCreate|CFile::modeWrite);
     CDIBitmap DIBitmap;
     DIBitmap.Draw(*GetDC(), rect);
     ASSERT(DIBitmap.Save(file));
}

then i tryied this one:
//GetViewBitmap: by MadYugoslav

CMyView::SaveAsImage()
{
     CRect rect;
     GetClientRect(&rect);
     HBITMAP hBitmap = GetViewBitmap(this, rect.TopLeft().x, rect.TopLeft().y, rect.Width(), rect.Height());
     CFile file(strFileName.GetBuffer(0), CFile::modeCreate | CFile::modeWrite);

     CDIBitmap DIBitmap(hBitmap);
     ASSERT(DIBitmap.Save(file));
}

any idea?
0
 
LVL 2

Expert Comment

by:MadYugoslav
Comment Utility
Is your view visible at time that You call function to save bmp.
Second try is to change CView* to CWnd* and try again.
0
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

 
LVL 2

Expert Comment

by:MadYugoslav
Comment Utility
I mean that argument You pass to my function is pointer to window (CWnd*) not CView*.
0
 
LVL 12

Expert Comment

by:migel
Comment Utility
Hm
maybe i'm missing something here,
first i tryied this one:
CMyView::SaveAsImage()
{
    CFile file(strFileName.GetBuffer(0),
CFile::modeCreate|CFile::modeWrite);
CDC* pdc = GetDC();
    CDIBitmap DIBitmap;
//    DIBitmap.Draw(*GetDC(), rect); ??
// must be
   CBitmap bmp;
  CCD dcMem;
 dcMem.CreateCompatibleDC(pdc);
  bmp.CreateCompatibleBitmap(pdc, rect);
  CBitmap* bmOld = dcMem.SelectObject(&bmp);
 Draw(&dcMem,...);
dcMem.SelectObject(bmOld);

DIBitmap.AssignDDP((HBITMAP)bmp);
    ASSERT(DIBitmap.Save(file));
}
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
sedgwick, did you check my comments?
0
 
LVL 42

Author Comment

by:sedgwick
Comment Utility
jkr: yes i did, it didn't compile, i think some 'includes' are missing or something like that. and also there is a call to a fucntion WriteToFile() which its implementation is missing.

migel: i tryied your code and i got a total black bitmap for some reason.

MadYugoslav: how to get pointer to a window from my CView class? (instead of 'this' should i put GetParent()?)

0
 
LVL 42

Author Comment

by:sedgwick
Comment Utility
jkr: sorry not WriteToFile() but:
WriteDIB( szFile, hDIB ) and also some other functions which seems to be missing in this article.
0
 
LVL 42

Author Comment

by:sedgwick
Comment Utility
MadYugoslav: the view is visible in that point.
0
 
LVL 2

Expert Comment

by:MadYugoslav
Comment Utility
Than You can try to change my function as I mentioned:
change CView* into CWnd*
When You call function pass as argument parent window of CView* window (possibly CFrameWnd* if it is Doc application).
0
 
LVL 42

Author Comment

by:sedgwick
Comment Utility
its working !!!!!!!!

i should have call one more function before the saving part which is:

DIBitmap.AssignDDP(hBitmap);

btw, here's the full code for saving as bitmap:
     CRect rect;
     GetClientRect(&rect);
     CSpectraAnalisysGuiApp* pApp = (CSpectraAnalisysGuiApp*)AfxGetApp();
     HBITMAP hBitmap = pApp->GetViewBitmap(GetParent(), rect.TopLeft().x, rect.TopLeft().y,
                                                       rect.Width(), rect.Height());
     CFile file(strFileName.GetBuffer(0), CFile::modeCreate|CFile::modeWrite);
     CDIBitmap DIBitmap;
     DIBitmap.AssignDDP(hBitmap);
     ASSERT(DIBitmap.Save(file));
     file.Close();

thanks Yugolslav and Migle for your help.

i'll ask to split the points between u 2.

cheers
0
 

Expert Comment

by:ComTech
Comment Utility
sedgwick, I have refunded 100 of your 200 points to award to migel.

I will accept this question for MadYugoslav, then you need to open another question in this Topic Area.  Title the Question  "Points for migel"  and in the comment box, write "For the points split in question #20146392."

And that should complete the split.

Thank you,
ComTech
Community Support Moderator
0
 
LVL 12

Expert Comment

by:migel
Comment Utility
oops
what a service :-)
0
 
LVL 42

Author Comment

by:sedgwick
Comment Utility
migel:

i post a question for your pts, dont worry mate.
just leave a comment...

cheers
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Introduction: Load and Save to file, Document-View interaction inside the SDI. Continuing from the second article about sudoku.   Open the project in visual studio. From the class view select CSudokuDoc and double click to open the header …
Introduction: Finishing the grid – keyboard support for arrow keys to manoeuvre, entering the numbers.  The PreTranslateMessage function is to be used to intercept and respond to keyboard events. Continuing from the fourth article about sudoku. …
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now