截屏 保存为24真彩bmp位图?

Randyqiu 2009-04-01 09:34:38
我保存下来的应该是32位的bmp位图。
我要做的事情是把截屏下来的图片进行处理,处理成256色位图。
我有两个想法:
1.把32位的转换为24位,因为我有把24位转化为8位256色位图的代码。
2.直接把32位转化为256色位图,如果有的话,我要源代码,小弟很急没时间一点点学,谢谢了。。。
3.在截屏保存的时候保存为24位的bmp位图,这个只需要说下哪些地方需要修改
以下是问题3的源代码:
BOOL CreateBitmapInfoStruct(HBITMAP hBmp,PBITMAPINFO& pbmi)
{
BITMAP bmp;
//PBITMAPINFO pbmi;
WORD cClrBits;

// Retrieve the bitmap color format, width, and height.
if (!GetObject(hBmp, sizeof(BITMAP), (LPSTR)&bmp))
return FALSE;

// Convert the color format to a count of bits.
cClrBits = (WORD)(bmp.bmPlanes * bmp.bmBitsPixel);
if (cClrBits == 1)
cClrBits = 1;
else if (cClrBits <= 4)
cClrBits = 4;
else if (cClrBits <= 8)
cClrBits = 8;
else if (cClrBits <= 16)
cClrBits = 16;
else if (cClrBits <= 24)
cClrBits = 24;
else cClrBits = 32;

// Allocate memory for the BITMAPINFO structure. (This structure
// contains a BITMAPINFOHEADER structure and an array of RGBQUAD
// data structures.)

if (cClrBits != 24)
pbmi = (PBITMAPINFO) LocalAlloc(LPTR,
sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * (1<< cClrBits));

// There is no RGBQUAD array for the 24-bit-per-pixel format.

else
pbmi = (PBITMAPINFO) LocalAlloc(LPTR,
sizeof(BITMAPINFOHEADER));

// Initialize the fields in the BITMAPINFO structure.

pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pbmi->bmiHeader.biWidth = bmp.bmWidth;
pbmi->bmiHeader.biHeight = bmp.bmHeight;
pbmi->bmiHeader.biPlanes = bmp.bmPlanes;
pbmi->bmiHeader.biBitCount = bmp.bmBitsPixel;
if (cClrBits < 24)
pbmi->bmiHeader.biClrUsed =(1<<cClrBits);
//pbmi->bmiHeader.biXPelsPerMeter=64;
//pbmi->bmiHeader.biYPelsPerMeter=64;
// If the bitmap is not compressed, set the BI_RGB flag.
pbmi->bmiHeader.biCompression = BI_RGB;

// Compute the number of bytes in the array of color
// indices and store the result in biSizeImage.
// For Windows NT, the width must be DWORD aligned unless
// the bitmap is RLE compressed. This example shows this.
// For Windows 95/98/Me, the width must be WORD aligned unless the
// bitmap is RLE compressed.
pbmi->bmiHeader.biSizeImage = ((pbmi->bmiHeader.biWidth * cClrBits +31) & ~31) /8
* pbmi->bmiHeader.biHeight;
// Set biClrImportant to 0, indicating that all of the
// device colors are important.
pbmi->bmiHeader.biClrImportant = 0;
return TRUE;
}
BOOL CreateBMPFile(LPCTSTR pszFile, PBITMAPINFO pbi,
HBITMAP hBMP, HDC hDC)
{
HANDLE hf; // file handle
BITMAPFILEHEADER hdr; // bitmap file-header
PBITMAPINFOHEADER pbih; // bitmap info-header
LPBYTE lpBits; // memory pointer
DWORD dwTotal; // total count of bytes
DWORD cb; // incremental count of bytes
BYTE *hp; // byte pointer
DWORD dwTmp;

pbih = (PBITMAPINFOHEADER) pbi;
//pbih->biBitCount=24;//每个像素所需的位数,必须是1(双色), 4(16色),8(256色)或24(真彩色)之一
//pbih->biClrImportant = 0; //位图显示过程中重要的颜色数,前11项是BITMAPINFOHEADER
//pbih->biClrUsed = 0; //位图实际使用的颜色表中的颜色数
//pbih->biCompression = BI_RGB; //位图压缩类型,必须是 0(不压缩),1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一
//pbih->biHeight = height; //位图的高度,以像素为单位
//pbih->biPlanes = 1; //目标设备的级别,必须为1
//pbih->biSize = sizeof(BITMAPINFOHEADER); //本结构所占用字节数
//pbih->biSizeImage = dataSize; //位图的大小,以字节为单位
//pbih->biWidth = width; //位图的宽度,以像素为单位
//pbih->biXPelsPerMeter = 64; //位图水平分辨率,每米像素数,0或者64都可以
//pbih->biYPelsPerMeter = 64; //位图垂直分辨率,每米像素数,0或者64都可以

lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizeImage);

if (!lpBits)
{
AfxMessageBox("分配位图内存失败!");
return FALSE;
}
// Retrieve the color table (RGBQUAD array) and the bits
// (array of palette indices) from the DIB.
if (!GetDIBits(hDC, hBMP, 0, (WORD) pbih->biHeight, lpBits, pbi,
DIB_RGB_COLORS))
{
AfxMessageBox("搜索位图颜色表和字节信息失败!");
return FALSE;
}

// Create the .BMP file.
hf = CreateFile(pszFile,
GENERIC_READ | GENERIC_WRITE,
(DWORD) 0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
(HANDLE) NULL);
if (hf == INVALID_HANDLE_VALUE)
{
CString str;
str.Format("创建位图文件失败,Could not open file (error %d)", GetLastError());
AfxMessageBox(str);
return FALSE;
}
hdr.bfType = 0x4d42; // 0x42 = "B" 0x4d = "M"

// Compute the size of the entire file.
hdr.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) +
pbih->biSize + pbih->biClrUsed
* sizeof(RGBQUAD) + pbih->biSizeImage);
hdr.bfReserved1 = 0;
hdr.bfReserved2 = 0;

// Compute the offset to the array of color indices.
hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) +
pbih->biSize + pbih->biClrUsed
* sizeof (RGBQUAD);

// Copy the BITMAPFILEHEADER into the .BMP file.
if (!WriteFile(hf, (LPVOID) &hdr, sizeof(BITMAPFILEHEADER),
(LPDWORD) &dwTmp, NULL))
{
AfxMessageBox("写入位图文件头失败!");
return FALSE;
}


// Copy the BITMAPINFOHEADER and RGBQUAD array into the file.
if (!WriteFile(hf, (LPVOID) pbih, sizeof(BITMAPINFOHEADER)
+ pbih->biClrUsed * sizeof (RGBQUAD),
(LPDWORD) &dwTmp, ( NULL)))
{
AfxMessageBox("写入位图文件头信息失败!");
return FALSE;
}

// Copy the array of color indices into the .BMP file.
dwTotal = cb = pbih->biSizeImage;
hp = lpBits;
if (!WriteFile(hf, (LPSTR) hp, (int) cb, (LPDWORD) &dwTmp,NULL))
{
AfxMessageBox("写入位图失败!");
return FALSE;
}
// Close the .BMP file.
if (!CloseHandle(hf))
{
AfxMessageBox("位图文件头句柄关闭失败!");
return FALSE;
}
// Free memory.
GlobalFree((HGLOBAL)lpBits);

return TRUE;
}


void CScreenDlg::SaveSelectBmp(void)
{
if(!m_bSelectOK)
{
MessageBox("已经取消选中的矩形");
return;
}

if(m_rectSelect.IsRectEmpty() || m_rectSelect.IsRectNull())
{
MessageBox("所选矩形为空!");
return;
}

CDC dcSave;
dcSave.CreateCompatibleDC(NULL);
CBitmap bitmap;
BITMAP bm;
m_bmpScreen.GetObject(sizeof(bm), &bm);
bm.bmWidth = m_rectSelect.Width();
bm.bmHeight = m_rectSelect.Height();
bitmap.CreateBitmapIndirect(&bm);
CBitmap* pOldBmp = dcSave.SelectObject(&bitmap);

dcSave.StretchBlt(0,0, m_rectSelect.Width(), m_rectSelect.Height(),
&m_dcMem, m_rectSelect.left, m_rectSelect.top,
m_rectSelect.Width(), m_rectSelect.Height(), SRCCOPY);

HBITMAP hBmp = (HBITMAP)bitmap.Detach();
dcSave.SelectObject(pOldBmp);


// save to the file
PBITMAPINFO pbmp;
if(!CreateBitmapInfoStruct(hBmp, pbmp))
{
MessageBox("创建位图信息失败!");
return;
}

CString strFile;
strFile.Format("F:\\assignment\\截屏\\截图存储处\\位图%d.bmp",i++);
if(!CreateBMPFile(strFile, pbmp, hBmp, GetDC()->GetSafeHdc()))
AfxMessageBox("Save image file unsuccessfully!");
}
...全文
361 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
Randyqiu 2009-04-02
  • 打赏
  • 举报
回复
老大们,请你们说一下怎么修改就可以了,
IONPhantom 2009-04-01
  • 打赏
  • 举报
回复
我就奇怪了这年月怎么还这么多用256色图的呢
撼地老牛 2009-04-01
  • 打赏
  • 举报
回复
用OpenCV或者CXimage,很方便,用GDI太累,GDI+还凑合

19,464

社区成员

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

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