BMP的解析

来源:互联网 发布:张卫健打人知乎 编辑:程序博客网 时间:2024/05/16 17:09
Chinaunix首页 | 论坛 | 认证专区 | 博客 登录 | 注册
  

The last one

哎,年纪渐渐大了,很多事情却刚刚开始,记忆力却感觉在下降,写在网上吧,容易找点

  • 互动:数据分析与云计算应用案例 (征集|参与)
  • 有奖讨论:企业网络架构的世界真有“试衣间”
  • 有奖征文:技术自白书之中国架构师 前8有奖!
首页 |  博文目录 |  关于我

pppStar

  • 博客访问: 218457
  • 博文数量: 194
  • 博客积分: 2366
  • 博客等级: 大尉
  • 技术积分: 1378
  • 用 户 组: 普通用户
  • 注册时间: 2007-04-22 09:37
文章分类

全部博文(194)

  • ffmpeg(6)
  • mp4(2)
  • rtsp(7)
  • net program(4)
  • h.264(5)
  • 杂2(5)
  • 生活(6)
  • 杂货铺(25)
  • linux(103)
  • 项目管理(5)
  • C++(19)
  • 未分配的博文(7)
文章存档

2015年(41)

2014年(31)

2013年(54)

2012年(40)

2011年(18)

2010年(10)

我的朋友
  • commshar

  • yuweixia

  • confeng

  • 闪烁Linu

最近访客
  • gooker

  • zylthink

  • 蝎子莱莱

  • 水起风生

  • emos

  • dayerong

  • babysoon

  • __slucx_

  • 十字螺丝

微信关注

IT168企业级官微



微信号:IT168qiye



系统架构师大会



微信号:SACC2013

订阅
推荐博文
  • ·lesson3-Qt对话框
  • ·BLE-NRF51822教程3-sdk程序框...
  • ·Greenplum(GPDB)开源啦!~...
  • ·生命不息,折腾不止
  • ·PostgreSQL不同模式(SCHEMA)...
  • ·sqlplus scott/system@ora10g...
  • ·使用oradebug dump hanganaly...
  • ·oracle em 修改端口
  • ·使用oradebug dump hanganaly...
  • ·使用oradebug dump hanganaly...
热词专题
  • ·python打包指南
  • ·linux定时 关机
  • ·关闭linux铃声
  • ·linux 使用者自订开机启动程...
  • ·欢迎ddwrt01在ChinaUnix博客...
友情链接
  • ·搞安卓的
  • ·比较有经验的人士
  • ·crifan 一定多看看
  • ·网络原理解释
  • ·忘我的追寻--高手, 常去...
  • ·视骏--做h.265, 迅雷看...
  • ·蓝汛-做cdn的
  • ·hevc h.265的一个博客...
  • ·一个做视频质量评价的博客,关...
  • ·GFree_Wind
 bmp文件格式详细解析 2015-09-28 14:32:37

分类: C/C++

原文地址:bmp文件格式详细解析 作者:liliu4239

先区分几个概念:16色和16位色一样吗?
不一样!
颜色位数,即是用多少位字节表示的值,每一位可以表示0和1两值。通常图片的颜色深度,简称色深,就是用位数来表示的,所以,我通常会看到8位色,16位色,24位色和32位色。
而我们在其它地方看到的又是16色,256色,16777216色等等,这些怎么一回事呢? 
16色即代表16种颜色,256色即256种颜色,8位色就是用8个位来表示的颜色,即2的8次方,就是256色,16位色2的16次方,就是65536色,24位即16777216色,32位即4294967296色 
他们之间并不存在转换关系,只有兼容关系,你不可能将红色转换为蓝色,也不可能将一个黑白的图片转换成一个彩色图片,但可以将彩色图片变成黑白图片,就像以前的黑白电视机播放彩色录像始终是黑白的,而彩色电视机播放黑白的录像还是黑白的,当由多到少时,它会丢失颜色数据,当由少到多时,并不会还原丢失的数据。
好了,切入正题:
bmp文件结构解析:
一个bmp图片最多由4大部分组成:BITMAPFILEHEADER结构体,BITMAPINFOHEADER结构体,RGBQUAD结构体(这个结构体可以有,也可以没有),DIB数据区。其中DIB意思就是Device-Independent Bitmap(设备无关位图)。

一个bmp文件以BITMAPFILEHEADER结构体开始,

typedef struct tagBITMAPFILEHEADER {

WORD bfType;//固定为0x4d42;
    DWORD bfSize; //文件大小
    WORD bfReserved1; //保留字,不考虑
    WORD bfReserved2; //保留字,同上
    DWORD bfOffBits; //实际位图数据的偏移字节数,即前三个部分长度之和
    } BITMAPFILEHEADER;

 BITMAPFILEHEADER的第1个属性是bfType(2字节),这里恒定等于0x4D42。由于内存中的数据排列高位在左,低位在右,所以内存中从左往右看就显示成(42 4D),所以在winhex中头两个 字节显示为(42 4D)就是这样形成的,以后的数据都是这个特点,不再作重复说明。

BITMAPFILEHEADER的第2个属性是bfSize(4字节),表示整个bmp文件的大小。

BITMAPFILEHEADER的第3个、第4个属性分别是bfReserved1bfReserved2(2字节),这里是2个保留属性,都为0,这里等于&H00000x0000

BITMAPFILEHEADER的第5个属性是bfOffBits(4字节),表示DIB数据区在bmp文件中的位置偏移量,比如等于0x00000076=118,表示数据区从文件开始往后数的118字节开始。

 BITMAPFILEHEADER结构体这里就讲完了,大家会发现BITMAPFILEHEADER只占了bmp文件开始的14字节长度,但需要 特别说明的是:我们在编程时,经常是以二进制的形式打开一个bmp文件,然后将其开头的14个字节读入自己定义的BITMAPFILEHEADER结构体中,如果按上述定义结构体的方式,需要注意,这个自己定义的结构体在内存中由于字节对齐,会占用16字节的空间,因而直接读入16字节,按字节顺序赋值给结构体,出来的数据是错误的,这样的话,可以先将这14字节的数据读入到一个缓冲器中,然后从缓冲器中按字节对结构体进行赋值。详细程序见后附录。鉴于此中原因,vb中定义一个BITMAPFILEHEADER结构体变量,其长度占了16个字节,原因就是第1个属性本来应该只分配2个字节,但实际被 分配了4个字节,多出来2个字节,所以如果想保存一张bmp图片,写入BITMAPFILEHEADER结构体时一定要注意这一点。

接下来是BITMAPINFO结构体部分。BITMAPINFO段由两部分组成:BITMAPINFOHEADER结构体和RGBQUAD结构 体。其中RGBQUAD结构体表示图片的颜色信息,有些时候可以省略,一般的24位图片和32位图片都不带RGBQUAD结构体,因为DIB数据区直接表 示的RGB值,一般4位图片和8位图片才带有RGBQUAD结构体。(多少位的图片就是用多少位来表示一个颜色信息,例如4位图片表示用4bit来表示 一个颜色信息。)一个bmp文件中有没有RGBQUAD结构体,可以根据前面BITMAPFILEHEADER结构体的第5个属性bfOffBits来判 断,因为BITMAPINFOHEADER结构体长度为40bit,如果BITMAPINFOHEADER结构体结束后还未到DIB数据区的偏移量,就说 明接下来的数据是RGBQUAD结构体部分。

下面进入正题BITMAPINFOHEADER部分。

typedef struct tagBITMAPINFOHEADER{
 //public:
 DWORD biSize; //指定此结构体的长度,为40
 LONG biWidth; //位图宽
 LONG biHeight; //位图高
 WORD biPlanes; //平面数,为1
 WORD biBitCount; //采用颜色位数,可以是1,2,4,8,16,24,新的可以是32
 DWORD biCompression; //压缩方式,可以是0,1,2,其中0表示不压缩
 DWORD biSizeImage; //实际位图数据占用的字节数
 LONG biXPelsPerMeter; //X方向分辨率
 LONG biYPelsPerMeter; //Y方向分辨率
 DWORD biClrUsed; //使用的颜色数,如果为0,则表示默认值(2^颜色位数)
 DWORD biClrImportant; //重要颜色数,如果为0,则表示所有颜色都是重要的
} BITMAPINFOHEADER;

BITMAPINFOHEADER的第1个属性是biSize(4字节),表示BITMAPINFOHEADER结构体的长度,最常见的长度是40字节。

BITMAPINFOHEADER的第2个属性是biWidth(4字节),表示bmp图片的宽度

BITMAPINFOHEADER的第3个属性是biHeight(4字节),表示bmp图片的高度

BITMAPINFOHEADER的第4个属性是biPlanes(2字节),表示bmp图片的平面属,显然显示器只有一个平面,所以恒等于1,这里等于0x0001

BITMAPINFOHEADER的第5个属性是biBitCount(2字节),表示bmp图片的颜色位数,即1位图(单色或二值图像),8位图,16位图,24位图、32位图等等。

BITMAPINFOHEADER的第6个属性是biCompression(4字节),表示图片的压缩属性,bmp图片是不压缩的,等于0,所以这里为0x00000000

BITMAPINFOHEADER的第7个属性是biSizeImage(4字节),表示bmp图片数据区的大小,当上一个数值biCompression等于0时,这里的值可以省略不填,所以这里等于0x00000000

BITMAPINFOHEADER的第8个属性是biXPelsPerMeter(4字节),表示图片X轴每米多少像素,可省略,这里等于0x00000EC3=3779像素/米。

BITMAPINFOHEADER的第9个属性是biYPelsPerMeter(4字节),表示图片Y轴每米多少像素,可省略,这里等于0x00000EC3=3779像素/米。

BITMAPINFOHEADER的第10个属性是biClrUsed(4字节),表示使用了多少个颜色索引表,一般biBitCount属性小于16才会用到,等于0时表示有2^biBitCount个颜色索引表,所以这里仍等于0x00000000

BITMAPINFOHEADER的第11个属性是biClrImportant(4字节),表示有多少个重要的颜色,等于0时表示所有颜色都很重要,所以这里等于0x00000000

至此BITMAPINFOHEADER结构体结束。

由于这个图片到这里还未到达DIB数据区的偏移量,或者说由于BITMAPINFOHEADER的第5个属性是biBitCount<16,也就是在1位图(只有两种颜色),4位图(只有2^4=16种颜色),8位图(只有2^8=256种颜色)的情况下,此时会有颜色表,也就是接下来的部分:RGBQUAD结构体。

//调色板Palette,当然,这里是对那些需要调色板的位图文件而言的。24位和32位是不需要调色板的。
//(调色板结构体个数等于使用的颜色数,即是多少色图就有多少个,4位图16色,就有16个RGBQUAD结构体。)

typedef 
struct tagRGBQUAD {
//public:
BYTE rgbBlue; //该颜色的蓝色分量
BYTE rgbGreen; //该颜色的绿色分量
BYTE rgbRed; //该颜色的红色分量
BYTE rgbReserved; //保留值
} RGBQUAD;

这里举个4位图也就是16色图的例子:一 RGBQUAD结构体只占用4字节空间,从左到右每个字节依次表示(蓝色,绿色,红色,未使用)。举例的这个图片我数了数总共有16RGBQUAD 构体,由于该图片是4位图,2^4正好等于16,所以它把16种颜色全部都枚举出来了,这些颜色就是一个颜色索引表。颜色索引表编号从0开始,总共16 颜色,所以编号为0-15。从winhex中可以看到按照顺序,这16RGBQUAD结构体依次为:

编号:(蓝,绿,红,空)

0号:(00000000)

1号:(00008000)

2号:(00800000)

3号:(00808000)

4号:(80000000)

5号:(80008000)

6号:(80800000)

7号:(80808000)

8号:(C0C0C000)

9号:(0000FF00)

10号:(00FF0000)

11号:(00FFFF00)

12号:(FF000000)

13号:(FF00FF00)

14号:(FFFF0000)

15号:(FFFFFF00)

到这里,正好满足DIB数据区的偏移量,所以后面的字节就是图片内容了。这里需要提醒的是所有的DIB数据扫描行是上下颠倒的,也就是说一幅图片先绘制底部的像素,再绘制顶部的像素,所以这些DIB数据所表示的像素点就是从图片的左下角开始,一直表示到图片的右上角。

 

程序附录:

// std.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"


//ReadBitMap
//
#include 
#include 
#include 
#include 
#include


#define WIDTHBYTES(bits) (((bits)+31)/32*4)

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


//位图文件头信息结构定义
//其中不包含文件类型信息(由于结构体的内存结构决定,要是加了的话将不能正确读取文件信息)

typedef struct tagBITMAPFILEHEADER {

 WORD bfType;//固定为0x4d42
 DWORD bfSize; //文件大小
 WORD bfReserved1; //保留字,不考虑
 WORD bfReserved2; //保留字,同上
 DWORD bfOffBits; //实际位图数据的偏移字节数,即前三个部分长度之和
} BITMAPFILEHEADER;


//信息头BITMAPINFOHEADER,也是一个结构,其定义如下:

typedef struct tagBITMAPINFOHEADER{
 //public:
 DWORD biSize; //指定此结构体的长度,为40
 LONG biWidth; //位图宽
 LONG biHeight; //位图高
 WORD biPlanes; //平面数,为1
 WORD biBitCount; //采用颜色位数,可以是1,2,4,8,16,24,新的可以是32
 DWORD biCompression; //压缩方式,可以是0,1,2,其中0表示不压缩
 DWORD biSizeImage; //实际位图数据占用的字节数
 LONG biXPelsPerMeter; //X方向分辨率
 LONG biYPelsPerMeter; //Y方向分辨率
 DWORD biClrUsed; //使用的颜色数,如果为0,则表示默认值(2^颜色位数)
 DWORD biClrImportant; //重要颜色数,如果为0,则表示所有颜色都是重要的
} BITMAPINFOHEADER;


//调色板Palette,当然,这里是对那些需要调色板的位图文件而言的。24位和32位是不需要调色板的。
//(似乎是调色板结构体个数等于使用的颜色数。)

typedef struct tagRGBQUAD {
 //public:
 BYTE rgbBlue; //该颜色的蓝色分量
 BYTE rgbGreen; //该颜色的绿色分量
 BYTE rgbRed; //该颜色的红色分量
 BYTE rgbReserved; //保留值
} RGBQUAD;

 

void showBmpHead(BITMAPFILEHEADER* pBmpHead)
{
 printf("位图文件头:\n");
 printf("bmp格式标志bftype:0x%x\n",pBmpHead->bfType );
 printf("文件大小:%d\n",pBmpHead->bfSize);
 printf("保留字:%d\n",pBmpHead->bfReserved1);
 printf("保留字:%d\n",pBmpHead->bfReserved2);
 printf("实际位图数据的偏移字节数:%d\n",pBmpHead->bfOffBits);

}


void showBmpInforHead(tagBITMAPINFOHEADER* pBmpInforHead)
{
 printf("位图信息头:\n");
 printf("结构体的长度:%d\n",pBmpInforHead->biSize);
 printf("位图宽:%d\n",pBmpInforHead->biWidth);
 printf("位图高:%d\n",pBmpInforHead->biHeight);
 printf("biPlanes平面数:%d\n",pBmpInforHead->biPlanes);
 printf("biBitCount采用颜色位数:%d\n",pBmpInforHead->biBitCount);
 printf("压缩方式:%d\n",pBmpInforHead->biCompression);
 printf("biSizeImage实际位图数据占用的字节数:%d\n",pBmpInforHead->biSizeImage);
 printf("X方向分辨率:%d\n",pBmpInforHead->biXPelsPerMeter);
 printf("Y方向分辨率:%d\n",pBmpInforHead->biYPelsPerMeter);
 printf("使用的颜色数:%d\n",pBmpInforHead->biClrUsed);
 printf("重要颜色数:%d\n",pBmpInforHead->biClrImportant);
}

void showRgbQuan(tagRGBQUAD* pRGB)
{
 printf("(%-3d,%-3d,%-3d) ",pRGB->rgbRed,pRGB->rgbGreen,pRGB->rgbBlue);

}

 

void main()
{

 BITMAPFILEHEADER bitHead;
 BITMAPINFOHEADER bitInfoHead;
 FILE* pfile;

 char strFile[50];
 char *BmpFileHeader;
 WORD *temp_WORD;
 DWORD *temp_DWORD;
 printf("please input the .bmp file name:\n");
 scanf("%s",strFile);
 
 pfile = fopen(strFile,"rb");//打开文件
    BmpFileHeader=(char *)calloc(14,sizeof(char));
 if(pfile!=NULL)
 {
  printf("file bkwood.bmp open success.\n");
  //读取位图文件头信息
  
  
  
  fread(BmpFileHeader,1,14,pfile);
  temp_WORD=(WORD* )(BmpFileHeader);
  bitHead.bfType=*temp_WORD;
  if(bitHead.bfType != 0x4d42)
  {
   printf("file is not .bmp file!");
   
   return;
  }
  temp_DWORD=(DWORD *)(BmpFileHeader+sizeof(bitHead.bfType));
  bitHead.bfSize=*temp_DWORD;
  temp_WORD=(WORD*)(BmpFileHeader+sizeof(bitHead.bfType)+sizeof(bitHead.bfSize));
  bitHead.bfReserved1=*temp_WORD;
  temp_WORD=(WORD*)(BmpFileHeader+sizeof(bitHead.bfType)+sizeof(bitHead.bfSize)+sizeof(bitHead.bfReserved1));
  bitHead.bfReserved2=*temp_WORD;
  temp_DWORD=(DWORD*)(BmpFileHeader+sizeof(bitHead.bfType)+sizeof(bitHead.bfSize)+sizeof(bitHead.bfReserved1)+sizeof(bitHead.bfReserved2));
  bitHead.bfOffBits=*temp_DWORD;
 
  
  
  showBmpHead(&bitHead);
  printf("\n\n");
 
  //读取位图信息头信息
  fread(&bitInfoHead,1,sizeof(BITMAPINFOHEADER),pfile);
  showBmpInforHead(&bitInfoHead);
  printf("\n");
  
 }
 else
 {
  printf("file open fail!\n");
  return;
 }
 
 tagRGBQUAD *pRgb ;

 if(bitInfoHead.biBitCount < 24)//有调色板
 {
  //读取调色盘结信息
  long nPlantNum = long(pow(2,double(bitInfoHead.biBitCount))); // Mix color Plant Number;
  pRgb=(tagRGBQUAD *)malloc(nPlantNum*sizeof(tagRGBQUAD));
  memset(pRgb,0,nPlantNum*sizeof(tagRGBQUAD));
  int num = fread(pRgb,4,nPlantNum,pfile);

  printf("Color Plate Number: %d\n",nPlantNum);

  printf("颜色板信息:\n");
  for (int i =0; i<nplantnum;i++)
  {
   if (i%5==0)
   {
    printf("\n");
   }
   showRgbQuan(&pRgb[i]);

  }

  printf("\n");

 }


 int width = bitInfoHead.biWidth;
 int height = bitInfoHead.biHeight;
 //分配内存空间把源图存入内存
 int l_width = WIDTHBYTES(width* bitInfoHead.biBitCount);//计算位图的实际宽度并确保它为32的倍数
 BYTE *pColorData=(BYTE *)malloc(height*l_width);
 memset(pColorData,0,height*l_width);
 long nData = height*l_width;

 //把位图数据信息读到数组里
 fread(pColorData,1,nData,pfile);

 

 //将位图数据转化为RGB数据
 tagRGBQUAD* dataOfBmp;
 dataOfBmp = (tagRGBQUAD *)malloc(width*height*sizeof(tagRGBQUAD));//用于保存各像素对应的RGB数据
 memset(dataOfBmp,0,width*height*sizeof(tagRGBQUAD));

 if(bitInfoHead.biBitCount<24)//有调色板,即位图为非真彩色
 {
  int k;
  int index = 0;
  if (bitInfoHead.biBitCount == 1)
  {
   for(int i=0;i<height;i++)
    for(int j=0;j<width;j++)
    {
     BYTE mixIndex= 0;
     k = i*l_width + j/8;//k:取得该像素颜色数据在实际数据数组中的序号
     //j:提取当前像素的颜色的具体值
     mixIndex = pColorData[k];
     switch(j%8)
     {
     case 0:
      mixIndex = mixIndex<<7;
      mixIndex = mixIndex>>7;
      break;
     case 1:
      mixIndex = mixIndex<<6;
      mixIndex = mixIndex>>7;
      break;
     case 2:
      mixIndex = mixIndex<<5;
      mixIndex = mixIndex>>7;
      break;

     case 3:
      mixIndex = mixIndex<<4;
      mixIndex = mixIndex>>7;
      break;
     case 4:
      mixIndex = mixIndex<<3;
      mixIndex = mixIndex>>7;
      break;

     case 5:
      mixIndex = mixIndex<<2;
      mixIndex = mixIndex>>7;
      break;
     case 6:
      mixIndex = mixIndex<<1;
      mixIndex = mixIndex>>7;
      break;

     case 7:
      mixIndex = mixIndex>>7;
      break;
     }

     //将像素数据保存到数组中对应的位置
     dataOfBmp[index].rgbRed = pRgb[mixIndex].rgbRed;
     dataOfBmp[index].rgbGreen = pRgb[mixIndex].rgbGreen;
     dataOfBmp[index].rgbBlue = pRgb[mixIndex].rgbBlue;
     dataOfBmp[index].rgbReserved = pRgb[mixIndex].rgbReserved;
     index++;

    }
  }

  if(bitInfoHead.biBitCount==2)
  {
   for(int i=0;i<height;i++)
    for(int j=0;j<width;j++)
    {
     BYTE mixIndex= 0;
     k = i*l_width + j/4;//k:取得该像素颜色数据在实际数据数组中的序号
     //j:提取当前像素的颜色的具体值
     mixIndex = pColorData[k];
     switch(j%4)
     {
     case 0:
      mixIndex = mixIndex<<6;
      mixIndex = mixIndex>>6;
      break;
     case 1:
      mixIndex = mixIndex<<4;
      mixIndex = mixIndex>>6;
      break;
     case 2:
      mixIndex = mixIndex<<2;
      mixIndex = mixIndex>>6;
      break;
     case 3:
      mixIndex = mixIndex>>6;
      break;
     }

     //将像素数据保存到数组中对应的位置
     dataOfBmp[index].rgbRed = pRgb[mixIndex].rgbRed;
     dataOfBmp[index].rgbGreen = pRgb[mixIndex].rgbGreen;
     dataOfBmp[index].rgbBlue = pRgb[mixIndex].rgbBlue;
     dataOfBmp[index].rgbReserved = pRgb[mixIndex].rgbReserved;
     index++;


    }
  }
  if(bitInfoHead.biBitCount == 4)
  {
   for(int i=0;i<height;i++)
    for(int j=0;j<width;j++)
    {
     BYTE mixIndex= 0;
     k = i*l_width + j/2;
     mixIndex = pColorData[k];
     if(j%2==0)
     {//低
      mixIndex = mixIndex<<4;
      mixIndex = mixIndex>>4;
     }
     else
     {//高
      mixIndex = mixIndex>>4;
     }

     dataOfBmp[index].rgbRed = pRgb[mixIndex].rgbRed;
     dataOfBmp[index].rgbGreen = pRgb[mixIndex].rgbGreen;
     dataOfBmp[index].rgbBlue = pRgb[mixIndex].rgbBlue;
     dataOfBmp[index].rgbReserved = pRgb[mixIndex].rgbReserved;
     index++;

    }

  }
  if(bitInfoHead.biBitCount == 8)
  {
   for(int i=0;i<height;i++)
    for(int j=0;j<width;j++)
    {
     BYTE mixIndex= 0;

     k = i*l_width + j;

     mixIndex = pColorData[k];

     dataOfBmp[index].rgbRed = pRgb[mixIndex].rgbRed;
     dataOfBmp[index].rgbGreen = pRgb[mixIndex].rgbGreen;
     dataOfBmp[index].rgbBlue = pRgb[mixIndex].rgbBlue;
     dataOfBmp[index].rgbReserved = pRgb[mixIndex].rgbReserved;
     index++;

 

    }
  }
  if(bitInfoHead.biBitCount == 16)
  {
   for(int i=0;i<height;i++)
    for(int j=0;j<width;j++)
    {
     WORD mixIndex= 0;

     k = i*l_width + j*2;
     WORD shortTemp;
     shortTemp = pColorData[k+1];
     shortTemp = shortTemp<<8;

     mixIndex = pColorData[k] + shortTemp;

     dataOfBmp[index].rgbRed = pRgb[mixIndex].rgbRed;
     dataOfBmp[index].rgbGreen = pRgb[mixIndex].rgbGreen;
     dataOfBmp[index].rgbBlue = pRgb[mixIndex].rgbBlue;
     dataOfBmp[index].rgbReserved = pRgb[mixIndex].rgbReserved;
     index++;
    }
  }
 }
 else//位图为24位真彩色
 {
  int k;
  int index = 0;
  for(int i=0;i<height;i++)
   for(int j=0;j<width;j++)
   {
    k = i*l_width + j*3;
    dataOfBmp[index].rgbRed = pColorData[k+2];
    dataOfBmp[index].rgbGreen = pColorData[k+1];
    dataOfBmp[index].rgbBlue = pColorData[k];
    index++;
   }
 }


 printf("像素数据信息:\n");
/*
 for (int i=0; i<width*height; i++)
 {
  if (i%5==0)
  {
   printf("\n");
  }
  showRgbQuan(&dataOfBmp[i]);
 }
*/
 fclose(pfile);
 
 if (bitInfoHead.biBitCount<24)
 {
  free(pRgb);
 }

 free(dataOfBmp);
 free(pColorData);
   free(BmpFileHeader);
 printf("\n");

} 

阅读(3) | 评论(0) | 转发(0) |
0

上一篇:fb_var_screeninfo解析

下一篇:外国人uboot

相关热门文章
  • error LNK2019: 无法解析的外...
  • Linux 下svn恢复到某一版本...
  • Android JSON数据解析
  • Tornado源码阅读总览
  • Linux 日志分析工具之AWStats...
  • test123
  • 编写安全代码——小心有符号数...
  • 使用openssl api进行加密解密...
  • 一段自己打印自己的c程序...
  • sql relay的c++接口
  • linux dhcp peizhi roc
  • 关于Unix文件的软链接
  • 求教这个命令什么意思,我是新...
  • sed -e "/grep/d" 是什么意思...
  • 谁能够帮我解决LINUX 2.6 10...
给主人留下些什么吧!~~
评论热议
请登录后评论。

登录 注册


<iframe id="cproIframe_u1625692_1" width="468" height="60" src="http://pos.baidu.com/acom?adn=2&amp;at=225&amp;aurl=&amp;cad=1&amp;ccd=32&amp;cec=UTF-8&amp;cfv=18&amp;ch=0&amp;col=zh-CN&amp;conBW=0&amp;conOP=1&amp;cpa=1&amp;dai=1&amp;dis=0&amp;layout_filter=image&amp;ltr=https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3Dg6mQ_JY_4pu5_bOe5PMx2TDulSRcos5rgUBb7q9PefwM-ct-2e2nQIlloyVlHUG3wvX_HW6AHEYYNWm3z1go4_%26wd%3D%26eqid%3Df705906d000c453c0000000256414ecc&amp;ltu=http%3A%2F%2Fblog.chinaunix.net%2Fuid-20554957-id-5208037.html&amp;lu_161=6&amp;lunum=6&amp;n=01084029_cpr&amp;pcs=1349x579&amp;pis=10000x10000&amp;ps=13536x305&amp;psr=1366x768&amp;pss=1349x13536&amp;qn=0c22b1f76a86288f&amp;rad=&amp;rsi0=468&amp;rsi1=60&amp;rsi5=4&amp;rss0=%23FFFFFF&amp;rss1=%23FFFFFF&amp;rss2=%230000ff&amp;rss3=%23444444&amp;rss4=%23008000&amp;rss5=&amp;rss6=%23e10900&amp;rss7=&amp;scale=&amp;skin=tabcloud_skin_3&amp;stid=5&amp;td_id=1625692&amp;titFF=%E5%AE%8B%E4%BD%93&amp;titFS=12&amp;titTA=left&amp;tn=text_default_468_60&amp;tpr=1447120726193&amp;ts=1&amp;version=2.0&amp;xuanting=0&amp;dtm=BAIDU_DUP2_SETJSONADSLOT&amp;dc=2&amp;di=u1625692&amp;ti=bmp%E6%96%87%E4%BB%B6%E6%A0%BC%E5%BC%8F%E8%AF%A6%E7%BB%86%E8%A7%A3%E6%9E%90-pppStar-ChinaUnix%E5%8D%9A%E5%AE%A2&amp;tt=1447120726130.63.234.250" align="center,center" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" allowtransparency="true" style="word-wrap: break-word;"></iframe>
<iframe id="cproIframe_u1625694_2" width="468" height="60" src="http://pos.baidu.com/acom?adn=2&amp;at=71&amp;aurl=&amp;cad=1&amp;ccd=32&amp;cec=UTF-8&amp;cfv=18&amp;ch=0&amp;col=zh-CN&amp;conOP=0&amp;cpa=1&amp;dai=2&amp;dis=0&amp;ltr=https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3Dg6mQ_JY_4pu5_bOe5PMx2TDulSRcos5rgUBb7q9PefwM-ct-2e2nQIlloyVlHUG3wvX_HW6AHEYYNWm3z1go4_%26wd%3D%26eqid%3Df705906d000c453c0000000256414ecc&amp;ltu=http%3A%2F%2Fblog.chinaunix.net%2Fuid-20554957-id-5208037.html&amp;lunum=6&amp;n=01084029_cpr&amp;pcs=1349x579&amp;pis=10000x10000&amp;ps=13536x245&amp;psr=1366x768&amp;pss=1349x13596&amp;qn=54ad90798a6f6143&amp;rad=&amp;rsi0=468&amp;rsi1=60&amp;rsi5=4&amp;rss0=%23FFFFFF&amp;rss1=%23FFFFFF&amp;rss2=%230000FF&amp;rss3=%23444444&amp;rss4=%23008000&amp;rss5=&amp;rss6=%23e10900&amp;rss7=&amp;scale=&amp;skin=&amp;td_id=1625694&amp;tn=text_default_468_60&amp;tpr=1447120726193&amp;ts=1&amp;version=2.0&amp;xuanting=0&amp;dtm=BAIDU_DUP2_SETJSONADSLOT&amp;dc=2&amp;di=u1625694&amp;ti=bmp%E6%96%87%E4%BB%B6%E6%A0%BC%E5%BC%8F%E8%AF%A6%E7%BB%86%E8%A7%A3%E6%9E%90-pppStar-ChinaUnix%E5%8D%9A%E5%AE%A2&amp;tt=1447120726130.297.375.375" align="center,center" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" allowtransparency="true" style="word-wrap: break-word;"></iframe>
0 0