完整24位真彩色位图灰度化源代码

转载自:http://lipingke.blog.hexun.com/35837085_d.html

 

 

贴出来不为别的,就为万一以后硬盘出问题资料在网上还有个备份。

//Code By xets007
//转载请注明出处
//

#include <windows.h>

BOOL BMP24to8(char *szSourceFile, char *szTargetFile);

int main(int argc, char *argv[])
{
    BOOL stat = BMP24to8("c://source.bmp", "c://target.bmp"); //调用这个函数直接把24位真彩色灰度化
    return 0;
}

BOOL BMP24to8(char *szSourceFile, char *szTargetFile)
{
    HANDLE hSourceFile = INVALID_HANDLE_VALUE, hTargetFile = INVALID_HANDLE_VALUE;
    DWORD dwSourceSize = 0, dwTargetSize = 0;
    PBYTE pSource = NULL, pTarget = NULL;
    hSourceFile = CreateFile(szSourceFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hSourceFile == INVALID_HANDLE_VALUE)
           return FALSE;
    dwSourceSize = GetFileSize(hSourceFile, NULL);
    pSource = (PBYTE)VirtualAlloc(NULL, dwSourceSize, MEM_COMMIT, PAGE_READWRITE);
    if (pSource == NULL || dwSourceSize <= 54) //分配空间失败或者文件太小(BMP文件不可能小于54个字节)
    {
           CloseHandle(hSourceFile);
           return FALSE;
    }
    DWORD dwTemp = 0;
    ReadFile(hSourceFile, pSource, dwSourceSize, &dwTemp, NULL);
    BITMAPFILEHEADER *pSourceFileHeader = (BITMAPFILEHEADER *)pSource;
    BITMAPINFOHEADER *pSourceInfoHeader = (BITMAPINFOHEADER *)(pSource + sizeof(BITMAPFILEHEADER));
    if (pSourceFileHeader->bfType != 0x4d42 || pSourceInfoHeader->biBitCount != 24) //不是BMP文件或者不是24位真彩色
    {
           CloseHandle(hSourceFile);
           VirtualFree(pSource, NULL, MEM_RELEASE);
           return FALSE;
    }
    CloseHandle(hSourceFile);

    LONG nWidth = pSourceInfoHeader->biWidth;
    LONG nHeight = pSourceInfoHeader->biHeight;
    LONG nSourceWidth = nWidth * 3;
    if (nSourceWidth % 4)
        nSourceWidth = (nSourceWidth / 4 + 1) * 4;
    LONG nTargetWidth = nWidth;
    if (nTargetWidth % 4)
        nTargetWidth = (nTargetWidth / 4 + 1) * 4;
    dwTargetSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256 + nHeight * nTargetWidth;
        pTarget = (PBYTE)VirtualAlloc(NULL, dwTargetSize, MEM_COMMIT, PAGE_READWRITE);
    memset(pTarget, 0, dwTargetSize);
    if (pTarget == NULL)
    {
           VirtualFree(pTarget, NULL, MEM_RELEASE);
           return FALSE;
    }
    BITMAPFILEHEADER *pTargetFileHeader = (BITMAPFILEHEADER *)pTarget;
    BITMAPINFOHEADER *pTargetInfoHeader = (BITMAPINFOHEADER *)(pTarget + sizeof(BITMAPFILEHEADER));
    pTargetFileHeader->bfType = pSourceFileHeader->bfType;
    pTargetFileHeader->bfSize = dwTargetSize;
    pTargetFileHeader->bfReserved1 = 0;
    pTargetFileHeader->bfReserved2 = 0;
    pTargetFileHeader->bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256;
    pTargetInfoHeader->biBitCount = 8;
    pTargetInfoHeader->biClrImportant = 0;
    pTargetInfoHeader->biClrUsed = 256;
    pTargetInfoHeader->biCompression = BI_RGB;
    pTargetInfoHeader->biHeight = pSourceInfoHeader->biHeight;
    pTargetInfoHeader->biPlanes = 1;
    pTargetInfoHeader->biSize = sizeof(BITMAPINFOHEADER);
    pTargetInfoHeader->biSizeImage = nHeight * nTargetWidth;
    pTargetInfoHeader->biWidth = pSourceInfoHeader->biWidth;
    pTargetInfoHeader->biXPelsPerMeter = pSourceInfoHeader->biXPelsPerMeter;
    pTargetInfoHeader->biYPelsPerMeter = pSourceInfoHeader->biYPelsPerMeter;
    RGBQUAD *pRgb;
    for (int i = 0; i < 256; i++) //初始化8位灰度图的调色板信息
    {
           pRgb = (RGBQUAD *)(pTarget + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + i * sizeof(RGBQUAD));
           pRgb->rgbBlue = i;
        pRgb->rgbGreen = i;
        pRgb->rgbRed = i;
        pRgb->rgbReserved = 0;
    }
    for (int m = 0; m < nHeight; m++) //转化真彩色图为灰度图
    {
           for (int n = 0; n < nWidth; n++)
  
        {
                pTarget[pTargetFileHeader->bfOffBits + m * nTargetWidth + n] = pSource[pSourceFileHeader->bfOffBits + m * nSourceWidth + n * 3] * 0.114 + pSource[pSourceFileHeader->bfOffBits + m * nSourceWidth + n * 3 + 1] * 0.587 + pSource[pSourceFileHeader->bfOffBits + m * nSourceWidth + n * 3 + 2] * 0.299;
              
        }
    }
    hTargetFile = CreateFile(szTargetFile, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    BOOL stat = WriteFile(hTargetFile, pTarget, dwTargetSize, &dwTemp, NULL);
    CloseHandle(hTargetFile);
    VirtualFree(pSource, NULL, MEM_RELEASE);
    VirtualFree(pTarget, NULL, MEM_RELEASE);
    return stat;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值