C++语言基础 例程 案例:bmp文件格式剖析

简介: 贺老师的教学链接  本课讲解附:二进制文件查看器及示例bmp文件 http://pan.baidu.com/s/1dDjf5uD用程序读出BMP文件信息//readbmp.h#ifndef READBMP_H_INCLUDED#define READBMP_H_INCLUDEDtypedef unsigned char BYTE;typedef unsigned shor

贺老师的教学链接  本课讲解


附:二进制文件查看器及示例bmp文件 http://pan.baidu.com/s/1dDjf5uD


用程序读出BMP文件信息

//readbmp.h
#ifndef READBMP_H_INCLUDED
#define READBMP_H_INCLUDED

typedef unsigned char BYTE;
typedef unsigned short int UINT;
typedef short int WORD;
typedef int DWORD;
typedef long LONG;

typedef struct tagBITMAPFILEHEADER
{
    UINT bfType; /*说明文件的类型*/
    DWORD bfSize; /*说明文件的大小*/
    UINT bfReserved1; /*保留,设置为0 */
    UINT bfReserved2; /*保留,设置为0*/
    DWORD bfOffBits; /*到图像数据的偏移量*/
} BITMAPFILEHEADER;

typedef struct tagBITMAPINFOHEADER
{
    DWORD biSize; /*BITMAPINFOHEADER结构所需要的字节数*/
    LONG biWidth; /*图像的宽度,以像素为单位*/
    LONG biHeight; /*图像的高度,以像素为单位*/
    WORD biPlanes; /*为目标设备说明位面数,其值设置为1*/
    WORD biBitCount; /*位数/像素*/
    DWORD biCompression; /*图像数据压缩的类型:不压缩,或4/8位RLE */
    DWORD biSizeImage; /*图像的大小,以字节为单位。*/
    LONG biXPelsPerMeter; /*水平分辨率,用像素/米表示*/
    LONG biYPelsPerMeter; /*垂直分辨率,用像素/米表示*/
    DWORD biClrUsed; /*位图使用的彩色表中的颜色索引数:2/16/256/224*/
    DWORD biClrImportant; /*对图像显示有重要影响的颜色索引的数目,如果是0,表示都重要*/
} BITMAPINFOHEADER;


typedef struct tagRGBQUAD   /* rgbq */
{
    BYTE rgbBlue; /*指定蓝色强度*/
    BYTE rgbGreen; /*指定绿色强度*/
    BYTE rgbRed; /*指定红色强度*/
    BYTE rgbReserved; /*保留,设置为0 */
} RGBQUAD;

typedef struct tagBITMAPINFO
{
    BITMAPINFOHEADER bmiHeader; // 位图信息头
    RGBQUAD bmiColors[16]; // 颜色表
} BITMAPINFO;

//像素信息
typedef unsigned char IMAGEDATA;

#endif // READBMP_H_INCLUDED

//main.cpp
#include "readbmp.h"
#include <cstdlib>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <fstream>
using namespace std;

//变量定义
BITMAPFILEHEADER bmpHeader;   //文件头
BITMAPINFOHEADER bmpInfoHeader;     //文件信息头
RGBQUAD *colorTable; //彩色表
IMAGEDATA *bmpData;

int main() 
{
    char bmpFileName[80]="bmp16bit.bmp";//bmp文件名
    ifstream bmpFile(bmpFileName, ios::in|ios::binary);
    if(!bmpFile)
    {
        cerr<<"open error!"<<endl;
        exit(1);//退出程序
    }
    /* 读出位图头 */
    //由于“内存对齐问题(这部分为14字节),无法一次性读入所有信息,此处逐个取出成员
    bmpFile.read((char*)&bmpHeader.bfType, sizeof(bmpHeader.bfType));
    bmpFile.read((char*)&bmpHeader.bfSize, sizeof(bmpHeader.bfSize));
    bmpFile.read((char*)&bmpHeader.bfReserved1, sizeof(bmpHeader.bfReserved1));
    bmpFile.read((char*)&bmpHeader.bfReserved1, sizeof(bmpHeader.bfReserved2));
    bmpFile.read((char*)&bmpHeader.bfOffBits, sizeof(bmpHeader.bfOffBits));
    /* 显示位图头 */
    if(0x4d42!=bmpHeader.bfType)  //前两个字符BM,其ASCII码合成0x4d42,应该是固定的
    {
        cerr<<"not a bmp file!"<<endl;
        exit(1);
    }
    cout<<"位图文件头:"<<endl;
    cout<<"文件类型: BM"<<endl;
    cout<<"文件大小:"<<hex<<bmpHeader.bfSize<<endl;  //hex:用16进制输出
    cout<<"保留字_1:"<<bmpHeader.bfReserved1<<endl;
    cout<<"保留字_2:"<<bmpHeader.bfReserved2<<endl;
    cout<<"实际位图数据的偏移字节数:"<<hex<<bmpHeader.bfOffBits<<endl<<endl;

    /* 读出位图信息 */
    bmpFile.read((char*)&bmpInfoHeader, sizeof(bmpInfoHeader));
    /* 显示位图信息 */
    cout<<"位图信息头:"<<endl;
    cout<<"结构体的长度:"<<bmpInfoHeader.biSize<<endl;
    cout<<"位图宽:"<<bmpInfoHeader.biWidth<<endl;
    cout<<"位图高:"<<bmpInfoHeader.biHeight<<endl;
    cout<<"biPlanes平面数:"<<bmpInfoHeader.biPlanes<<endl;
    cout<<"biBitCount采用颜色位数:"<<bmpInfoHeader.biBitCount<<endl;
    cout<<"压缩方式:"<<bmpInfoHeader.biCompression<<endl;
    cout<<"biSizeImage实际位图数据占用的字节数:"<<bmpInfoHeader.biSizeImage<<endl;
    cout<<"X方向分辨率:"<<bmpInfoHeader.biXPelsPerMeter<<endl;
    cout<<"Y方向分辨率:"<<bmpInfoHeader.biYPelsPerMeter<<endl;
    cout<<"使用的颜色数:"<<bmpInfoHeader.biClrUsed<<endl;
    cout<<"重要颜色数:"<<bmpInfoHeader.biClrImportant<<endl<<endl;

    /*biClrUsed指定本图象实际用到的颜色数,如果该值为零,则用到的颜色数为2^biBitCount*/
    int colorNum = bmpInfoHeader.biClrUsed;
    if(0==colorNum)
    {
        colorNum = pow(2, bmpInfoHeader.biBitCount);
    }
    colorTable = new RGBQUAD[colorNum];

    /* 读取彩色表并显示  */
    cout<<"所用颜色(R:G:B)"<<endl;
    int i;
    for(i=0; i<colorNum; i++)
    {
        bmpFile.read((char*)&colorTable[i].rgbBlue, 1);
        bmpFile.read((char*)&colorTable[i].rgbGreen, 1);
        bmpFile.read((char*)&colorTable[i].rgbRed, 1);
        bmpFile.read((char*)&colorTable[i].rgbReserved, 1);
        cout<<dec<<"["<<i<<"]="<<hex<<int(colorTable[i].rgbRed);
        cout<<":"<<int(colorTable[i].rgbGreen);
        cout<<":"<<int(colorTable[i].rgbBlue)<<endl;
    }
    cout<<endl;

    /*读取像素信息*/
    bmpData = new unsigned char[bmpInfoHeader.biSizeImage];
    bmpFile.read((char*)bmpData, bmpInfoHeader.biSizeImage);

    /显示像素信息:下面的显示只提取了数据。BMP中的像素信息是从右上到左上存储,在显示图像时还需要要做处理*/
    /*牵涉到每像素几位-bmpInfoHeader.biBitCount-的问题,下面的代码,有点小绕*/
    int w, h;
    cout<<"下面是像素信息:"<<endl;
    for(h=0; h<bmpInfoHeader.biHeight; ++h)
    {
        cout<<"["<<setw(2)<<h<<"]: ";
        for(w=0; w < bmpInfoHeader.biSizeImage / bmpInfoHeader.biHeight; ++w)
        {
            cout<<setw(2)<<int(*(bmpData+h*bmpInfoHeader.biHeight*bmpInfoHeader.biBitCount/8+w))<<" ";
        }
        cout<<endl;
    }
    /*本程序只读出了位图信息,要显示出来,需要调用输出设备的功能了,此处略过*/
    delete[] bmpData;
    delete[] colorTable;
    return 0;
}


目录
相关文章
|
6月前
|
C++ Windows
.NET Framework安装不成功,下载`NET Framework 3.5`文件,Microsoft Visual C++
.NET Framework常见问题及解决方案汇总,涵盖缺失组件、安装失败、错误代码等,提供多种修复方法,包括全能王DLL修复工具、微软官方运行库及命令行安装等,适用于Windows系统,解决应用程序无法运行问题。
697 3
|
10月前
|
存储 负载均衡 算法
基于 C++ 语言的迪杰斯特拉算法在局域网计算机管理中的应用剖析
在局域网计算机管理中,迪杰斯特拉算法用于优化网络路径、分配资源和定位故障节点,确保高效稳定的网络环境。该算法通过计算最短路径,提升数据传输速率与稳定性,实现负载均衡并快速排除故障。C++代码示例展示了其在网络模拟中的应用,为企业信息化建设提供有力支持。
285 15
|
5月前
|
存储 C++
C++语言中指针变量int和取值操作ptr详细说明。
总结起来,在 C++ 中正确理解和运用 int 类型地址及其相关取值、设定等操纵至关重要且基础性强:定义 int 类型 pointer 需加星号;初始化 pointer 需配合 & 取址;读写 pointer 执向之处需配合 * 解引用操纵进行。
487 12
|
10月前
|
存储 算法 安全
企业员工数据泄露防范策略:基于 C++ 语言的布隆过滤器算法剖析[如何防止员工泄密]
企业运营过程中,防范员工泄密是信息安全领域的核心议题。员工泄密可能致使企业核心数据、商业机密等关键资产的流失,进而给企业造成严重损失。为应对这一挑战,借助恰当的数据结构与算法成为强化信息防护的有效路径。本文专注于 C++ 语言中的布隆过滤器算法,深入探究其在防范员工泄密场景中的应用。
227 8
|
10月前
|
安全 C++
【c++】继承(继承的定义格式、赋值兼容转换、多继承、派生类默认成员函数规则、继承与友元、继承与静态成员)
本文深入探讨了C++中的继承机制,作为面向对象编程(OOP)的核心特性之一。继承通过允许派生类扩展基类的属性和方法,极大促进了代码复用,增强了代码的可维护性和可扩展性。文章详细介绍了继承的基本概念、定义格式、继承方式(public、protected、private)、赋值兼容转换、作用域问题、默认成员函数规则、继承与友元、静态成员、多继承及菱形继承问题,并对比了继承与组合的优缺点。最后总结指出,虽然继承提高了代码灵活性和复用率,但也带来了耦合度高的问题,建议在“has-a”和“is-a”关系同时存在时优先使用组合。
520 6
|
存储 算法 安全
基于哈希表的文件共享平台 C++ 算法实现与分析
在数字化时代,文件共享平台不可或缺。本文探讨哈希表在文件共享中的应用,包括原理、优势及C++实现。哈希表通过键值对快速访问文件元数据(如文件名、大小、位置等),查找时间复杂度为O(1),显著提升查找速度和用户体验。代码示例展示了文件上传和搜索功能,实际应用中需解决哈希冲突、动态扩容和线程安全等问题,以优化性能。
|
11月前
|
编译器 C++ 开发者
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。
|
9月前
|
编译器 C++ 容器
【c++11】c++11新特性(上)(列表初始化、右值引用和移动语义、类的新默认成员函数、lambda表达式)
C++11为C++带来了革命性变化,引入了列表初始化、右值引用、移动语义、类的新默认成员函数和lambda表达式等特性。列表初始化统一了对象初始化方式,initializer_list简化了容器多元素初始化;右值引用和移动语义优化了资源管理,减少拷贝开销;类新增移动构造和移动赋值函数提升性能;lambda表达式提供匿名函数对象,增强代码简洁性和灵活性。这些特性共同推动了现代C++编程的发展,提升了开发效率与程序性能。
356 12
|
7月前
|
人工智能 机器人 编译器
c++模板初阶----函数模板与类模板
class 类模板名private://类内成员声明class Apublic:A(T val):a(val){}private:T a;return 0;运行结果:注意:类模板中的成员函数若是放在类外定义时,需要加模板参数列表。return 0;
194 0
|
7月前
|
存储 编译器 程序员
c++的类(附含explicit关键字,友元,内部类)
本文介绍了C++中类的核心概念与用法,涵盖封装、继承、多态三大特性。重点讲解了类的定义(`class`与`struct`)、访问限定符(`private`、`public`、`protected`)、类的作用域及成员函数的声明与定义分离。同时深入探讨了类的大小计算、`this`指针、默认成员函数(构造函数、析构函数、拷贝构造、赋值重载)以及运算符重载等内容。 文章还详细分析了`explicit`关键字的作用、静态成员(变量与函数)、友元(友元函数与友元类)的概念及其使用场景,并简要介绍了内部类的特性。
297 0