How Do You Create A Bitmap from a image in a window?
Gary Krone -- gkrone@inconsys.com
Friday, March 07, 1997
Environment: VC++ 4.2-flat, WinNT 4.0
This has got to be simple!
What I want to know is how you can take an image drawn on a window and make
a CBitmap Object out of it ( Or similar way to take a 'snapshot' of the
screen image for later use ). The catch is the image doesn't exist previous
to being drawn on the window surface. If anyone has some sample code on how
to do this it would be greatly appreciated.
Gary Krone
gkrone@inconsys.com
gkrone@execpc.com
Norman C. Byers -- nbyers@intxxnet.com
Sunday, March 09, 1997
[Mini-digest: 9 responses]
Read the documentation for CreateDC. You use a driver name of "DISPLAY".
Once you have a DC to the screen, its fairly simple to find your images
location, and do the appropriate create compatible DC and compatible
bitmaps, do bitblts and all that neat junk. You can get this Windows 101
stuff from the earliest Petzold books.
----------
From: Gary Krone[SMTP:gkrone@inconsys.com]
Sent: Friday, March 07, 1997 9:03 AM
To: mfc-l@netcom.com
Subject: How Do You Create A Bitmap from a image in a window?
Environment: VC++ 4.2-flat, WinNT 4.0
This has got to be simple!
What I want to know is how you can take an image drawn on a window and make
a CBitmap Object out of it ( Or similar way to take a 'snapshot' of the
screen image for later use ). The catch is the image doesn't exist
previous
to being drawn on the window surface. If anyone has some sample code on
how
to do this it would be greatly appreciated.
Gary Krone
gkrone@inconsys.com
gkrone@execpc.com
-----From: Ben Burnett
Gary Krone wrote:
Environment: VC++ 4.2-flat, WinNT 4.0
This has got to be simple!
What I want to know is how you can take an image drawn on a window
and make
a CBitmap Object out of it ( Or similar way to take a 'snapshot' of
the
screen image for later use ). The catch is the image doesn't exist
previous
to being drawn on the window surface. If anyone has some sample
code on how
to do this it would be greatly appreciated.
Gary Krone
gkrone@inconsys.com
gkrone@execpc.com
If your still looking for the sample code just e-mail me and i'll send
you an attachment
-----From: Sreekant Sreedharan
Hi Gary,
I don't remember how I did it, but I can give an idea.
To begin with, you should create a bitmap of the properties(
width,height,bits-per-pixel etc.). Select this bitmap into the window
device context, this is important. Then you can use
CDC::GetCurrentBitmap to retrieve the CBitmap* anytime to take your
'snapshot'.
Please let me know if you have a problem.
Gary Krone wrote:
>
> Environment: VC++ 4.2-flat, WinNT 4.0
>
> This has got to be simple!
>
> What I want to know is how you can take an image drawn on a window and make
> a CBitmap Object out of it ( Or similar way to take a 'snapshot' of the
> screen image for later use ). The catch is the image doesn't exist previous
> to being drawn on the window surface. If anyone has some sample code on how
> to do this it would be greatly appreciated.
> Gary Krone
> gkrone@inconsys.com
> gkrone@execpc.com
--
---- From "Sreekant Sreedharan"
-----From: igor_firkusny@abtassoc.com
So, you have done some drawing to a Window, and you want to cache the
rendered graphics to a memory bitmap? I don't have sample code on
hand, but the general approach is the following:
Create a memory DC compatible to your window's DC using
CreateCompatibleDC. This DC will initially have a dummy, 1-bit bitmap
tied to it, which is pretty useless, so you need to create a bitmap to
associate with it using CreateCompatibleBitmap(), specifying the
source window's DC. Then select this new bitmap into the memory DC
with SelectObject(), and then bit-transfer (BitBlt() etc) the bitmap
in the source to the destination DC.
Remember to destroy both the bitmap and the memory DC you created
after you're done, or it will leak.
I have done this and it works. However, this message was written from
memory, so I apologize if I misstated something.
--if
______________________________ Reply Separator _________________________________
Subject: How Do You Create A Bitmap from a image in a window?
Author: uunet!netcom.com!mfc-l at UUCPmail
Date: 3/9/97 9:23 AM
Environment: VC++ 4.2-flat, WinNT 4.0
This has got to be simple!
What I want to know is how you can take an image drawn on a window and make
a CBitmap Object out of it ( Or similar way to take a 'snapshot' of the
screen image for later use ). The catch is the image doesn't exist previous
to being drawn on the window surface. If anyone has some sample code on how
to do this it would be greatly appreciated.
Gary Krone
gkrone@inconsys.com
gkrone@execpc.com
-----From: Joao Marcos Melo Mendes
Ahoy, :)
On Fri, 7 Mar 1997, Gary Krone wrote:
Environment: VC++ 4.2-flat, WinNT 4.0
Actually, I'm using 4.2b now, but I upgraded only recently. I can tell
you for sure weather this code predates the upgrade or not, but more
likely than not it did, so it should work for you.
> This has got to be simple!
Well, yes and no. :) What I wanted to do was to save a CBitmap taken from
a window into a BMP file, so you'll find the code is a little convoluted,
but I'm sure you'll be able to strip up the stuff you don't need.
> What I want to know is how you can take an image drawn on a window and make
> a CBitmap Object out of it ( Or similar way to take a 'snapshot' of the
The root of the matter is simple: get the window DC, create a compatible
DC, create a compatible bitmap, select the bitmap into the compatible DC,
then BitBlt between the two.
Try this:
long CMyWnd::SaveFile(CString strFName)
{
CFile f;
CBitmap bmp, * bmpOld;
CDC dcTmp, * pdc;
CRect rct;
BITMAPINFO * lp;
BITMAPFILEHEADER bfh;
long l, lngSize;
GetClientRect(rct);
if ( (pdc=GetDC()) == NULL )
return (long)FALSE;
if ( bmp.CreateBitmap(rct.Width(),rct.Height(),pdc->GetDeviceCaps(PLANES),pdc->GetDeviceCaps(BITSPIXEL),NULL) == 0 ) {
ReleaseDC(pdc);
return (long)FALSE; }
HBITMAP hbmp=(HBITMAP)bmp.GetSafeHandle();
if ( dcTmp.CreateCompatibleDC(pdc) == 0 ) {
ReleaseDC(pdc);
return (long)FALSE; }
HDC hdc=dcTmp.GetSafeHdc();
if ( (bmpOld=dcTmp.SelectObject(&bmp)) == NULL ) {
ReleaseDC(pdc);
return (long)FALSE; }
if ( dcTmp.BitBlt(0,0,rct.Width(),rct.Height(),pdc,0,0,SRCCOPY) == 0 ) {
dcTmp.SelectObject(bmpOld);
ReleaseDC(pdc);
return (long)FALSE; }
dcTmp.SelectObject(bmpOld);
ReleaseDC(pdc);
long len = sizeof(BITMAPINFOHEADER)+4*rct.Width()*rct.Height();
if ( (lp = (BITMAPINFO *)GlobalAllocPtr(GHND,len)) == NULL ) {
bmp.DeleteObject();
return (long)FALSE; }
lp->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
LPVOID lpv = ((LPBYTE)lp)+sizeof(BITMAPINFOHEADER);
if ( (l=::GetDIBits(hdc,hbmp,0,0,NULL,lp,DIB_RGB_COLORS)) == 0 ) {
GlobalFreePtr((LPVOID)lp);
bmp.DeleteObject();
return (long)FALSE; }
if ( ::GetDIBits(hdc,hbmp,0,l,lpv, lp, DIB_RGB_COLORS) == 0 ) {
GlobalFreePtr((LPVOID)lp);
bmp.DeleteObject();
return (long)FALSE; }
bmp.DeleteObject();
lngSize = ( lp->bmiHeader.biSizeImage != 0 ? lp->bmiHeader.biSizeImage : 4*rct.Width()*rct.Height() );
bfh.bfType = 'M'*256+'B';
bfh.bfSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+lngSize;
bfh.bfReserved1 = 0;
bfh.bfReserved2 = 0;
bfh.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
if ( f.Open(strFName,CFile::modeCreate|CFile::modeWrite) == NULL ) {
GlobalFreePtr((LPVOID)lp);
return (long)FALSE; }
f.Write(&bfh,sizeof(BITMAPFILEHEADER));
f.Write(lp,sizeof(BITMAPINFOHEADER));
f.Write(lpv,lngSize);
f.Close();
GlobalFreePtr((LPVOID)lp);
return (long)TRUE;
}
BTW, unfortunately, I have verified that this code only works when the
screen color depth is 24-bit. Otherwise, I get corrupted BMP files
(though I couldn't tell you the exact nature of the corruption). ( It
should work fine for just extracting CBitmap objects, though.)
Anyway, if anyone could point me in the direction of a way with which to
save the CBitmap object to file regardless of screen color depth, I would
be indebted.
Joao Mendes
MegaMedia, S.A.
"We're fools to make war on our brothers in arms." - Mark Knopfler
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: 2.6.2
mQBNAzKu3TgAAAECAL8+YSEFZ0XrlBMu9t2xDq3rhpWZoscP83VrX5MevAm3UOd6
fOtDKsJxsWugnVMexo50NfBjeWOHz5nA1b9hYx0ABRG0H0pvYW8gTWVuZGVzIDxq
bW1tQG1lZ2FtZWRpYS5wdD4=
=sspP
-----END PGP PUBLIC KEY BLOCK-----
-----From: "Manyam Khaja"
Here is the code I use to capture the screen contents of a window:
int CaptureWindowScreenToBitmap(CWnd* wnd, HBITMAP* bitmap)
{
RECT r;
CClientDC dc(wnd);
HDC hScrDC, hMemDC; // screen DC and memory DC
HBITMAP hBitmap, hOldBitmap; // handles to deice-dependent
bitmaps
wnd->GetClientRect(&r);
hScrDC = dc.GetSafeHdc();
hMemDC = CreateCompatibleDC(hScrDC);
// create a bitmap compatible with the screen DC
hBitmap = CreateCompatibleBitmap(hScrDC, r.right, r.bottom);
// select new bitmap into memory DC
hOldBitmap = (HBITMAP) SelectObject(hMemDC, hBitmap);
// bitblt screen DC to memory DC
BitBlt(hMemDC, 0, 0, r.right, r.bottom, hScrDC, 0, 0, SRCCOPY);
// select old bitmap back into memory DC and get handle to
// bitmap of the screen
*bitmap = (HBITMAP) SelectObject(hMemDC, hOldBitmap);
// clean up
DeleteDC(hScrDC);
DeleteDC(hMemDC);
return 0;
}
incase you need it, here is the code to paste the bitmap back to the
window screen:
int PasteBitmapToWindowScreen(CWnd* wnd, HBITMAP* bitmap)
{
HDC hScrDC, hMemDC; // screen DC and memory DC
CClientDC dc(wnd);
hScrDC = dc.GetSafeHdc();
hMemDC = CreateCompatibleDC(hScrDC);
SelectObject(hMemDC, *bitmap);
RECT r;
wnd->GetClientRect(&r);
BitBlt(hScrDC, 0, 0, r.right, r.bottom, hMemDC, 0, 0, SRCCOPY);
DeleteDC(hScrDC);
DeleteDC(hMemDC);
return 0;
}
Hope that helps,
-Manyam
Gary Krone wrote:
>
> Environment: VC++ 4.2-flat, WinNT 4.0
>
> This has got to be simple!
>
> What I want to know is how you can take an image drawn on a window and make
> a CBitmap Object out of it ( Or similar way to take a 'snapshot' of the
> screen image for later use ). The catch is the image doesn't exist previous
> to being drawn on the window surface. If anyone has some sample code on how
> to do this it would be greatly appreciated.
> Gary Krone
> gkrone@inconsys.com
> gkrone@execpc.com
-----From: Roma
Gary Krone wrote:
>
> Environment: VC++ 4.2-flat, WinNT 4.0
>
> This has got to be simple!
>
> What I want to know is how you can take an image drawn on a window and make
> a CBitmap Object out of it ( Or similar way to take a 'snapshot' of the
> screen image for later use ). The catch is the image doesn't exist previous
> to being drawn on the window surface. If anyone has some sample code on how
> to do this it would be greatly appreciated.
> Gary Krone
> gkrone@inconsys.com
> gkrone@execpc.com
Hi,
here is a code from one my old program. I didn't try it under winNT, it
was written on
MSVC 1.5 on WFW, but I hope there is no difference in this things:
clas CSomeView : public CView
{
...
CBitmap m_Picture;
...
};
void CSomeView::DrawAndStorePicture()
{
CClientDC *pDC = new CClientDC(this);
//Actual drawing to the window
PaintPicture(pDC);
//Now, let's copy just created image into bitmap.
//In WFW this is true - other processes can't overlap our window,
but in Win32 I don't
//know what will happen if your window will be overlapped by other
window at the moment
//between drawing and BitBlt.
CDC MemDC;
MemDC.CreateCompatibleDC(pDC);
CRect ClientRect;
GetClientRect(ClientRect);
m_Picture.DeleteObject();
m_Picture.CreateCompatibleBitmap(pDC, ClientRect.Width(),
ClientRect.Height());
CBitmap* pOldBmp = m_MemDC.SelectObject(&m_Picture);
//This call copy bits from screen to the bitmap, selected into
memory dc.
MemDC.BitBlt(0, 0, ClientRect.Width(), ClientRect.Height(), pDC, 0,
0, SRCCOPY);
MemDC.SelectObject(pOldBmp);
}
HTH,
-Roma
roma@neonet.lv
-----From: Pal_Sukhram/svoa0008@ssb.com
--openmail-part-09a2d75c-00000001
Content-Type: text/plain; charset=US-ASCII; name="RE:"
Become an MFC-L member
| Вернуться в корень Архива
|