HBITMAP生成BMP时,WriteFIle执行失败,错误代码:1784

xiejanee 2014-08-22 11:09:11
写了段代码,用HBITMAP生成BMP,代码如下:

HBITMAP hBmp= ( HBITMAP) LoadImage( NULL, "111.bmp", IMAGE_BITMAP, 0, 0
, LR_CREATEDIBSECTION| LR_LOADFROMFILE);
BITMAP bmpinfo;
if ( GetObject( hBmp, sizeof(bmpinfo), &bmpinfo)<= 0 || NULL== bmpinfo.bmBits)
{
DeleteObject( hBmp);
MessageBox( NULL, _T("读取位图文件数据错误!"), _T("提升"), MB_OK);
return 0;
}
HDC hDC = GetDC( NULL);

//第一次调用getDIbit,获得不含文件和信息头的bmp数据大小
BYTE *lpvBits = NULL;
BITMAPINFO bmpInfo = {0};
bmpInfo.bmiHeader.biSize = sizeof(bmpInfo.bmiHeader);
int nRet = GetDIBits(hDC, hBmp, 0, (WORD)bmpinfo.bmHeight, NULL, &bmpInfo, DIB_PAL_COLORS);

//第二次调用,获取数据
lpvBits= new BYTE[bmpInfo.bmiHeader.biSizeImage];
if (NULL == lpvBits) {
nRet = -1;
// TRACE( _T("Allocate memory for lpvBits failed/n"));
}
int tet = GetDIBits(hDC, hBmp, 0, (WORD)bmpinfo.bmHeight, lpvBits, &bmpInfo, DIB_PAL_COLORS);

//另存为.bmp
BITMAPFILEHEADER hdr; // bitmap file-header
DWORD dwTmp;

HANDLE hf = CreateFile("md.bmp",
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) +
bmpInfo.bmiHeader.biSize + 256
* sizeof(RGBQUAD) + bmpInfo.bmiHeader.biSizeImage);
hdr.bfReserved1 = 0;
hdr.bfReserved2 = 0;

// Compute the offset to the array of color indices.
hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) +
bmpInfo.bmiHeader.biSize + 256
* 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) &bmpInfo, sizeof(BITMAPINFOHEADER)
+256 * sizeof (RGBQUAD),
(LPDWORD) &dwTmp, ( NULL)))
{
//errhandler("WriteFile", hwnd);
}

// Copy the array of color indices into the .BMP file.
DWORD cb = bmpInfo.bmiHeader.biSizeImage;
if (!WriteFile(hf, (LPSTR) lpvBits, bmpInfo.bmiHeader.biSizeImage, (LPDWORD) &dwTmp,NULL))
{
DWORD i = GetLastError();
cout <<"err:"<< (int)i;
//errhandler("WriteFile", hwnd);
}

当程序执行到函数WriteFile(hf, (LPSTR) lpvBits, bmpInfo.bmiHeader.biSizeImage, (LPDWORD) &dwTmp,NULL)时,出现错误,错误代码为:1784, 即:提供给请求操作的用户缓冲区无效。请大家帮忙看看代码的问题出在哪? 难道是调用GetDIBits 函数时没有成功给lpvBits赋值?
...全文
235 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
勤奋的小游侠 2014-08-22
  • 打赏
  • 举报
回复
dwTmp是什么东西
xiejanee 2014-08-22
  • 打赏
  • 举报
回复
是的 位图里面的数据我并没有改动 而是直接用来构造新的bmp图像。 上面代码中,我是想把一副灰度图的数据部分取出,然后添加文件头和信息头放入新的bmp图像中,按道理说得到的图和原图一样,但是得到的图很奇怪,成了只有一种颜色的彩图了。
赵4老师 2014-08-22
  • 打赏
  • 举报
回复
小心每行数据的字节数必须是4的倍数,不够需要凑齐。
xiejanee 2014-08-22
  • 打赏
  • 举报
回复
谢谢赵老师,我对程序修改了一下,执行不会报错。但是有个问题,下面这段代码只是将bmp图像读进内存,未作任何修改,然后另存为新的bmp图像,发现所得图像与原图不同,不知道为何。 HBITMAP hBmp= ( HBITMAP) LoadImage( NULL, "111.bmp", IMAGE_BITMAP, 0, 0 , LR_CREATEDIBSECTION| LR_LOADFROMFILE); BITMAP bmp; if ( GetObject( hBmp, sizeof(bmp), &bmp)<= 0 || NULL== bmp.bmBits) { DeleteObject( hBmp); MessageBox( NULL, _T("读取位图文件数据错误!"), _T("提升"), MB_OK); return 0; } HDC hDC = GetDC( NULL); PBITMAPFILEHEADER headbuf; PBITMAPINFO infobuf; LPBYTE databuf; long headsize,infosize,datasize; WORD cClrBits; DWORD my_biClrUsed=0; cClrBits = (WORD)(bmp.bmPlanes * bmp.bmBitsPixel); //得到每像素多少位 //分配内存大小,信息头+调色板大小 infosize= sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (1<< cClrBits); infobuf = (PBITMAPINFO) GlobalAlloc (GPTR, infosize); // Initialize the fields in the BITMAPINFO structure. infobuf->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); //信息头大小(不含调色板) infobuf->bmiHeader.biWidth = bmp.bmWidth; infobuf->bmiHeader.biHeight = bmp.bmHeight; infobuf->bmiHeader.biPlanes = bmp.bmPlanes; infobuf->bmiHeader.biBitCount = bmp.bmBitsPixel; infobuf->bmiHeader.biCompression = BI_RGB; infobuf->bmiHeader.biClrImportant = 0; my_biClrUsed=(1<<cClrBits); infobuf->bmiHeader.biClrUsed = my_biClrUsed; //图像大小 infobuf->bmiHeader.biSizeImage = ((infobuf->bmiHeader.biWidth*cClrBits+31)&~31)/8*infobuf->bmiHeader.biHeight; datasize=infobuf->bmiHeader.biSizeImage; databuf = (LPBYTE) GlobalAlloc(GPTR, datasize); //根据位图大小分配内存 if (!databuf) { } //根据DC和BITMAP得到位图数据 if (!GetDIBits( hDC, hBmp, 0, (WORD) infobuf->bmiHeader.biHeight, databuf, // outdatabuf中得到位图数据 infobuf, DIB_PAL_COLORS) ) { } //另存为.bmp BITMAPFILEHEADER hdr; // bitmap file-header DWORD dwTmp; HANDLE hf = CreateFile("md.bmp", 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) + infobuf->bmiHeader.biSize + 256 * sizeof(RGBQUAD) + infobuf->bmiHeader.biSizeImage); hdr.bfReserved1 = 0; hdr.bfReserved2 = 0; // Compute the offset to the array of color indices. hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + infobuf->bmiHeader.biSize + 256 * 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) infobuf, sizeof(BITMAPINFOHEADER) +256 * sizeof (RGBQUAD), (LPDWORD) &dwTmp, ( NULL))) { //errhandler("WriteFile", hwnd); } // Copy the array of color indices into the .BMP file. DWORD cb = infobuf->bmiHeader.biSizeImage; if (!WriteFile(hf, (LPSTR) databuf, infobuf->bmiHeader.biSizeImage, (LPDWORD) &dwTmp,NULL)) { DWORD i = GetLastError(); cout <<"err:"<< (int)i; //errhandler("WriteFile", hwnd); } // Close the .BMP file. if (!CloseHandle(hf)) { } // Free memory. GlobalFree(databuf); GlobalFree(infobuf);
赵4老师 2014-08-22
  • 打赏
  • 举报
回复
仅供参考
#pragma comment(lib,"gdi32")
#include <windows.h>
#include <stdio.h>

int main() {
    const DWORD uWidth = 18 + 17 * 256, uHeight = 18 + 17 * 128;

    PBITMAPINFO pbmi = (PBITMAPINFO) LocalAlloc (LPTR, sizeof (BITMAPINFOHEADER) + sizeof (RGBQUAD) * 2);
    pbmi->bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
    pbmi->bmiHeader.biWidth = uWidth;
    pbmi->bmiHeader.biHeight = uHeight;
    pbmi->bmiHeader.biPlanes = 1;
    pbmi->bmiHeader.biBitCount = 1;
    pbmi->bmiHeader.biSizeImage = ((uWidth + 31) & ~31) / 8 * uHeight;
    pbmi->bmiColors[0].rgbBlue = 0;
    pbmi->bmiColors[0].rgbGreen = 0;
    pbmi->bmiColors[0].rgbRed = 0;
    pbmi->bmiColors[1].rgbBlue = 255;
    pbmi->bmiColors[1].rgbGreen = 255;
    pbmi->bmiColors[1].rgbRed = 255;

    HDC hDC = CreateCompatibleDC (0);
    void * pvBits;
    HBITMAP hBitmap = CreateDIBSection (hDC, pbmi, 0, &pvBits, NULL, 0);
    SelectObject (hDC, hBitmap);
    HFONT hFont = CreateFont (16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "宋体");
//  HFONT hFont = CreateFont (16, 0, 0, 0, 0, 0, 0, 0, SHIFTJIS_CHARSET, 0, 0, 0, 0, "宋体");
    SelectObject (hDC, hFont);
    BitBlt (hDC, 0, 0, uWidth, uHeight, NULL, 0, 0, WHITENESS);

    char c[4];
    int i, j;
    for (i = 128; i < 256; i++) {
        sprintf (c, "%02X", i);
        TextOut (hDC, 1, (i - 127) * 17 + 1, c, 2);
    }
    for (j = 0; j < 256; j++) {
        sprintf (c, "%02X", j);
        TextOut (hDC, (j + 1)* 17 + 1, 1, c, 2);
    }
    for (i = 128; i < 256; i++) {
        for (j = 0; j < 256; j++) {
            c[0] = (char) i;
            c[1] = (char) j;
            TextOut (hDC, (j + 1) * 17 + 1, (i - 127) * 17 + 1, c, 2);
        }
    }
    for (i = 0; i < 130; i++) {
        MoveToEx (hDC, 0, i * 17, NULL);
        LineTo (hDC, uWidth, i * 17);
    }
    for (j = 0; j < 258; j++) {
        MoveToEx (hDC, j * 17, 0, NULL);
        LineTo (hDC, j * 17, uHeight);
    }

    BITMAPFILEHEADER bmfh;
    bmfh.bfType = *(PWORD) "BM";
    bmfh.bfReserved1 = 0;
    bmfh.bfReserved2 = 0;
    bmfh.bfOffBits = sizeof (BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER) + sizeof (RGBQUAD) * 2;
    bmfh.bfSize = bmfh.bfOffBits + pbmi->bmiHeader.biSizeImage;

    HANDLE hFile = CreateFile ("goal.bmp", GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
    if (hFile != INVALID_HANDLE_VALUE) {
        DWORD dwWritten;
        WriteFile (hFile, &bmfh, sizeof (BITMAPFILEHEADER), &dwWritten, NULL);
        WriteFile (hFile, pbmi, sizeof (BITMAPINFOHEADER) + sizeof (RGBQUAD) * 2, &dwWritten, NULL);
        WriteFile (hFile, pvBits, pbmi->bmiHeader.biSizeImage, &dwWritten, NULL);

        CloseHandle (hFile);
    }

    DeleteObject (hFont);
    DeleteObject (hBitmap);
    DeleteDC (hDC);
    LocalFree (pbmi);

    return 0;
}
xiejanee 2014-08-22
  • 打赏
  • 举报
回复
引用 1 楼 lovesmiles 的回复:
dwTmp是什么东西
dwTmp 保存函数返回的写入字节数的一个变量

64,650

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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