如何将选中的一块区域保存成bmp?

AttaBoy 2001-10-28 05:51:23
我像写一个截图的程序。
...全文
166 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
kingzai 2001-11-11
  • 打赏
  • 举报
回复
我还以为不要呢:
int CRemoteC::SaveBitmapToFile(HBITMAP hBitmap, LPSTR lpFileName)
{
//我们也可以把屏幕内容以位图格式存到磁盘文件上.
//lpFileName 为位图文件名
HDC hDC; //设备描述表
int iBits; //当前显示分辨率下每个像素所占字节数
WORD wBitCount; //位图中每个像素所占字节数
//定义调色板大小, 位图中像素字节大小,位图文件大小,写入文件字节数
DWORD dwPaletteSize=0,
dwBmBitsSize,
dwDIBSize, dwWritten;
BITMAP Bitmap; //位图属性结构
BITMAPFILEHEADER bmfHdr; //位图文件头结构
BITMAPINFOHEADER bi; //位图信息头结构
LPBITMAPINFOHEADER lpbi; //指向位图信息头结构
HANDLE fh, hDib, hPal,hOldPal=NULL;
//定义文件,分配内存句柄,调色板句柄
//计算位图文件每个像素所占字节数
hDC = CreateDC("DISPLAY",NULL,NULL,NULL);
iBits = GetDeviceCaps(hDC, BITSPIXEL)*GetDeviceCaps(hDC, PLANES);
DeleteDC(hDC);
if (iBits <= 1)
wBitCount = 1;
else if (iBits <= 4)
wBitCount = 4;
else if (iBits <= 8)
wBitCount = 8;
else if (iBits <= 32)
wBitCount = 24;
//计算调色板大小
if (wBitCount <= 8)
dwPaletteSize = (1 << wBitCount) *
sizeof(RGBQUAD);
//设置位图信息头结构
GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = Bitmap.bmWidth;
bi.biHeight = Bitmap.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = wBitCount;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;

dwBmBitsSize = ((Bitmap.bmWidth*wBitCount+31)/32)* 4*Bitmap.bmHeight ;
hDib = GlobalAlloc(GHND,dwBmBitsSize+dwPaletteSize+sizeof(BITMAPINFOHEADER));//为位图内容分配内存
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
*lpbi = bi;
hPal=(HPALETTE)::GetStockObject(DEFAULT_PALETTE);// 处理调色板
if (hPal)
{
hDC = GetDC(NULL);
hOldPal = SelectPalette(hDC,(HPALETTE)hPal, FALSE);
RealizePalette(hDC);
}
// 获取该调色板下新的像素值
GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight,
(LPSTR)lpbi + sizeof(BITMAPINFOHEADER)
+dwPaletteSize,
(BITMAPINFO *)
lpbi, DIB_RGB_COLORS);
//恢复调色板
if (hOldPal)
{
SelectPalette(hDC,(HPALETTE) hOldPal, TRUE);
RealizePalette(hDC);
ReleaseDC(NULL, hDC);
}
//创建位图文件
fh = CreateFile(lpFileName, GENERIC_WRITE,0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if (fh == INVALID_HANDLE_VALUE)
return FALSE;
// 设置位图文件头
bmfHdr.bfType = 0x4D42; // "BM"
dwDIBSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)
+ dwPaletteSize + dwBmBitsSize;
bmfHdr.bfSize = dwDIBSize;
bmfHdr.bfReserved1 = 0;
bmfHdr.bfReserved2 = 0;
bmfHdr.bfOffBits = (DWORD)sizeof
(BITMAPFILEHEADER)
+ (DWORD)sizeof(BITMAPINFOHEADER)
+ dwPaletteSize;
// 写入位图文件头
WriteFile(fh, (LPSTR)&bmfHdr, sizeof
(BITMAPFILEHEADER), &dwWritten, NULL);
// 写入位图文件其余内容
WriteFile(fh, (LPSTR)lpbi, dwDIBSize,
&dwWritten, NULL);
//清除
GlobalUnlock(hDib);
GlobalFree(hDib);
CloseHandle(fh);
return TRUE;
}
mousubin 2001-11-11
  • 打赏
  • 举报
回复
SaveBitmapToFile?
kingzai 2001-11-09
  • 打赏
  • 举报
回复
回答第三遍:
LPTSTR CRemoteC::CopyScreenToBitmap(LPRECT lpRect)
{

HDC hScrDC, hMemDC; // 屏幕和内存设备描述表
HBITMAP hBitmap,hOldBitmap; // 位图句柄
int nX, nY, nX2, nY2; // 选定区域坐标
int nWidth, nHeight; // 位图宽度和高度
int xScrn, yScrn; // 屏幕分辨率


// 确保选定区域不为空矩形
if (IsRectEmpty(lpRect)) return NULL;

//为屏幕创建设备描述表
hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);

//为屏幕设备描述表创建兼容的内存设备描述表
hMemDC = CreateCompatibleDC(hScrDC);

// 获得选定区域坐标
nX = lpRect->left;
nY = lpRect->top;
nX2 = lpRect->right;
nY2 = lpRect->bottom;

// 获得屏幕分辨率
xScrn = GetDeviceCaps(hScrDC, HORZRES);
yScrn = GetDeviceCaps(hScrDC, VERTRES);

//确保选定区域是可见的

if (nX < 0) nX = 0;
if (nY < 0) nY = 0;
if (nX2 > xScrn) nX2 = xScrn;
if (nY2 > yScrn) nY2 = yScrn;
nWidth = nX2 - nX;
nHeight = nY2 - nY;

// 创建一个与屏幕设备描述表兼容的位图
int *temp=new int(m_szResolution.Find("*"));
char *pWidth=new char[10];
char *pHeight=new char[10];
strcpy(pWidth,m_szResolution.Mid(0,*temp));
strcpy(pHeight,m_szResolution.Mid(*temp+1));
delete temp;
int nDestResWidth=atoi(pWidth);
int nDestResHeight=atoi(pHeight);
delete pWidth;
delete pHeight;
hBitmap = CreateCompatibleBitmap(hScrDC, nDestResWidth, nDestResHeight);

// 把新位图选到内存设备描述表中
hOldBitmap=(HBITMAP)::SelectObject(hMemDC, hBitmap);

// 把屏幕设备描述表拷贝到内存设备描述表中
StretchBlt(hMemDC, 0, 0, nDestResWidth, nDestResHeight,hScrDC, nX, nY,nWidth,nHeight,SRCCOPY);
//得到屏幕位图的句柄
hBitmap =(HBITMAP) ::SelectObject(hMemDC, hOldBitmap);
//清除
DeleteDC(hScrDC);
DeleteDC(hMemDC);
char tmppath[MAX_PATH];
char *tmpname=new char[MAX_PATH];
GetTempPath(MAX_PATH,tmppath);
GetTempFileName(tmppath,"AnyServer",0,tmpname);//获得一个唯一的临时文件名
// SaveBitmapToFile(hBitmap,tmpname);
return tmpname;
}
mousubin 2001-11-09
  • 打赏
  • 举报
回复
gz.
AttaBoy 2001-11-09
  • 打赏
  • 举报
回复
靠,,,,疯了

都这么多天了。
AttaBoy 2001-10-28
  • 打赏
  • 举报
回复
怎么处理,有没有例子
lvxg820 2001-10-28
  • 打赏
  • 举报
回复
可以将其送入剪贴板,然后在处理
一个非常著名的优秀屏幕、文本和视频捕获、编辑与转换软件。可以捕获Windows屏幕、DOS屏幕;RM电影、游戏画面;菜单、窗口、客户区窗口、最后一个激活的窗口或用鼠标定义的区域。图象可保存BMP、PCX、TIF、GIF、PNG或JPEG格式,也可以存为视频动画。使用JPEG可以指定所需的压缩级(从1%到99%)。可以选择是否包括光标,添加水印。另外还具有自动缩放,颜色减少,单色转换,抖动,以及转换为灰度级。 可以捕获Windows屏幕、DOS屏幕;RM电影、游戏画面;菜单、窗口、客户区窗口、最后一个激活的窗口或用鼠标定义的区域。图象可被存为BMP、PCX、TIF、GIF或JPEG格式,也可以存为系列动画。 使用JPEG可以指定所需的压缩级(从1%到99%)。可以选择是否包括光标,添加水印。 另外还具有自动缩放,颜色减少,单色转换,抖动,以及转换为灰度级。 此外,保存屏幕捕获的图象前,可以用其自带的编辑器编辑;也可以选择自动将其送至SnagIt打印机或Windows剪贴板中,也可以直接用E-mail发送。 SnagIt具有将显示在Windows桌面上的文本块转换为机器可读文本的独特能力,这里甚至无需CUT和PASTE。 程序支持DDE,所以其他程序可以控制和自动捕获屏幕。 新版还能嵌入Word、powerpoint和ie浏览器中。 利用SnagIt的捕捉界面,能够捕捉您Windows PC上的图片、文本和打印输出,然后通过内嵌编辑器,可以对捕捉结果进行改进,SnagIt Screen Capture增强了您PrintScreen键的功能。 Snagit是一个极其优秀的捕捉图形的软件,和其他捕捉屏幕软件相比 它有以下几个特点: 1、捕捉的种类多:不仅可以捕捉静止的图像,而且可以获得动态的图像和声音,另外还可以在选中的范围内只获取文本。 2、捕捉范围极其灵活:可以选择整个屏幕,某个静止或活动窗口,也可以自己随意选择捕捉内容。 3、输出的类型多:可以以文件的形式输出,也可以把捕捉的内容直接发e-mail给朋友,另外可以编辑册。 4、具备简单的图形处理功能:利用它的过滤功能可以将图形的颜色进行简单处理,也可对图形进行放大或缩小。 目前SnagIt最新版本为SnagIt 11。 更新日志: Snagit截图工具v11.3.0.107 : *新增分享到Google Drive,并从Google Drive导入。 *新增TechSmith Fuse集,从您的移动设备的SnagIt。 *增加了自动更新SnagIt的能力。 *Windows 8.1支持 *新增能力旋转stamps。 *增加了文字填充为标注。 *增加了尾巴锁的标注。 *增加了改进捕捉十字星。 *修复了各种错误。 v11.2.0 ( 2013年3月19日) : *重新设计的一键式。 *重新设计了SnagIt的消息中心。 *增加了在YouTube的输出进行双因素身份验证的支持。 *增加了额外的日语文件名组件自动文件命名。 *重新添加,通过批量转换缩放多个图像的支持。 *改进的滚动在Microsoft outlook中的电子邮件捕获的性能。 *修正了SnagIt的编辑器会上传视频到YouTube之后崩溃。 *修正了SnagIt的无法备份和恢复库大于4 GB 。 *修正引起的分组,并在画布上几个解组矢量对象崩溃的bug 。

16,550

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Creator Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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