将HBITMAP保存为Bmp文件,发现Bmp文件颜色不正确,哪位老大帮俺看看

codemon 2002-08-05 03:59:28
将HBITMAP保存为Bmp文件,发现Bmp文件颜色不正确,哪位老大帮俺看看

BOOL Save(LPCTSTR lpszFileName,HBITMAP hBmp,BITMAPINFO* pBi)
{
BITMAPINFOHEADER* pBh=(BITMAPINFOHEADER*)pBi;
LPBYTE lpBits = new BYTE[pBh->biSizeImage];
if (!lpBits) return FALSE;

HDC hdc=GetDC(NULL);
if (!hdc ||
!GetDIBits(hdc,hBmp, 0, (WORD)(pBh->biHeight),lpBits,pBi,DIB_RGB_COLORS))
{
if(hdc) ReleaseDC(NULL,hdc);
delete lpBits;
return FALSE;
}

ReleaseDC(NULL,hdc);

FILE* pFile=NULL;
pFile = fopen(lpszFileName, "w+b");
if(!pFile)
{
delete lpBits;
return FALSE;
}


BITMAPFILEHEADER hdr;
hdr.bfType = (WORD)('M'<<8)|'B';
hdr.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) + pBh->biSize + pBh->biClrUsed* sizeof(RGBQUAD) + pBh->biSizeImage);
hdr.bfReserved1 = 0;
hdr.bfReserved2 = 0;
hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + pBh->biSize + pBh->biClrUsed * sizeof(RGBQUAD);

fseek(pFile,0,SEEK_SET);
fwrite(&hdr,sizeof(BYTE),sizeof(BITMAPFILEHEADER),pFile);
fwrite(pBh,sizeof(BYTE), sizeof(BITMAPINFOHEADER)+pBh->biClrUsed * sizeof(RGBQUAD),pFile);
fwrite(lpBits,sizeof(BYTE),pBh->biSizeImage,pFile);
fclose(pFile);

delete lpBits;
return TRUE;
}
...全文
107 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
zzhcom 2002-08-06
  • 打赏
  • 举报
回复
只能说你们公司的网管孤陋寡闻了,codeproject这么经典的网站都不能上,有这样的公司
================================================================

CSDN 论坛助手 Ver 1.0 B0402提供下载。 改进了很多,功能完备!

★ 浏览帖子速度极快![建议系统使用ie5.5以上]。 ★ 多种帖子实现界面。
★ 保存帖子到本地[html格式]★ 监视您关注帖子的回复更新。
★ 可以直接发贴、回复帖子★ 采用XML接口,可以一次性显示4页帖子,同时支持自定义每次显示帖子数量。可以浏览历史记录!
★ 支持在线检测程序升级情况,可及时获得程序更新的信息。

★★ 签名 ●
可以在您的每个帖子的后面自动加上一个自己设计的签名哟。

Http://www.ChinaOK.net/csdn/csdn.zip
Http://www.ChinaOK.net/csdn/csdn.rar
Http://www.ChinaOK.net/csdn/csdn.exe [自解压]

codemon 2002-08-06
  • 打赏
  • 举报
回复
wuxuan(真心英雄)
公司限制,只能上CSDN,能不能帮个忙贴过来?谢了先。
zhangdaqiang 2002-08-06
  • 打赏
  • 举报
回复
http://www.codeproject.com/bitmap/cximage.asp
codemon 2002-08-06
  • 打赏
  • 举报
回复
解决啦!!!
原来是 biCompression 的值不对 :)
nzzt 2002-08-06
  • 打赏
  • 举报
回复
这个函数绝对没有问题。
出问题的地方可能是:
1。BITMAPINFO 没算对
2。HBITMAP 不是用当前系统的DC抓下来的。你传个HDC进来,用传进来的HDC看看。

MSDN上的例子:

PBITMAPINFO CreateBitmapInfoStruct(HWND hwnd, HBITMAP hBmp)
{
BITMAP bmp;
PBITMAPINFO pbmi;
WORD cClrBits;

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

// 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);

// 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 pbmi;
} The following example code defines a function that initializes the remaining structures, retrieves the array of palette indices, opens the file, copies the data, and closes the file.

void CreateBMPFile(HWND hwnd, LPTSTR 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;
lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizeImage);

if (!lpBits)
errhandler("GlobalAlloc", hwnd);

// 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))
{
errhandler("GetDIBits", hwnd);
}

// 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)
errhandler("CreateFile", hwnd);
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))
{
errhandler("WriteFile", hwnd);
}

// Copy the BITMAPINFOHEADER and RGBQUAD array into the file.
if (!WriteFile(hf, (LPVOID) pbih, sizeof(BITMAPINFOHEADER)
+ pbih->biClrUsed * sizeof (RGBQUAD),
(LPDWORD) &dwTmp, ( NULL))
errhandler("WriteFile", hwnd);

// 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))
errhandler("WriteFile", hwnd);

// Close the .BMP file.
if (!CloseHandle(hf))
errhandler("CloseHandle", hwnd);

// Free memory.
GlobalFree((HGLOBAL)lpBits);
}
wuxuan 2002-08-05
  • 打赏
  • 举报
回复
see this.
http://www.codeproject.com/bitmap/cximage.asp
s_phoenix 2002-08-05
  • 打赏
  • 举报
回复
gz
我最近听别人说什么“调色板”。我也不太懂。看看后面的大侠了,是否和这个有关?
codemon 2002-08-05
  • 打赏
  • 举报
回复
等待ing....

16,471

社区成员

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

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

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