• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 645
  • Last Modified:

save view as image

how to save the current view as image(bmp, gif etc..)?
0
Meir Rivkin
Asked:
Meir Rivkin
  • 8
  • 5
  • 4
  • +2
1 Solution
 
migelCommented:
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
 
jkrCommented:
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
 
MadYugoslavCommented:
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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
Meir RivkinFull stack Software EngineerAuthor Commented:
MadYugoslav: and no that i have the HBITMAP how can use it to do the saving part?
0
 
Meir RivkinFull stack Software EngineerAuthor Commented:
    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
 
jkrCommented:
Did you check out http://www.codeguru.com/bitmap/window_to_file.shtml ('Writing a window image to a BMP file') ?
0
 
migelCommented:
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
 
jkrCommented:
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
 
MadYugoslavCommented:
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
 
Meir RivkinFull stack Software EngineerAuthor Commented:
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
 
MadYugoslavCommented:
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
 
MadYugoslavCommented:
I mean that argument You pass to my function is pointer to window (CWnd*) not CView*.
0
 
migelCommented:
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
 
jkrCommented:
sedgwick, did you check my comments?
0
 
Meir RivkinFull stack Software EngineerAuthor Commented:
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
 
Meir RivkinFull stack Software EngineerAuthor Commented:
jkr: sorry not WriteToFile() but:
WriteDIB( szFile, hDIB ) and also some other functions which seems to be missing in this article.
0
 
Meir RivkinFull stack Software EngineerAuthor Commented:
MadYugoslav: the view is visible in that point.
0
 
MadYugoslavCommented:
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
 
Meir RivkinFull stack Software EngineerAuthor Commented:
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
 
ComTechCommented:
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
 
migelCommented:
oops
what a service :-)
0
 
Meir RivkinFull stack Software EngineerAuthor Commented:
migel:

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

cheers
0

Featured Post

Important Lessons on Recovering from Petya

In their most recent webinar, Skyport Systems explores ways to isolate and protect critical databases to keep the core of your company safe from harm.

  • 8
  • 5
  • 4
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now