Solved

save view as image

Posted on 2001-07-05
22
586 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
ID: 6256716
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
ID: 6256763
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
ID: 6258513
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
Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.

 
LVL 42

Author Comment

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

Author Comment

by:sedgwick
ID: 6262084
    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
ID: 6262907
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
ID: 6263008
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
ID: 6263176
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
ID: 6263896
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
ID: 6264908
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
ID: 6264932
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
 
LVL 2

Expert Comment

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

Expert Comment

by:migel
ID: 6265020
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
ID: 6265848
sedgwick, did you check my comments?
0
 
LVL 42

Author Comment

by:sedgwick
ID: 6268042
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
ID: 6268045
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
ID: 6268050
MadYugoslav: the view is visible in that point.
0
 
LVL 2

Expert Comment

by:MadYugoslav
ID: 6268093
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
ID: 6272381
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
ID: 6273258
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
ID: 6273935
oops
what a service :-)
0
 
LVL 42

Author Comment

by:sedgwick
ID: 6276181
migel:

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

cheers
0

Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Folder Comparison 12 54
sum67 challenge 35 97
sumHeights2  challenge 7 102
Sed question 2 83
Introduction: Dialogs (2) modeless dialog and a worker thread.  Handling data shared between threads.  Recursive functions. Continuing from the tenth article about sudoku.   Last article we worked with a modal dialog to help maintain informat…
If you use Adobe Reader X it is possible you can't open OLE PDF documents in the standard. The reason is the 'save box mode' in adobe reader X. Many people think the protected Mode of adobe reader x is only to stop the write access. But this fe…
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.
Along with being a a promotional video for my three-day Annielytics Dashboard Seminor, this Micro Tutorial is an intro to Google Analytics API data.

813 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

16 Experts available now in Live!

Get 1:1 Help Now