BMP文件的读取

简介:
运行测试效果: 


代码:

复制代码
void CMyView::OnReadBmp() 
{//读取BMP文件并显示
    CDC *pDC = GetDC();

    CFileDialog dlg(TRUE);
    if(dlg.DoModal()==IDOK)
    {//选择要打开的BMP图片
        strFilePath=dlg.GetPathName();
    }

    if(strFilePath=="")
    {//取消
        return;
    }

    FILE *fp=fopen(strFilePath,"r");

    BITMAPFILEHEADER fileheader;
    BITMAPINFO info;

    fread(&fileheader,sizeof(fileheader),1,fp);

    if(fileheader.bfType!=0x4D42)
    {//不是BMP位图文件
        pDC->TextOut(100,200,"无位图文件 请选择位图文件");
        fclose(fp);
        return ;
    }
    UCHAR *buffer = NULL;

    //读位图头部
    fread(&info.bmiHeader, sizeof(BITMAPINFOHEADER), 1, fp);
    //位图宽度
    long width=info.bmiHeader.biWidth;
    this->width = width;
    //位图高度
    long height=info.bmiHeader.biHeight;
    this->height = height;
    
    DWORD size;
    if (info.bmiHeader.biSizeImage != 0)
    {//带颜色表
        size = info.bmiHeader.biSizeImage;
        
    }
    else
    {//不带颜色表的
        size = info.bmiHeader.biHeight*info.bmiHeader.biWidth*3;
    }
    buffer = new UCHAR[size];//分配缓冲区
    if (buffer == NULL)
    {//分配内存失败
        delete[] buffer;
        return; 
    }
    //忽略头部字节
    fseek(fp,fileheader.bfOffBits,0);
    fread(buffer,size,1,fp);

    int i,j;
    
#pragma region 16 color
    // 16色图的解析
    if(info.bmiHeader.biBitCount==4)
    {
        int pitch;
        if(width%8==0)
            pitch=width;
        else
            pitch=width+8-width%8;

        RGBQUAD quad[16];
        fseek(fp,fileheader.bfOffBits-sizeof(RGBQUAD)*16,0);
        fread(quad,sizeof(RGBQUAD)*16,1,fp);

        if(height>0)
        {//height>0 表示图片颠倒
            for(i=0; i<height; i++)
            {
                for(j=0; j<width; j++)
                {
                    int index;
                    if(j%2==0)
                        index = buffer[(i*pitch+j)/2]/16;
                    if(j%2==1)
                        index = buffer[(i*pitch+j)/2]%16;

                    UCHAR r=quad[index].rgbRed;
                    UCHAR g=quad[index].rgbGreen;
                    UCHAR b=quad[index].rgbBlue;
                    pDC->SetPixel(j,height-i,RGB(r,g,b));
                }
            }
        }
        else
        {//图片不颠倒
            for(i=0; i<0-height; i++)
            {
                for(j=0; j<width; j++)
                {
                    int index;
                    if(j%2==0)
                        index = buffer[(i*pitch+j)/2]/16;

                    if(j%2==1)
                        index = buffer[(i*pitch+j)/2]%16;

                    UCHAR r=quad[index].rgbRed;
                    UCHAR g=quad[index].rgbGreen;
                    UCHAR b=quad[index].rgbBlue;
                    pDC->SetPixel(j,i,RGB(r,g,b));
                }
            }
        }
    }
#pragma endregion 16 color

#pragma region 256 color
    // 256色图的解析
    if(info.bmiHeader.biBitCount==8)
    {
        int pitch;
        if(width%4==0)
        {
            pitch=width;
        }
        else
        {
            pitch=width+4-width%4;
        }

        RGBQUAD quad[256];
        fseek(fp,fileheader.bfOffBits-sizeof(RGBQUAD)*256,0);
        fread(quad,sizeof(RGBQUAD)*256,1,fp);

        if(height>0)
        {//height>0 表示图片颠倒
            for(int i=0;i<height;i++)
            {
                for(int j=0;j<width;j++)
                {
                    int index=buffer[i*pitch+j];
                    UCHAR r=quad[index].rgbRed;
                    UCHAR g=quad[index].rgbGreen;
                    UCHAR b=quad[index].rgbBlue;
                    pDC->SetPixel(j,height-i,RGB(r,g,b));
                }
            }
        }
        else
        {
            for(int i=0;i<0-height;i++)
            {
                for(int j=0;j<width;j++)
                {
                    int index=buffer[i*pitch+j];
                    UCHAR r=quad[index].rgbRed;
                    UCHAR g=quad[index].rgbGreen;
                    UCHAR b=quad[index].rgbBlue;
                    pDC->SetPixel(j,i,RGB(r,g,b));
                }
            }
        }
    }
#pragma endregion 256 color

#pragma region 24 bit
    // 24位图解析
    if(info.bmiHeader.biBitCount==24)
    {
        int pitch=width%4;
        // bgr
        if(height>0)
        {//height>0 表示图片颠倒
            for(int i=0;i<height;i++)
            {
                int realPitch=i*pitch;
                for(int j=0;j<width;j++)
                {
                    UCHAR b=buffer[(i*width+j)*3+realPitch];
                    UCHAR g=buffer[(i*width+j)*3+1+realPitch];
                    UCHAR r=buffer[(i*width+j)*3+2+realPitch];
                    pDC->SetPixel(j,height-i,RGB(r,g,b));
                }
            }
        }
        else
        {
            for(int i=0;i<0-height;i++)
            {
                int realPitch=i*pitch;
                for(int j=0;j<width;j++)
                {
                    UCHAR b=buffer[(i*width+j)*3+realPitch];
                    UCHAR g=buffer[(i*width+j)*3+1+realPitch];
                    UCHAR r=buffer[(i*width+j)*3+2+realPitch];
                    pDC->SetPixel(j,i,RGB(r,g,b));
                }
            }
        }
    }
#pragma endregion 24 bit

    this->ReleaseDC(pDC);//释放掉绘制上下文
    delete[] buffer;//释放缓冲区
    fclose(fp); //关闭BMP文件
}
复制代码



本文转自Phinecos(洞庭散人)博客园博客,原文链接:http://www.cnblogs.com/phinecos/archive/2009/05/09/1453205.html,如需转载请自行联系原作者

目录
相关文章
|
5月前
|
计算机视觉 Python
从图像文件中读取并处理
【7月更文挑战第29天】从图像文件中读取并处理。
29 1
|
5月前
|
Python
GIF格式 保存
【7月更文挑战第18天】
73 3
|
5月前
保存网络图片在sdcard两个方法
保存网络图片在sdcard两个方法
45 0
|
7月前
|
编解码
视频I420裸流保存为文件
视频I420裸流保存为文件
*.pvr.ccz文件还原成png格式
*.pvr.ccz文件还原成png格式
228 0
|
大数据 C#
C# 读取大文件 (可以读取3GB大小的txt文件)
原文:C# 读取大文件 (可以读取3GB大小的txt文件) 在处理大数据时,有可能 会碰到 超过3GB大小的文件,如果通过 记事本 或 NotePad++去打开它,会报错,读不到任何文件。
4252 1
CFile读取图片文件Byte
CFile读取图片文件Byte
105 0
RGB数据剪切后保存为JPG格式文件的代码(使用jpeglib)
RGB数据剪切后保存为JPG格式文件的代码(使用jpeglib)
160 0
GSoap根据filename读取图片byte
GSoap根据filename读取图片byte
69 0
|
存储 编解码 C语言
C语言代码创建、解析BMP格式图片
BMP格式的图片是众多图片格式中的一种,也称为位图数据,BMP结构也比较简单,不需要依赖任何外部库,直接手撸几十行代码即可完成解码编码,非常方便。
433 0