如何向BITMAPINFO添加调色板 [英] How to add color palette to BITMAPINFO

查看:169
本文介绍了如何向BITMAPINFO添加调色板的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个函数创建一个 bmp 文件,并分别写入文件头,信息头和实际像素数据。这是:

I have a function which creates a bmp file and writes the file header, the info header, and the actual pixel data respectively. Here it is:

bool SaveBMP(BYTE* Buffer, int width, int height, long paddedsize, LPCTSTR bmpfile)
{
    BITMAPFILEHEADER bmfh;
    BITMAPINFOHEADER info;

    memset(&bmfh, 0, sizeof(BITMAPFILEHEADER));
    memset(&info, 0, sizeof(BITMAPINFOHEADER));

    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

    info.biSize = sizeof(BITMAPINFOHEADER);
    info.biWidth = width;
    info.biHeight = height;
    info.biPlanes = 1;          
    info.biBitCount = 8;        
    info.biCompression = 0;
    info.biSizeImage = 0;       
    info.biXPelsPerMeter = 0;   
    info.biYPelsPerMeter = 0;
    info.biClrUsed = 256;       
    info.biClrImportant = 0;    

    HANDLE file = CreateFile(bmpfile, GENERIC_WRITE, FILE_SHARE_READ,
                             NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

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

但是,我理解我必须为8位灰度图像提供一个调色板

However, I understand that I have to provide a color palette for 8bit grayscale images like in the following code.

BITMAPINFO* pbmi

for (int i = 0; i<256; i++)
{
    pbmi->bmiColors[i].rgbRed = i;
    pbmi->bmiColors[i].rgbGreen = i;
    pbmi->bmiColors[i].rgbBlue = i;
    pbmi->bmiColors[i].rgbReserved = 0;
}

问题是,我不知道如何连接我的 BITMAPINFOHEADER 转到 BITMAPINFO

The problem is, I don't know how to connect my BITMAPINFOHEADER to the BITMAPINFO.

CreateDIBSection 函数与我当前的代码?

And is there a way to use CreateDIBSection function with my current code?

推荐答案

没有使用 BITMAPINFO 。我使用 RGBQUAD 来写调色板。这里的解决方案:

I modified the function and didn't use BITMAPINFO at all. I used RGBQUAD to write the color palette instead. Here's the solution:

bool SaveBMP(BYTE* Buffer, int width, int height, long paddedsize, LPCTSTR bmpfile)
{
    const int NUMBER_OF_COLORS = 256;
    const int COLOR_PALETTE_SIZE = NUMBER_OF_COLORS * sizeof(RGBQUAD);
    const int HEADER_OFFSET = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + COLOR_PALETTE_SIZE;
    const int TOTAL_FILE_SIZE = HEADER_OFFSET + paddedsize;

    BITMAPFILEHEADER bmfh;
    BITMAPINFOHEADER info;
    RGBQUAD quad[NUMBER_OF_COLORS];
    memset(&bmfh, 0, sizeof(BITMAPFILEHEADER));
    memset(&info, 0, sizeof(BITMAPINFOHEADER));

    // create the color palette
    for (int i = 0; i < NUMBER_OF_COLORS; i++)
    {
        quad[i].rgbBlue = i;
        quad[i].rgbGreen = i;
        quad[i].rgbRed = i;
        quad[i].rgbReserved = 0;
    }

    // fill the fileheader
    bmfh.bfType = 0x4d42;           // 0x4d42 = 'BM'
    bmfh.bfSize = TOTAL_FILE_SIZE;  // Total file size
    bmfh.bfReserved1 = 0;           // UNUSED
    bmfh.bfReserved2 = 0;           // UNUSED
    bmfh.bfOffBits = HEADER_OFFSET; // Offset to start of pixel data

    // fill the infoheader
    info.biSize = sizeof(BITMAPINFOHEADER); // Header size (Must be at least 40)
    info.biWidth = width;                   // Image width
    info.biHeight = -height;                // Image height
    info.biPlanes = 1;                      // MUST BE 1
    info.biBitCount = 8;                    // Bits per pixel (1, 4, 8, 16, 24 or 32)
    info.biCompression = 0;                 // Compression type (BI_RGB = 0, BI_RLE8 = 1, BI_RLE4 = 2 or BI_BITFIELDS = 3)
    info.biSizeImage = height * width;      // Image size (May be 0 if not compressed)
    info.biXPelsPerMeter = 0;               // Preferred resolution in pixels per meter
    info.biYPelsPerMeter = 0;               // Preferred resolution in pixels per meter
    info.biClrUsed = NUMBER_OF_COLORS;      // Number of entries in the color map that are actually used
    info.biClrImportant = 0;                // Number of significant colors (All colors = 0)

    // 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 info header
    if (WriteFile(file, &info, sizeof(BITMAPINFOHEADER), &bwritten, NULL) == false)
    {
        CloseHandle(file);
        return false;
    }

    // write palette
    if (WriteFile(file, quad, COLOR_PALETTE_SIZE, &bwritten, NULL) == false)
    {
        CloseHandle(file);
        return false;
    }

    // write image data
    if (WriteFile(file, Buffer, paddedsize, &bwritten, NULL) == false)
    {
        CloseHandle(file);
        return false;
    }

    // close file
    CloseHandle(file);
    return true;
}

这篇关于如何向BITMAPINFO添加调色板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆