//
#include "stdafx.h"
#include <Windows.h>
int APIENTRY _tWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow)
{
HDC hDC,hMemDC;
int x,y;
HBITMAP hbmp,holdbmp;
DWORD err;
BOOL b;
//获取屏幕DC
hDC=::GetDC(NULL);
err=::GetLastError();
//创建一个内存DC
hMemDC=::CreateCompatibleDC(hDC);
err=::GetLastError();
//获取屏幕大小
x=::GetDeviceCaps(hDC,HORZRES);
y=::GetDeviceCaps(hDC,VERTRES);
//x = ::GetSystemMetrics(SM_CXSCREEN);
//y = ::GetSystemMetrics(SM_CYSCREEN);
//创建一个和屏幕DC相同的位图
hbmp = ::CreateCompatibleBitmap(hDC,x,y);
err=::GetLastError();
//把位图选到内存DC中
holdbmp=(HBITMAP)::SelectObject(hMemDC,hbmp);
//把屏幕DC拷贝到内存DC中
b=BitBlt(hMemDC,0,0,x,y,hDC,x,y,SRCCOPY);
//得到位图句柄
hbmp=(HBITMAP)::SelectObject(hMemDC,holdbmp);
//计算每个像数所占字节数
int ibits;
WORD bitcount;
ibits=GetDeviceCaps(hDC,BITSPIXEL)*GetDeviceCaps(hDC,PLANES);
if (ibits <= 1)
bitcount = 1;
else if (ibits <= 4)
bitcount = 4;
else if (ibits <= 8)
bitcount = 8;
else if (ibits <= 16)
bitcount = 16;
else if (ibits <= 24)
bitcount = 24;
else
bitcount = 32;
DWORD dwtsbsize=0,dwwritten;//调色板
//计算调色板大小
if (bitcount <= 8)
dwtsbsize = (1 << bitcount) * sizeof(RGBQUAD);
BITMAP bmp; //位图属性结构
BITMAPFILEHEADER bmfhdr; //位图文件头结构
BITMAPINFOHEADER bi; //位图信息头结构
LPBITMAPINFOHEADER lpbi; //指向位图信息头结构
GetObject(hbmp,sizeof(bmp),(LPVOID)&bmp);
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = bmp.bmWidth;
bi.biHeight= bmp.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = bitcount;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
//位图大小
DWORD dwbitsize;
dwbitsize = ((bmp.bmWidth*bitcount+31)/32)*4*bmp.bmHeight;
//为位图分配内存
HANDLE fh,hdib,hpal,holdpal=NULL;
hdib=VirtualAlloc(NULL,dwbitsize+dwtsbsize+sizeof(BITMAPINFOHEADER),MEM_COMMIT,PAGE_READWRITE);
lpbi=(LPBITMAPINFOHEADER)hdib;
*lpbi=bi;
// 处理调色板
hpal=GetStockObject(DEFAULT_PALETTE);
if (hpal)
{
holdpal = SelectPalette(hDC, (HPALETTE)hpal, false);
RealizePalette(hDC);
}
// 获取该调色板下新的像素值
GetDIBits(hDC, hbmp, 0, (UINT) bmp.bmHeight,(LPSTR)lpbi +
sizeof(BITMAPINFOHEADER)+dwtsbsize,(BITMAPINFO*)lpbi, DIB_RGB_COLORS);
//恢复调色板
if (holdpal)
{
SelectPalette(hDC, (HPALETTE)holdpal, true);
RealizePalette(hDC);
}
//创建位图文件
fh = CreateFile("C:\\1.bmp", GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL|
FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if (fh == INVALID_HANDLE_VALUE)
return 0;
// 设置位图文件头
bmfhdr.bfType=0x4d42; //"bm"
//位图大小
DWORD dwbmpsize=sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)+
dwtsbsize + dwbitsize;
bmfhdr.bfSize=dwbmpsize;
bmfhdr.bfReserved1 = 0;
bmfhdr.bfReserved2 = 0;
bmfhdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) +
(DWORD)sizeof(BITMAPINFOHEADER)+ dwtsbsize;
// 写入位图文件头
WriteFile(fh, (LPSTR)&bmfhdr, sizeof(BITMAPFILEHEADER), &dwwritten, NULL);
// 写入位图文件其余内容
WriteFile(fh, (LPSTR)lpbi, dwbitsize, &dwwritten, NULL);
//清除
VirtualFree(hdib,dwbitsize+dwtsbsize+sizeof(BITMAPINFOHEADER),MEM_DECOMMIT);
CloseHandle(fh);
MSG msg;
// 主消息循环:
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
//问题:
为什么我保存的图象 是黑屏啊。。。。 没想通
另外 怎么才能保存成 jpeg格式呢? 现在我保存一张bmp的图 是3M 太大了
如果 我想保存成录象 又该怎么办呢? 现在最主要的是 保存的图象不是黑屏
请各位大虾指点哦。。。。。。
16 个解决方案
#1
holdbmp=(HBITMAP)::SelectObject(hMemDC,hbmp);
//把屏幕DC拷贝到内存DC中
b=BitBlt(hMemDC,0,0,x,y,hDC,x,y,SRCCOPY);
//得到位图句柄
hbmp=(HBITMAP)::SelectObject(hMemDC,holdbmp);
// 我看了一下 这里会不会有什么问题 我也想不出来
麻烦各位大虾指点一下啦。。。。
//把屏幕DC拷贝到内存DC中
b=BitBlt(hMemDC,0,0,x,y,hDC,x,y,SRCCOPY);
//得到位图句柄
hbmp=(HBITMAP)::SelectObject(hMemDC,holdbmp);
// 我看了一下 这里会不会有什么问题 我也想不出来
麻烦各位大虾指点一下啦。。。。
#2
在头文件添加
将
改为
保存m_pBitmap即可!
CBitmap * m_pBitmap; //背景位图
将
holdbmp=(HBITMAP)::SelectObject(hMemDC,hbmp);
//把屏幕DC拷贝到内存DC中
b=BitBlt(hMemDC,0,0,x,y,hDC,x,y,SRCCOPY);
//得到位图句柄
hbmp=(HBITMAP)::SelectObject(hMemDC,holdbmp);
改为
//创建军兼容DC,当bSave为中时把开始保存的全屏位图,按截取矩形大小保存
CDC dcCompatible;
dcCompatible.CreateCompatibleDC(CDC::FromHandle(hMemDC));
dcCompatible.SelectObject(m_pBitmap);
b=BitBlt(hMemDC, 0, 0, x, y,dcCompatible, x, y, SRCCOPY);
保存m_pBitmap即可!
#3
我没用MFC类库耶。。。。 用CDC的话 就要加 MFC类的头文件啦 程序体积就大啦。。。。
我想用API实现
我想用API实现
#4
各位帅歌美女 帮我顶顶贴吧。。。。 别让它沉啦。。。。。。。。
#5
帮顶.
#6
谢谢 兄弟 不过还是希望有高手解决 这样顶也不是办法。。。。。。。。
#7
bi.biSizeImage = 0;
这个字段没设置。
这个字段没设置。
#8
http://www.handytech.cn/main/ArticleShow_12_2.htm 自己写bmp图的格式很麻烦,用这个方法吧。
http://topic.csdn.net/t/20030517/19/1798130.html 4楼和7楼。
http://topic.csdn.net/t/20050120/10/3739972.html
http://topic.csdn.net/t/20000529/20/10122.html 这两个也可以参考一下。
http://topic.csdn.net/t/20030517/19/1798130.html 4楼和7楼。
http://topic.csdn.net/t/20050120/10/3739972.html
http://topic.csdn.net/t/20000529/20/10122.html 这两个也可以参考一下。
#9
// 写入位图文件其余内容
WriteFile(fh, (LPSTR)lpbi, dwbitsize, &dwwritten, NULL);
=======================================================
dwbitsize没有包含信息头的大小,应该为:
WriteFile(fh, (LPSTR)lpbi, dwbmpsize-sizeof(BITMAPFILEHEADER), &dwwritten, NULL);
或
WriteFile(fh,(LPSTR)lpbi,sizeof(BITMAPINFOHEADER)+dwtsbsize+dwbitsize,&dwwritten,NULL);
WriteFile(fh, (LPSTR)lpbi, dwbitsize, &dwwritten, NULL);
=======================================================
dwbitsize没有包含信息头的大小,应该为:
WriteFile(fh, (LPSTR)lpbi, dwbmpsize-sizeof(BITMAPFILEHEADER), &dwwritten, NULL);
或
WriteFile(fh,(LPSTR)lpbi,sizeof(BITMAPINFOHEADER)+dwtsbsize+dwbitsize,&dwwritten,NULL);
#10
现在的问题是
GetDIBits(hDC, hbmp, 0, (UINT) bmp.bmHeight,(LPSTR)lpbi +
sizeof(BITMAPINFOHEADER)+dwtsbsize,(BITMAPINFO*)lpbi, DIB_RGB_COLORS);
得到的数据都是0.
GetDIBits(hDC, hbmp, 0, (UINT) bmp.bmHeight,(LPSTR)lpbi +
sizeof(BITMAPINFOHEADER)+dwtsbsize,(BITMAPINFO*)lpbi, DIB_RGB_COLORS);
得到的数据都是0.
#11
//把屏幕DC拷贝到内存DC中
b=BitBlt(hMemDC,0,0,x,y,hDC,x,y,SRCCOPY);
=================================================
问题在这。
BitBlt第7,8两个参数设错了。改为:b=BitBlt(hMemDC,0,0,x,y,hDC,0,0,SRCCOPY);就正确了。
BitBlt原型:
BOOL BitBlt(HDC hdcDest,int nXDest,int nYDest,int nWidth,int nHeight,HDC hdcSrc,int nXSrc,int nYSrc,DWORD dwRop);
//int nXSrc,int nYSrc是源起始坐标。
b=BitBlt(hMemDC,0,0,x,y,hDC,x,y,SRCCOPY);
=================================================
问题在这。
BitBlt第7,8两个参数设错了。改为:b=BitBlt(hMemDC,0,0,x,y,hDC,0,0,SRCCOPY);就正确了。
BitBlt原型:
BOOL BitBlt(HDC hdcDest,int nXDest,int nYDest,int nWidth,int nHeight,HDC hdcSrc,int nXSrc,int nYSrc,DWORD dwRop);
//int nXSrc,int nYSrc是源起始坐标。
#12
帮顶起
#13
谢谢
#14
谢谢 dongpy 你照你说的 改了 就对了 非常感谢
另外 我还想存成jpeg格式 bmp太大了 有没有思路和方法呢? 还请各位帮助
另外 我还想存成jpeg格式 bmp太大了 有没有思路和方法呢? 还请各位帮助
#15
MARK
#16
去sourceforge.net上找个jpeg开源库。
#1
holdbmp=(HBITMAP)::SelectObject(hMemDC,hbmp);
//把屏幕DC拷贝到内存DC中
b=BitBlt(hMemDC,0,0,x,y,hDC,x,y,SRCCOPY);
//得到位图句柄
hbmp=(HBITMAP)::SelectObject(hMemDC,holdbmp);
// 我看了一下 这里会不会有什么问题 我也想不出来
麻烦各位大虾指点一下啦。。。。
//把屏幕DC拷贝到内存DC中
b=BitBlt(hMemDC,0,0,x,y,hDC,x,y,SRCCOPY);
//得到位图句柄
hbmp=(HBITMAP)::SelectObject(hMemDC,holdbmp);
// 我看了一下 这里会不会有什么问题 我也想不出来
麻烦各位大虾指点一下啦。。。。
#2
在头文件添加
将
改为
保存m_pBitmap即可!
CBitmap * m_pBitmap; //背景位图
将
holdbmp=(HBITMAP)::SelectObject(hMemDC,hbmp);
//把屏幕DC拷贝到内存DC中
b=BitBlt(hMemDC,0,0,x,y,hDC,x,y,SRCCOPY);
//得到位图句柄
hbmp=(HBITMAP)::SelectObject(hMemDC,holdbmp);
改为
//创建军兼容DC,当bSave为中时把开始保存的全屏位图,按截取矩形大小保存
CDC dcCompatible;
dcCompatible.CreateCompatibleDC(CDC::FromHandle(hMemDC));
dcCompatible.SelectObject(m_pBitmap);
b=BitBlt(hMemDC, 0, 0, x, y,dcCompatible, x, y, SRCCOPY);
保存m_pBitmap即可!
#3
我没用MFC类库耶。。。。 用CDC的话 就要加 MFC类的头文件啦 程序体积就大啦。。。。
我想用API实现
我想用API实现
#4
各位帅歌美女 帮我顶顶贴吧。。。。 别让它沉啦。。。。。。。。
#5
帮顶.
#6
谢谢 兄弟 不过还是希望有高手解决 这样顶也不是办法。。。。。。。。
#7
bi.biSizeImage = 0;
这个字段没设置。
这个字段没设置。
#8
http://www.handytech.cn/main/ArticleShow_12_2.htm 自己写bmp图的格式很麻烦,用这个方法吧。
http://topic.csdn.net/t/20030517/19/1798130.html 4楼和7楼。
http://topic.csdn.net/t/20050120/10/3739972.html
http://topic.csdn.net/t/20000529/20/10122.html 这两个也可以参考一下。
http://topic.csdn.net/t/20030517/19/1798130.html 4楼和7楼。
http://topic.csdn.net/t/20050120/10/3739972.html
http://topic.csdn.net/t/20000529/20/10122.html 这两个也可以参考一下。
#9
// 写入位图文件其余内容
WriteFile(fh, (LPSTR)lpbi, dwbitsize, &dwwritten, NULL);
=======================================================
dwbitsize没有包含信息头的大小,应该为:
WriteFile(fh, (LPSTR)lpbi, dwbmpsize-sizeof(BITMAPFILEHEADER), &dwwritten, NULL);
或
WriteFile(fh,(LPSTR)lpbi,sizeof(BITMAPINFOHEADER)+dwtsbsize+dwbitsize,&dwwritten,NULL);
WriteFile(fh, (LPSTR)lpbi, dwbitsize, &dwwritten, NULL);
=======================================================
dwbitsize没有包含信息头的大小,应该为:
WriteFile(fh, (LPSTR)lpbi, dwbmpsize-sizeof(BITMAPFILEHEADER), &dwwritten, NULL);
或
WriteFile(fh,(LPSTR)lpbi,sizeof(BITMAPINFOHEADER)+dwtsbsize+dwbitsize,&dwwritten,NULL);
#10
现在的问题是
GetDIBits(hDC, hbmp, 0, (UINT) bmp.bmHeight,(LPSTR)lpbi +
sizeof(BITMAPINFOHEADER)+dwtsbsize,(BITMAPINFO*)lpbi, DIB_RGB_COLORS);
得到的数据都是0.
GetDIBits(hDC, hbmp, 0, (UINT) bmp.bmHeight,(LPSTR)lpbi +
sizeof(BITMAPINFOHEADER)+dwtsbsize,(BITMAPINFO*)lpbi, DIB_RGB_COLORS);
得到的数据都是0.
#11
//把屏幕DC拷贝到内存DC中
b=BitBlt(hMemDC,0,0,x,y,hDC,x,y,SRCCOPY);
=================================================
问题在这。
BitBlt第7,8两个参数设错了。改为:b=BitBlt(hMemDC,0,0,x,y,hDC,0,0,SRCCOPY);就正确了。
BitBlt原型:
BOOL BitBlt(HDC hdcDest,int nXDest,int nYDest,int nWidth,int nHeight,HDC hdcSrc,int nXSrc,int nYSrc,DWORD dwRop);
//int nXSrc,int nYSrc是源起始坐标。
b=BitBlt(hMemDC,0,0,x,y,hDC,x,y,SRCCOPY);
=================================================
问题在这。
BitBlt第7,8两个参数设错了。改为:b=BitBlt(hMemDC,0,0,x,y,hDC,0,0,SRCCOPY);就正确了。
BitBlt原型:
BOOL BitBlt(HDC hdcDest,int nXDest,int nYDest,int nWidth,int nHeight,HDC hdcSrc,int nXSrc,int nYSrc,DWORD dwRop);
//int nXSrc,int nYSrc是源起始坐标。
#12
帮顶起
#13
谢谢
#14
谢谢 dongpy 你照你说的 改了 就对了 非常感谢
另外 我还想存成jpeg格式 bmp太大了 有没有思路和方法呢? 还请各位帮助
另外 我还想存成jpeg格式 bmp太大了 有没有思路和方法呢? 还请各位帮助
#15
MARK
#16
去sourceforge.net上找个jpeg开源库。