当获得了DC的句柄,如何把DC上的区域保存到一个位图文件中?

AnyStayIsJk 2009-05-13 12:53:31
当获得了DC的句柄,如何把DC上的区域保存到一个位图文件中?谢谢
...全文
1082 28 打赏 收藏 转发到动态 举报
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
wj120202 2012-02-23
  • 打赏
  • 举报
回复
学习了!
nokianasty 2010-03-27
  • 打赏
  • 举报
回复
mark
sevenzhy 2009-09-03
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 dby99 的回复:]
我看到有些代码上没有用ReleaseDC(NULL, hMemDC );这一句,会不会产生内存泄露啊?
[/Quote]

没有GetDC()就不需要ReleaseDC(),成对使用.
dby99 2009-05-13
  • 打赏
  • 举报
回复
我看到有些代码上没有用ReleaseDC(NULL, hMemDC );这一句,会不会产生内存泄露啊?
AnyStayIsJk 2009-05-13
  • 打赏
  • 举报
回复
参数个数问题
dby99 2009-05-13
  • 打赏
  • 举报
回复
ReleaseDC(NULL, hMemDC );
报编译错误,error C2660: 'ReleaseDC' : function does not take 2 parameters
请问怎么回事?
AnyStayIsJk 2009-05-13
  • 打赏
  • 举报
回复
我用 CreateFileA创建位图时返回INVALID_HANDLE_VALUE,请问是什么原因呀??谢谢了
AnyStayIsJk 2009-05-13
  • 打赏
  • 举报
回复
那如何获得程序的窗口的句柄呢?我的代码运行于HOOK了的ExtTextOutA函数的内部,若方便请留下QQ,我的291187020,我是做逆向的。。。。。。。
lyserver 2009-05-13
  • 打赏
  • 举报
回复
调用代码:

int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
HDC hDesktopDC=GetDC(NULL);
DC2File(hDesktopDC,"c:\\temp.bmp",0,0,800,500);
ReleaseDC(NULL,hDesktopDC);
MessageBox(NULL,"保存完毕!","",MB_OK);
return 0;
}
lambochan 2009-05-13
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 anystayisjk 的回复:]
编译通过了,可是如何把LPRECT t转换成RECT t后并赋给Save((LPCTSTR)"c:\\jk.bmp",hdc,t);呢?
[/Quote]

Save((LPCTSTR)"c:\\jk.bmp",hdc,*t);

HWND是你的窗口的句柄,而不是DC句柄.
GetWindowRect()需要的是程序窗口句柄吧.
GetClientRect()是客户区窗口句柄.
lyserver 2009-05-13
  • 打赏
  • 举报
回复
#include "stdafx.h"
#include <ocidl.h>
#include <olectl.h>
// ////////////////////////////////////////
// 函数名称:DC2File
// 函数功能:将指定DC中的位图保存为BMP文件
// ////////////////////////////////////////
BOOL DC2File(HDC hDC,LPCSTR szFileName,UINT nLeft=0,UINT nTop=0,UINT nWidth=0,UINT nHeight=0)
{
HDC hMemDC;
BITMAP bmp;
HBITMAP hSrcBmp,hMemBmp,hOldBmp;
BOOL retVal=FALSE;

hSrcBmp=(HBITMAP)GetCurrentObject(hDC,OBJ_BITMAP);
if(hSrcBmp==NULL)return FALSE;

GetObject(hSrcBmp,sizeof(BITMAP),&bmp);
if(nWidth>(UINT)bmp.bmWidth)nWidth=(UINT)bmp.bmWidth;
if(nHeight>(UINT)bmp.bmHeight)nHeight=(UINT)bmp.bmHeight;
if( nWidth<nLeft || nHeight<nTop)return 0;

hMemDC = CreateCompatibleDC(hDC);
hMemBmp = CreateCompatibleBitmap(hDC,(nWidth-nLeft),(nHeight-nTop));
hOldBmp = (HBITMAP)SelectObject(hMemDC,hMemBmp);
BitBlt(hMemDC,nLeft,nTop,(nWidth-nLeft),(nHeight-nTop),hDC,nLeft,nTop,SRCCOPY);

PICTDESC ps;
IPicture* pIPic=NULL;
ps.cbSizeofstruct = sizeof(PICTDESC);
ps.picType = PICTYPE_BITMAP;
ps.bmp.hbitmap = hMemBmp;
ps.bmp.hpal = NULL;
if(OleCreatePictureIndirect(&ps,IID_IPicture,TRUE,(LPVOID*)&pIPic)==ERROR_SUCCESS)
{
LONG lSize = 0;
IStream* pIStm = NULL;
CreateStreamOnHGlobal(NULL,TRUE,&pIStm);
if(pIPic->SaveAsFile(pIStm,TRUE,&lSize) == ERROR_SUCCESS)
{
LARGE_INTEGER li;
li.HighPart = 0;
li.LowPart = 0;
ULARGE_INTEGER uli;
uli.HighPart = 0;
uli.LowPart = 0;
pIStm->Seek(li, STREAM_SEEK_SET, &uli);

char buffer[1024];
HANDLE hFile = CreateFile(szFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_HIDDEN, NULL);
DWORD dwRead = 1,dwWrite=0;
while(dwRead>0)
{
pIStm->Read(buffer, 1024, &dwRead);
if(dwRead > 0)WriteFile(hFile, buffer, dwRead, &dwWrite, NULL);
}
CloseHandle(hFile);
retVal=TRUE;
}
pIPic->Release();
pIStm->Release();
}
DeleteObject(SelectObject(hMemDC,hOldBmp));
DeleteDC(hMemDC);
return retVal;
}
AnyStayIsJk 2009-05-13
  • 打赏
  • 举报
回复
我位图这块比较差,谢谢了,就差这个了,如何把LPRECT t转换成RECT t后并赋给Save((LPCTSTR)"c:\\jk.bmp",hdc,t);呢?谢谢
lambochan 2009-05-13
  • 打赏
  • 举报
回复
倒..
BitBlt( hMemDC, 0, 0, bi.biWidth, bi.biHeight, saveDC, 0, 0, SRCCOPY );
这个又不记得改回:
BitBlt( hMemDC, 0, 0, bi.biWidth, bi.biHeight, saveDC, rc.left, rc.top, SRCCOPY );

-_-"..

good luck~不搞了..哈哈
AnyStayIsJk 2009-05-13
  • 打赏
  • 举报
回复
error C2664: “GetWindowRect”: 不能将参数 1 从“HDC”转换为“HWND”
AnyStayIsJk 2009-05-13
  • 打赏
  • 举报
回复
编译通过了,可是如何把LPRECT t转换成RECT t后并赋给Save((LPCTSTR)"c:\\jk.bmp",hdc,t);呢?
lambochan 2009-05-13
  • 打赏
  • 举报
回复

#define WIDTHBYTES(w,b) ((((w)*(b)+31)/32)*4)
BOOL Save( LPCTSTR lpszFileName, HDC saveDC, RECT rc )
{
BITMAPFILEHEADER bf = { 0 };
BITMAPINFOHEADER bi = { 0 };
HDC hMemDC;
HBITMAP hBitmap;
LPBYTE lpBits;

bi.biSize = sizeof( BITMAPINFOHEADER );
bi.biBitCount = 24; // 保存为true color
bi.biWidth = rc.right - rc.left;
bi.biHeight = rc.bottom - rc.top;
bi.biPlanes = 1;
bi.biCompression = BI_RGB;
bi.biSizeImage = WIDTHBYTES( bi.biWidth, bi.biBitCount ) * bi.biHeight;

HDC hdc = GetDC( NULL );
if( !hdc )
return FALSE;
hBitmap = CreateDIBSection( hdc, ( CONST BITMAPINFO * )&bi, DIB_RGB_COLORS,
( VOID ** )&lpBits, NULL, 0 );
if( !hBitmap ){
ReleaseDC( NULL, hdc );
return FALSE;
}

hMemDC = CreateCompatibleDC( hdc );
HBITMAP hOldBmp = ( HBITMAP )SelectObject( hMemDC, hBitmap );
BitBlt( hMemDC, 0, 0, bi.biWidth, bi.biHeight, saveDC, 0, 0, SRCCOPY );
SelectObject( hMemDC, hOldBmp );
ReleaseDC( NULL, hdc );
DeleteDC( hMemDC );

bf.bfType = 0x4d42;
bf.bfSize = sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER )
+ bi.biSizeImage;
bf.bfOffBits = sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER );

DWORD dwWrite;
HANDLE fh = CreateFile( lpszFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL );
WriteFile( fh, ( LPBYTE )&bf, sizeof( BITMAPFILEHEADER ), &dwWrite, NULL );
WriteFile( fh, ( LPBYTE )&bi, sizeof( BITMAPINFOHEADER ), &dwWrite, NULL );
WriteFile( fh, ( LPBYTE )lpBits, bi.biSizeImage, &dwWrite, NULL );


DeleteObject( hBitmap );
return TRUE;
}


还有没?估计这个没有了.

因为是随手写的.哈哈~
lambochan 2009-05-13
  • 打赏
  • 举报
回复
2: HBITMAP hOldBmp = ( HBITMAP )SelectObject( hMemDC, hBitmap );
1: #define WIDTHBYTES(w,b) ((((w)*(b)+31)/32)*4)
AnyStayIsJk 2009-05-13
  • 打赏
  • 举报
回复
报这两个错误

1>c:\documents and settings\cx\桌面\textusenglish\textusenglish\textusenglish\textusenglish.cpp(25) : error C3861: “WIDTHBYTES”: 找不到标识符
1>c:\documents and settings\cx\桌面\textusenglish\textusenglish\textusenglish\textusenglish.cpp(38) : error C2660: “SelectObject”: 函数不接受 1 个参数
lambochan 2009-05-13
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 anystayisjk 的回复:]
请用SDK的方式,别用MFC,我的整个程序是SDK的。谢谢了
[/Quote]

CFile file( lpszFileName, CFile::modeCreate|CFile::modeWrite );
file.Write( &bf, sizeof( BITMAPFILEHEADER ) );
file.Write( &bi, sizeof( BITMAPINFOHEADER ) );
file.WriteHuge( lpBits, bi.biSizeImage );
把这几句替换成writefile..
DWORD dwWrite;
HANDLE fh = CreateFile( lpszFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL );
WriteFile( fh, ( LPBYTE )&bf, sizeof( BITMAPFILEHEADER ), &dwWrite, NULL );
WriteFile( fh, ( LPBYTE )&bi, sizeof( BITMAPINFOHEADER ), &dwWrite, NULL );
WriteFile( fh, ( LPBYTE )lpBits, bi.biSizeImage, &dwWrite, NULL );

汗...
lambochan 2009-05-13
  • 打赏
  • 举报
回复
晕,应为:
BitBlt( hMemDC, 0, 0, bi.biWidth, bi.biHeight, saveDC, rc.left, rc.top, SRCCOPY );

才对.
加载更多回复(8)

19,469

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧