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,如需转载请自行联系原作者

目录
相关文章
|
Java API 图形学
JAVA读取EMF文件并转化为PNG,JPG,GIF格式
JAVA读取EMF文件并转化为PNG,JPG,GIF格式 使用第三方库下载地址为:http://java.freehep.org/vectorgraphics/index.html 主要思路: 使用EMFInputStream读取EMF文件,然后使用EMFRenderer对象将EMF绘制到创建 好的空白的BufferedImage里面。
1994 0
|
9月前
|
计算机视觉
将TIF图像格式转化为PNG或者JPG格式
安装好cv2库,如果没有安装,请使用pip install opencv-python进行安装。
124 0
*.pvr.ccz文件还原成png格式
*.pvr.ccz文件还原成png格式
155 0
CFile读取图片文件Byte
CFile读取图片文件Byte
83 0
RGB数据剪切后保存为JPG格式文件的代码(使用jpeglib)
RGB数据剪切后保存为JPG格式文件的代码(使用jpeglib)
140 0
GSoap根据filename读取图片byte
GSoap根据filename读取图片byte
53 0
|
存储 编解码 C语言
C语言代码创建、解析BMP格式图片
BMP格式的图片是众多图片格式中的一种,也称为位图数据,BMP结构也比较简单,不需要依赖任何外部库,直接手撸几十行代码即可完成解码编码,非常方便。
353 0
|
存储 编解码 容器
FFmpeg 读取视频流并保存为BMP
FFmpeg 读取视频流并保存为BMP 简介 基本概念 在演示如何读取视频文件之前,应先了解几个关于视频流的概念: 容器(Container): 视频文件本身就叫容器,容器的类型(比如AVI、MP4)决定了视频信息如何存储。
2885 0
|
存储 C++ Windows
浅析BMP位图文件结构(含Demo)
浅析BMP位图文件结构(含Demo) 作者:一点一滴的Beer http://beer.cnblogs.com/       关于BMP位图格式在网上可以找到比较详细的相关文档,有兴趣的可以搜索标题为“BMP文件结构的探索”的文章,可以在搜索结果中找到一个WORD文档,里面有很详细的介绍。
1002 0

热门文章

最新文章