我需要使用 C++ 代码创建单色 .bmp 签名文件,但无法创建

Posted

技术标签:

【中文标题】我需要使用 C++ 代码创建单色 .bmp 签名文件,但无法创建【英文标题】:I need to create monocrome .bmp signature file by using C++ code but not able to create 【发布时间】:2017-12-26 14:02:09 【问题描述】:

。下面是代码sn-p。

bool SaveBMP ( BYTE* Buffer, int width, int height, long paddedsize, LPCTSTR bmpfile )

    // declare bmp structures 
    BITMAPFILEHEADER bmfh;
    BITMAPINFOHEADER info;

    // andinitialize them to zero
    memset ( &bmfh, 0, sizeof (BITMAPFILEHEADER ) );
    memset ( &info, 0, sizeof (BITMAPINFOHEADER ) );

    // fill the fileheader with data
    bmfh.bfType = 0x4d42;       // 0x4d42 = 'BM'
    bmfh.bfReserved1 = 0;
    bmfh.bfReserved2 = 0;
    bmfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + paddedsize;
    bmfh.bfOffBits = 0x36;      // number of bytes to start of bitmap bits

    // fill the infoheader

    info.biSize = sizeof(BITMAPINFOHEADER);
    info.biWidth = width;
    info.biHeight = height;
    info.biPlanes = 1;          // we only have one bitplane
    info.biBitCount = 1;        // RGB mode is 24 bits
    info.biCompression = BI_RGB;    
    info.biSizeImage = 0;       // can be 0 for 24 bit images
    info.biXPelsPerMeter = 0x0ec4;     // paint and PSP use this values
    info.biYPelsPerMeter = 0x0ec4;     
    info.biClrUsed = 0;         // we are in RGB mode and have no palette
    info.biClrImportant = 0;    // all colors are important

    // now we open the file to write to
    HANDLE file = CreateFile ( bmpfile , GENERIC_WRITE, FILE_SHARE_READ,
         NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
    if ( file == NULL )
    
        CloseHandle ( file );
        return false;
    

    // write file header
    unsigned long bwritten;
    if ( WriteFile ( file, &bmfh, sizeof ( BITMAPFILEHEADER ), &bwritten, NULL ) == false )
       
        CloseHandle ( file );
        return false;
    
    // write infoheader
    if ( WriteFile ( file, &info, sizeof ( BITMAPINFOHEADER ), &bwritten, NULL ) == false )
       
        CloseHandle ( file );
        return false;
    
    // write image data
    if ( WriteFile ( file, Buffer, paddedsize, &bwritten, NULL ) == false )
       
        CloseHandle ( file );
        return false;
    

    // and close file
    CloseHandle ( file );

    return true;

**//当我运行这段代码时,创建的位图文件是空白的,没有显示签名,只有签名文件的背景能够显示。 **

【问题讨论】:

我再次尝试上传,现在可以上传代码了。 所以您可以使用图像编辑器打开创建的文件而不会出现任何错误,并且文件大小正确但内容为空? 【参考方案1】:

单色位图需要调色板。在这种情况下,调色板大小为 8 个字节(2 个RGBQUAD 值)

这额外的 8 个字节应添加到 BITMAPFILEHEADER 文件大小。

BITMAPFILEHEADER 之后,您正在使用不包含调色板信息的BITMAPINFOHEADER。您必须直接使用BITMAPINFO 而不是BITMAPINFOHEADER

BITMAPINFO* bmpinfo = (BITMAPINFO*)malloc(palette_size + sizeof(BITMAPINFOHEADER));
bmpinfo->bmiHeader =  sizeof(BITMAPINFOHEADER), 
    width, height, 1, bitcount, BI_RGB, 0, 0, 0, 0, 0 ;

如果没有为单色位图检索Buffer,那么您不能简单地在此保存功能中更改bitcount 并期望一切正常。

if ( file == NULL )// <-error

    CloseHandle ( file );
    return false;

如果CreateFile 失败,则返回值为INVALID_HANDLE_VALUE。您可以从 API 函数的在线文档中找到这些值。更正后的版本应该是

if(file != INVALID_HANDLE_VALUE)

    unsigned long bwritten;
    WriteFile(file, &bmfh, sizeof(BITMAPFILEHEADER), &bwritten, NULL);
    WriteFile(file, bmpinfo, 8 + sizeof(BITMAPINFOHEADER), &bwritten, NULL);
    WriteFile(file, Buffer, paddedsize, &bwritten, NULL);
    CloseHandle(file);
    return true;

return false;

【讨论】:

您提供的解决方案,我确实更改了代码,但问题仍然存在 //正如您提供的解决方案,我确实更改了代码,但问题仍然存在。正在创建单色文件但签名也被删除,这是意料之外的。这意味着只显示图片的背景,但背景上的文字被删除。 “我确实更改了代码” 不是一回事。您必须使用调色板检索缓冲区,或者如果缓冲区尚未包含调色板,则必须添加调色板。 我是这个东西的新手,请你帮我添加调色板或者你会解释如何用调色板检索缓冲区。 @Pankaj Palette 存储在 BITMAPINFO::bmiColors 中。所以这将初始化黑白调色板:bmpinfo-&gt;bmiColors[0] = 0,0,0,0; bmpinfo-&gt;bmiColors[1] = 255,255,255,0;.

以上是关于我需要使用 C++ 代码创建单色 .bmp 签名文件,但无法创建的主要内容,如果未能解决你的问题,请参考以下文章

1bpp 单色 BMP

计算单色 BMP 的 BITMAPINFOHEADER biCompression 值

生成 1 位深度的 BMP 图像

使用命令将 BMP 文件打印到打印机

现代C++ 类型推导

如何使用 C++ 创建 BMP 文件?