Meir Rivkin
asked on
save view as image
how to save the current view as image(bmp, gif etc..)?
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')
More interesting for you might be http://www.codeguru.com/bitmap/window_to_file.shtml ('Writing a window image to a BMP file')
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=CreateCompatibleBit map(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);
}
{
CDC* pDC;
CDC tDC;
HBITMAP Bitmap, oBitmap;
pDC=View->GetDC();
tDC.CreateCompatibleDC(pDC
Bitmap=CreateCompatibleBit
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);
}
ASKER
MadYugoslav: and no that i have the HBITMAP how can use it to do the saving part?
ASKER
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.lpstrInitial Dir = 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*)A fxGetApp() ;
HBITMAP hBitmap = pApp->GetViewBitmap(this, rect.TopLeft().x, rect.TopLeft().y, rect.Width(), rect.Height());
now, how to save to the file?
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.lpstrInitial
// 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
// 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*)A
HBITMAP hBitmap = pApp->GetViewBitmap(this, rect.TopLeft().x, rect.TopLeft().y, rect.Width(), rect.Height());
now, how to save to the file?
Did you check out http://www.codeguru.com/bitmap/window_to_file.shtml ('Writing a window image to a BMP file') ?
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::RealizeDIBPalet te(HDC, LPBITMAPINFO)
{
}
LPSTR CDIBitmap::FindDIBBits()
{
return (lpbi + *(LPDWORD)lpbi + PaletteSize ());
}
HANDLE CDIBitmap::BitmapToDIB(HBI TMAP 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.bi SizeImage) ;
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::CreateDIBPalett e()
{
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].peRe d = lpbmi->bmiColors[i].rgbRed ;
lpPal->palPalEntry[i].peGr een = lpbmi->bmiColors[i].rgbGre en;
lpPal->palPalEntry[i].peBl ue = lpbmi->bmiColors[i].rgbBlu e;
lpPal->palPalEntry[i].peFl ags = 0;
}
else
{
lpPal->palPalEntry[i].peRe d = lpbmc->bmciColors[i].rgbtR ed;
lpPal->palPalEntry[i].peGr een = lpbmc->bmciColors[i].rgbtG reen;
lpPal->palPalEntry[i].peBl ue = lpbmc->bmciColors[i].rgbtB lue;
lpPal->palPalEntry[i].peFl ags = 0;
}
}
hPal = CreatePalette (lpPal);
// if (!hPal)
// DIBError (ERR_CREATEPAL);
GlobalUnlock (hLogPal);
GlobalFree (hLogPal);
}
GlobalUnlock (hDIB);
return hPal;
}
void CDIBitmap::InitBitmapInfoH eader(LPBI TMAPINFOHE ADER 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->b iPlanes;
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(BITMAPFILEHE ADER) + 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(HBITM AP hbm)
{
}
BOOL CDIBitmap::AssignDDP(HBITM AP 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::GetSystemPalett e ()
{
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].p eBlue = 0;
*((LPWORD) (&lpLogPal->palPalEntry[i] .peRed)) = i;
lpLogPal->palPalEntry[i].p eFlags = 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;
}
// 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::RealizeDIBPalet
{
}
LPSTR CDIBitmap::FindDIBBits()
{
return (lpbi + *(LPDWORD)lpbi + PaletteSize ());
}
HANDLE CDIBitmap::BitmapToDIB(HBI
{
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.bi
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::CreateDIBPalett
{
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].peRe
lpPal->palPalEntry[i].peGr
lpPal->palPalEntry[i].peBl
lpPal->palPalEntry[i].peFl
}
else
{
lpPal->palPalEntry[i].peRe
lpPal->palPalEntry[i].peGr
lpPal->palPalEntry[i].peBl
lpPal->palPalEntry[i].peFl
}
}
hPal = CreatePalette (lpPal);
// if (!hPal)
// DIBError (ERR_CREATEPAL);
GlobalUnlock (hLogPal);
GlobalFree (hLogPal);
}
GlobalUnlock (hDIB);
return hPal;
}
void CDIBitmap::InitBitmapInfoH
{
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->b
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(BITMAPFILEHE
/* 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(HBITM
{
}
BOOL CDIBitmap::AssignDDP(HBITM
{
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::GetSystemPalett
{
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].p
*((LPWORD) (&lpLogPal->palPalEntry[i]
lpLogPal->palPalEntry[i].p
}
// 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;
}
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?)
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
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::m odeWrite);
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?
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
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
CDIBitmap DIBitmap(hBitmap);
ASSERT(DIBitmap.Save(file)
}
any idea?
Is your view visible at time that You call function to save bmp.
Second try is to change CView* to CWnd* and try again.
Second try is to change CView* to CWnd* and try again.
I mean that argument You pass to my function is pointer to window (CWnd*) not CView*.
Hm
maybe i'm missing something here,
first i tryied this one:
CMyView::SaveAsImage()
{
CFile file(strFileName.GetBuffer (0),
CFile::modeCreate|CFile::m odeWrite);
CDC* pdc = GetDC();
CDIBitmap DIBitmap;
// DIBitmap.Draw(*GetDC(), rect); ??
// must be
CBitmap bmp;
CCD dcMem;
dcMem.CreateCompatibleDC(p dc);
bmp.CreateCompatibleBitmap (pdc, rect);
CBitmap* bmOld = dcMem.SelectObject(&bmp);
Draw(&dcMem,...);
dcMem.SelectObject(bmOld);
DIBitmap.AssignDDP((HBITMA P)bmp);
ASSERT(DIBitmap.Save(file) );
}
maybe i'm missing something here,
first i tryied this one:
CMyView::SaveAsImage()
{
CFile file(strFileName.GetBuffer
CFile::modeCreate|CFile::m
CDC* pdc = GetDC();
CDIBitmap DIBitmap;
// DIBitmap.Draw(*GetDC(), rect); ??
// must be
CBitmap bmp;
CCD dcMem;
dcMem.CreateCompatibleDC(p
bmp.CreateCompatibleBitmap
CBitmap* bmOld = dcMem.SelectObject(&bmp);
Draw(&dcMem,...);
dcMem.SelectObject(bmOld);
DIBitmap.AssignDDP((HBITMA
ASSERT(DIBitmap.Save(file)
}
sedgwick, did you check my comments?
ASKER
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()?)
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()?)
ASKER
jkr: sorry not WriteToFile() but:
WriteDIB( szFile, hDIB ) and also some other functions which seems to be missing in this article.
WriteDIB( szFile, hDIB ) and also some other functions which seems to be missing in this article.
ASKER
MadYugoslav: the view is visible in that point.
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).
change CView* into CWnd*
When You call function pass as argument parent window of CView* window (possibly CFrameWnd* if it is Doc application).
ASKER
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*)A fxGetApp() ;
HBITMAP hBitmap = pApp->GetViewBitmap(GetPar ent(), rect.TopLeft().x, rect.TopLeft().y,
rect.Width(), rect.Height());
CFile file(strFileName.GetBuffer (0), CFile::modeCreate|CFile::m odeWrite);
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
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*)A
HBITMAP hBitmap = pApp->GetViewBitmap(GetPar
rect.Width(), rect.Height());
CFile file(strFileName.GetBuffer
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
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
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
oops
what a service :-)
what a service :-)
ASKER
migel:
i post a question for your pts, dont worry mate.
just leave a comment...
cheers
i post a question for your pts, dont worry mate.
just leave a comment...
cheers
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)