• BMP文件的读取


    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文件
  • 相关阅读:
    巴科斯范式和sql语言
    mysql 视图
    1503
    mysql SQL_CALC_FOUND_ROWS
    create table xxx as select 与 create table xxx like
    mysql 1030 Got error 28 from storage engine
    python -- 装饰器入门
    12C新特性 -- 共享asm口令文件
    MySQL子查询的优化
    MySQL的explain
  • 原文地址:https://www.cnblogs.com/tianlangshu/p/1989427.html
Copyright © 2020-2023  润新知