读取bmp图片

对bmp处理 注意宽度必须是4的倍数(字节)
将bmp内容读取到unsigned char格式的内存中,直接对该内存进行处理
MyBitmap.h

#pragma once
#include "stdafx.h"
#include <cmath>
class MyBitmap
{
public:
    void GetBmpByFilePath(char *filepath);
    void ShowArrayToDevice(CDC *dc, int xDes, int yDes, const unsigned char *desfile,WORD BitCount, tagRGBQUAD *pPal);
    WORD GetBitCount();
    bool HavePalette();
    unsigned char *GetBmp();
    LONG GetWidth();
    LONG GetHeight();
private:
    WORD biBitCount;
    tagRGBQUAD *pPal;
    unsigned char *bmp;
    LONG width;
    LONG height;
};

MyBitmap.cpp

#include "MyBitmap.h"
void  MyBitmap::GetBmpByFilePath(char *filepath)
{
    FILE *file = NULL;
    file = fopen(filepath, "rb");
    if (file == NULL) { AfxMessageBox("文件读取失败!"); return; }
    //读取bmp头
    BITMAPFILEHEADER bmpFileHead;
    fread(&bmpFileHead, sizeof(BITMAPFILEHEADER), 1, file);
    if (bmpFileHead.bfType != 0x4d42)  { AfxMessageBox("图像不是bmp格式!"); return; }
    DWORD sumNum = bmpFileHead.bfSize;//这个长度是数据长度
    DWORD offNum = bmpFileHead.bfOffBits;//数据偏移头部长度
    BITMAPINFOHEADER bmpInfoHead;
    fread(&bmpInfoHead, sizeof(BITMAPINFOHEADER), 1, file);
    if (bmpInfoHead.biCompression != 0){ AfxMessageBox("无法处理的bmp压缩格式!"); return; }
    biBitCount = bmpInfoHead.biBitCount;
    long nPlantNum;
    if (bmpInfoHead.biBitCount < 24)//读取调色板
    {
        nPlantNum = long(pow(2, double(bmpInfoHead.biBitCount)));    //   Mix color Plant Number;
        pPal = new tagRGBQUAD[nPlantNum*sizeof(tagRGBQUAD)];
        memset(pPal, 0, nPlantNum*sizeof(tagRGBQUAD));
        fread(pPal, 4, nPlantNum, file);
    }
    else pPal = NULL;
    width = bmpInfoHead.biWidth;//宽度必须是4B的倍数
    height = bmpInfoHead.biHeight;
    if (bmpInfoHead.biBitCount < 24)//注意宽度的计算方式
    {
        width = (width % (32 / biBitCount) == 0) ? width : (width / (32 / biBitCount) + 1) * (32 / biBitCount);//宽度调整为4B 32的倍数
        // width = (width+3)/4*4;
        width = width*biBitCount / 8;
    }
    else
        width = (width*biBitCount / 8 + 3) / 4 * 4;
    height = abs(height);
    bmp = new unsigned char[height*width];
    fread(bmp, 1, height*width, file);
    fclose(file);
}
WORD MyBitmap::GetBitCount()
{
    return biBitCount;
}
bool MyBitmap::HavePalette()
{
    if (pPal) return false;
    return true;
}
unsigned char *MyBitmap::GetBmp()
{
    return bmp;
}
LONG MyBitmap::GetHeight()
{
    return height;
}
LONG MyBitmap::GetWidth()
{
    return width;
}
void MyBitmap::ShowArrayToDevice(CDC *dc, int x, int y, const unsigned char *desfile,WORD BitCount, tagRGBQUAD *pPal)
{
    CDC dcMemory;
    dcMemory.CreateCompatibleDC(dc);
    CBitmap bitmap;
    bitmap.CreateCompatibleBitmap(dc, width / 3, height);
    dcMemory.SelectObject(&bitmap);
    int k;
    for (int j = 0; j < height; j++)
    for (int i = 0; i < width; i++)//宽度变长,比如2倍,图像会显示2副,第二幅为第一副的隔行
    {
        unsigned char r, g, b, gray;
        COLORREF c;
        BYTE w16;
        switch (BitCount)
        {
        case 1://读取单色bmp
            // fread(&gray, sizeof(BYTE), 1, file);
            gray = bmp[(height - 1 - j)*width + i];
            for (k = 0; k < 8; k++)
            {
                c = gray & 0x80;
                if (c == 0x80) c = RGB(255, 255, 255);
                else c = 0;
                dcMemory.SetPixel(x + i * 8 + k, y + j, c);
                //  SetPixel(hdc, x + i++, y + height - j, c);
                gray = gray << 1;
            }
            break;
        case 4://读取4位16色
            w16 = bmp[j*width + i];
            dcMemory.SetPixel(x + i * 2, y + height - j, RGB(pPal[w16 >> 4].rgbRed, pPal[w16 >> 4].rgbGreen, pPal[w16 >> 4].rgbBlue));
            dcMemory.SetPixel(x + i * 2 + 1, y + height - j, RGB(pPal[w16 & 0x0f].rgbRed, pPal[w16 & 0x0f].rgbGreen, pPal[w16 & 0x0f].rgbBlue));
            break;
        case 8://读取8位256色
            gray = bmp[j*width + i];
            dcMemory.SetPixel(x + i, y + height - j, RGB(pPal[gray].rgbRed, pPal[gray].rgbGreen, pPal[gray].rgbBlue));
            break;
        case 24:
            b = bmp[j*width + i];
            g = bmp[j*width + i + 1];
            r = bmp[j*width + i + 2];
            dcMemory.SetPixel(x + i / 3, y + height - j, RGB(r, g, b));
            i += 2;
            break;
        }
    }
    dc->BitBlt(0, 0, width, height, &dcMemory, 0, 0, SRCCOPY);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值