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 BurnettGary 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 | Вернуться в корень Архива |