BMP文件读写笔记

1 typedef struct
2 {
3     unsigned char rgbBlue; //该颜色的蓝色分量  
4     unsigned char rgbGreen; //该颜色的绿色分量  
5     unsigned char rgbRed; //该颜色的红色分量  
6     unsigned char rgbReserved; //保留值  
7 } ClRgbQuad;

八戒备,你说,一生一世那短暂,原来当你发觉所好之,就活该不顾一切的夺追求,因为身随时都见面停,命运是海洋,当您能畅游的时,你就是尽情游于而的所爱,因为你免知道什么时候狂流会到来,绻走一切,希望以及企盼。

E007 为 07E0h = 0000 0111 1110 0000(二进制),是绿色分量的掩码。

悟空,你说师傅,请不要让我悟空,请让我悟不空,我手中的金箍棒是以争取好之肆意。要费永远都放,要鸟永远会展翅,要圣洁的恒久天真,要欣赏的恒久爱。可是我又得了金箍圈。它又受自身错过人身自由。

1、写8bit位图

你当西游路上寻找什么?你私自不晓。一人同马没有在古道之中。这是您当时选取的路也?为了信念让在差不多之劳苦吗值得也?喜欢你,所以重视你的挑。你的故事以切年后还代代相传,激励后人,走自己相应倒之路途。

4、各图数据**

金山寺 500年后

typedef   struct   tagBITMAPINFOHEADER{ 
DWORD   biSize;   //   本结构所占据字节数 
LONGbiWidth;   //   位图的宽窄,以像素为单位 
LONGbiHeight;   //   位图的可观,以像素为单位 
WORD   biPlanes;   //   目标设备的级别,必须也1 
WORD   biBitCount//   每个像素所要的位数,必须是1(双色), 
//   4(16色),8(256色)或24(真彩色)之一 
DWORD   biCompression;   //   位图压缩类型,必须是   0(不减), 
//   1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一 
DWORD   biSizeImage;   //   位图的分寸,以字节为单位 
LONGbiXPelsPerMeter;   //   位图水平分辨率,每米像素数 
LONGbiYPelsPerMeter;   //   位图垂直分辨率,每米像素数 
DWORD   biClrUsed;//   位图实际使用的水彩表中的水彩数 
DWORD   biClrImportant;//   位图显示过程中重点的水彩数 
}   BITMAPINFOHEADER; 

你说,你永远无法用言语来描述一发树得长,一朵花之全貌,你说,生命的意思是呀?请不要就此言语来报自己。

  • bmp文件头(bmp file header)提供文件之格式、大小等信息
  • 员图信息头(bitmap
    information)供图像数据的尺寸、位平面数、压缩方式、颜色索引等消息
  • 调色板(color
    palette):可选,如使用索引来代表图像,调色板就是索引与那对应之颜色的映射表
  •  各图数据(bitmap data)哪怕图像数据啦

啊师也而所动,八戒,当你说出:我则是猪,但自呢无随便你们宰的时节,位置心里特别难过,你自我还是深受数所摆来的丁,我回忆你宰割被贬下凡前的泪雨:你呀时都是那么美。为师会召开的吗就算是当你冷静看正在月亮的时段,不会见吃悟空打扰您。因为打扰一个心中正以流泪的食指是当太残忍。

其二组织定义如下: 
typedef   struct   tagBITMAPFILEHEADER 

WORDbfType;   //   位图文件的类别,必须也BM 
DWORD   bfSize;   //   位图文件的轻重,以字节为单位   
WORDbfReserved1;   //   位图文件保留字,必须为0 
WORDbfReserved2;   //   位图文件保留字,必须也0 
DWORD   bfOffBits;   //   位图数据的开场位置,以相对于各图 
//   文件头之偏移量表示,以字节为单位 
}   BITMAPFILEHEADER; 

悟空,你说你无理解干什么而因去而忧心忡忡,为什么以时刻短暂而令人担忧。你如找到那力量,让具备的身都超过界限,让抱有的花又又世上开花,让想竟的就可知随便飞翔,让所有的人数以及他们爱的永远当共。

 

西游路上,你对非议,沉默不语。是啊使而一言不发?是上辈子的记忆,还是实际的残暴。当有人说公切莫是人,什么还能够抛弃,忘记的时节,你可说,我弗是忘记所有,我是一无所有。当弟子于限所环绕的时,你却碰破了她。你跨不有这世界是为你莫亮堂它们产生差不多异常,一旦您知道了,就盖了她。我好像又看见了那时的老三窖藏,如来之大弟子,可您却同时是西游旅途的唐僧

 1     if (bmpInfoHeader.biBitCount == 1) {//二值图
 2             channels = 1;
 3             //一个字节存8个像素,除以8向上取整得到字节数
 4             offset = ((int)ceil(width / 8.0)) % 4; 
 5             //求每行末尾的无意义字节数
 6             if (offset != 0)
 7             {
 8                 offset = 4 - offset;
 9             }
10             bmpImg->channels = 1;
11             //存数据的数据块,每个像素用一个字节
12             bmpImg->imageData = (unsigned char*)malloc(sizeof(unsigned char)*width*height);
13             step = channels*width; //每行宽度,字节为单位
14              //读取调色板,二值图像调色板只有两种颜色
15              quad = (ClRgbQuad*)malloc(sizeof(ClRgbQuad) * 2); 
16             fread(quad, sizeof(ClRgbQuad), 2, pFile);
17             free(quad);
18             int w = (int)ceil(width / 8.0);//每行占的字节数
19             //用于临时存储从每个字节读取出来的像素值
20             unsigned char bits[8];
21             //计数器,每行达到图像宽度(width-1),说明后面的bit均为无效,因为最后一个有效字节也只有部分bits是有效的
22             int m = 0;
23             for (i = 0; i < height; i++)
24             {
25                 m = 0;
26                 for (j = 0; j < w; j++)
27                 {
28                     fread(&pixVal, sizeof(unsigned char), 1, pFile);
29                     //获取字符中没一位的值,以一个unsigned char[8]的数组存储
30                     get_bitsofchar(bits, pixVal);
31                     //把每个字节的8位值解析出来,分别存入8个字节
32                     for (int k = 0; k < 8; k++) {
33                         if (m < width) {
34                             //    count[(height - 1 - i)*step + m] = bits[k];
35                             if (bits[k] == 1) { //把值1映射为8位图中的255
36                                 bits[k] = 255;
37                             }
38                             // 坐标原点在左下角=》(height - 1 - i)*step+j,通过这个变换坐标原点变为左上角
39                             bmpImg->imageData[(height - 1 - i)*step + m] = bits[k];
40                         }
41                         m++;
42                     }
43                 }
44                 if (offset != 0)
45                 {
46                     for (j = 0; j < offset; j++)
47                     {
48                         fread(&pixVal, sizeof(unsigned char), 1, pFile);  //读取每行的空字节
49                     }
50                 }
51             }
52             for (int i = 0; i < height; i++) {
53                 for (int j = 0; j < width; j++) {
54                     printf("%d ", bmpImg->imageData[i*width + j]);
55                 }
56                 printf("\n");
57             }
58         }

唐三藏 500年 雷音寺

 1  if (bmpInfoHeader.biBitCount == 24)
 2         {
 3             //3通道, 每个像元占3列
 4             channels = 3;
 5             bmpImg->channels = 3; 
 6              //每个像元占3列,数据块是8位的3倍
 7             bmpImg->imageData = (unsigned char*)malloc(sizeof(unsigned char)*width * 3 * height);
 8             step = channels*width;//每行宽度,字节为单位(只包括有效数据)
 9              //计算空白数据,因为每行的长度只能是4的整数倍,如果不是,则以空白补上
10             offset = (channels*width) % 4;
11             if (offset != 0)
12             {
13                 offset = 4 - offset;
14             }
16             for (i = 0; i < height; i++)
17             {
18                 for (j = 0; j < width; j++)
19                 {
20                     for (k = 0; k < 3; k++) //三个通道分别读取
21                     {
22                         fread(&pixVal, sizeof(unsigned char), 1, pFile);
23                         bmpImg->imageData[(height - 1 - i)*step + j * 3 + k] = pixVal;
24                     }
25                 }
26                 if (offset != 0)
27                 {
28                     for (j = 0; j < offset; j++)
29                     {
30                         fread(&pixVal, sizeof(unsigned char), 1, pFile); //读空白
31                     }
32                 }
33             }
34         }

悟空传,一总理500年底光阴史。500年晚,谁还能够分清唐僧还是金蝉子,孙悟空还是齐天大圣,天蓬还是八防范,沙僧还是卷帘大将。每一个总人口犹承担自己的运走及西游之路。当五百年之小日子只是一个骗局,虚无着之人物又怎要艰辛,为什么要爱为?在此世界上粗人是从来不下的,你被他归来,他寻觅不过来时的里程,找不至要失去之地方,就会见生在中外的之一地方,西游旅途,你们可是好?

3、调色板

也师阵的非常欣赏而。八戒备,蟠桃大会上,玉帝问罪与您,你说,我扶起了所好之总人口,所以来罪。从那时起,我不怕当你我而师徒之为。八防范,爱情对而阵的那么要呢?明知道它们底痛,就越是要认真的去爱。明知道与玉帝也敌没有好结果,为什么非吃生阿月给您的巡回仙丹呢?吃了它,你便好淡忘前世的记啊。

语言 1语言 2

金山寺达标,论法平征战成称为。三收藏,主持的位就假设招与您,你也说:其实自己要是学的而而且教不了自我。我要这天,再遮不歇我肉眼,要这地,在埋不了我心,要立马动物都清楚我意,要那诸佛都咬消云散,三藏,你终于回来了,你记起了您的信念了啊?一截伟大的旅程从此开始。

  • 1配节用于蓝色分量
  • 1字节用于绿色分量
  • 1配节用于红分量
  • 1字节用于填充符(设置为0,透明度)

悟空,你当时的衷心是那么的纯洁,连天地都黯然失色。夜,东海,大海在月夜遇闪着万点银光,在濒海高高的山崖上,你呆呆的朝在大海,世界是如此吧?极目之远在,无边无际,我可非能够以一发?

bmp.h文件:

公说,人独自吗和谐解脱,却无能够算是得正果。众生心中懵懂一切开,爱欲痴缠,丢下未得。苦吗由于的,乐也从之。却丢不产坐单需要字,我劝人清心忘欲,可很由于空而生,由让的于空而去,不过大凡教来者向来高居失去,苍生的被江湖,如落叶纷纷于全球,生生不息,本不用导,也许还有别得真意。

00F8也F800h = 1111 1000 0000 0000(二进制),是蓝色分量的掩码。

500年前,一会蟠桃大会,引发一次于大闹天宫。悟空,你因您的无限法力可以无拘无束。可是,在此世界上为什么有神明也?为什么世间万物都使为她们所任吗?

颜色表结构的概念如下: 

我而这天再遮不鸣金收兵我之眼眸,我只要立马地再盖不了自己之心扉。

5)11-14:从文本开始形成图数据中的偏移量(14+40+4*(2^biBitCount))(在发生颜色板的事态下)。4600
0000,为00000046h=70,上面的公文头就是是35字=70字节。

五百年,很老吗?,失去的整个,都无处找了啊?

对24-位真彩色图像就非动彩色板,因为各图被之RGB值就意味着了每个象素的颜色。

悟空,你要么决定要动了,去海外实现而的想望。你清白的一刻,远胜与周神佛的生平。

 

人生发出酒须尽欢,莫使金尊空对月。八防范,我了解,在列一个同时月的晚,就见面来泪滑落脸旁。八戒备,你唯独理解,你的心底只是出那坏,如果还用于塞悲伤,哪里来空间装满幸福吧?八防止,为师不可知支援您,为师的眼底只有佛法,爱恨两配为师无能为力。

 1 typedef struct
 2 {
 3     unsigned long  biSize;//说明位图信息头结构所需要的字节数
 4     long   biWidth;//列出,像素为单位
 5     long   biHeight;//行数,像素为单位
 6     unsigned short   biPlanes;//为目标设备说明位面数,其值将总是被设为1
 7     unsigned short   biBitCount;//说明比特数/象素,其值为1、4、8、16、24、或32,平时用到的图像绝大部分是24位(真彩色)和8位256色
 8     unsigned long  biCompression;//说明图象数据压缩的类型,一般没有没有压缩的类型,所以没有此项数据    
 9     unsigned long  biSizeImage;//说明图象的大小,以字节为单位
10     long   biXPelsPerMeter;//说明水平分辨率,用象素/米表示
11     long   biYPelsPerMeter;//说明垂直分辨率,用象素/米表示
12     unsigned long   biClrUsed;//说明位图实际使用的彩色表中的颜色索引数(设为0的话,则说明使用所有调色板项)。
13     unsigned long   biClrImportant;//说明对图象显示有重要影响的颜色索引的数目,如果是0,表示都重要
14 } ClBitMapInfoHeader;

这个领域,我来了,我奋战了,我很爱过,我无以乎结局。               
          ――《悟空传》

 1     //先写文件类型标识
 2          fileType = 0x4D42;
 3     fwrite(&fileType, sizeof(unsigned short), 1, pFile);
 4      if (bmpImg->channels == 1)//8位,单通道,灰度图  
 5     {      
 6                 //每行字节数
 7         step = bmpImg->width;
 8                //如果step 不是4字节的整数倍,凑整
 9         offset = step % 4;
10         if (offset != 0)
11         {
12             offset = 4 - offset;
13             step += offset;
14         }
15                 //写文件头
16         bmpFileHeader.bfSize = 54 + 256 * 4 + bmpImg->width;
17         bmpFileHeader.bfReserved1 = 0;
18         bmpFileHeader.bfReserved2 = 0;
19         bmpFileHeader.bfOffBits = 54 + 256 * 4;
20         fwrite(&bmpFileHeader, sizeof(ClBitMapFileHeader), 1, pFile);
21                  //写位图信息头
22         bmpInfoHeader.biSize = 40;
23         bmpInfoHeader.biWidth = bmpImg->width;
24         bmpInfoHeader.biHeight = bmpImg->height;
25         bmpInfoHeader.biPlanes = 1;
26         bmpInfoHeader.biBitCount = 8;
27         bmpInfoHeader.biCompression = 0;
28         bmpInfoHeader.biSizeImage = bmpImg->height*step;
29         bmpInfoHeader.biXPelsPerMeter = 0;
30         bmpInfoHeader.biYPelsPerMeter = 0;
31         bmpInfoHeader.biClrUsed = 256;
32         bmpInfoHeader.biClrImportant = 256;
33         fwrite(&bmpInfoHeader, sizeof(ClBitMapInfoHeader), 1, pFile);
34         //写调色板,是一个灰度值序列,长度255
35         quad = (ClRgbQuad*)malloc(sizeof(ClRgbQuad) * 256);
36         for (i = 0; i < 256; i++)
37         {
38             quad[i].rgbBlue = i;
39             quad[i].rgbGreen = i;
40             quad[i].rgbRed = i;
41             quad[i].rgbReserved = 0;
42         }
43         fwrite(quad, sizeof(ClRgbQuad), 256, pFile);
44         free(quad);
45                //写每个像素
46         for (i = bmpImg->height - 1; i > -1; i--)
47         {
48             for (j = 0; j < bmpImg->width; j++)
49             {
50                 pixVal = bmpImg->imageData[i*bmpImg->width + j];
51                 fwrite(&pixVal, sizeof(unsigned char), 1, pFile);
52             }
53                         //写无意义充填字节
54             if (offset != 0)
55             {
56                 for (j = 0; j < offset; j++)
57                 {
58                     pixVal = 0;
59                     fwrite(&pixVal, sizeof(unsigned char), 1, pFile);
60                 }
61             }
62         }
63     }

悟空,你还记须菩提为?你的72扭转从何而来?他为何未给您于他师傅吗?因为他见到了卿将来一经开的转业。悟空,你的讳从何而来呢?鸿蒙初辟本无姓,打破顽冥须悟空。500年矣,悟空,你想起来了吗?

 

精是什么?为什么而受神仙铲除为?原来,像这样神仙没法管的事物都生一个名,叫妖。神以是啊为?神不射,为何容不产一些针对性那个莫尊敬,神不腻,为何设用地上千万生灵命运握与手中呢?悟空,只为心高嫌地窄,立心端要解瑶天。你毕竟做了卿本应该举行的转业,你的史事千万年后以和流传中。

 

若要牢记你是一个猕猴,因此你不用学做神,你的秉性比所有神明都神圣。

4)9-10:保留,必须安装为0。

500年后

12)35-38:用配节数表示的位图数据的高低,该数必须是4底翻番,数值达到相当:一行所占的字节数×个图高度。0090
0000吧00009000h=80×90×2h=36864。假设位图是24位,宽也41,高为30,则数值=
(biWidth*biBitCount+31)/32*4*biHeight,即=(41*24+31)/32*4*30=3720

八戒,在为师的3个单弟力,大家认为你无与伦比愚蠢,最易来笑话。为师知道,你的笑颜和心情无关。前天夜里,我梦游的时光看见有雷同车轮蓝色的月亮,漫天的天河,把远大静静照在平但哭泣的猪身上。八戒,我掌握你内心的痛苦,我理解您是一个非情愿忘记前世而宁愿承受痛苦的人口,是一个情愿痛苦,也未乐意麻木的一个丁。

1)1-2:图像文件标识符。0x4d42=’BM’,表示是Windows支持之BMP格式。

老三收藏:可是我毕竟以为自家要好就落地了一万年。

其次、文件相继组成部分详细描述(以字节文单位):

猪八戒 500年前

 1 #pragma once
 2 #include <stdio.h>  
 3 typedef struct
 4 {
 5   //  unsigned short    bfType;  //不单独读就出错 (2bytes)
 6     unsigned long    bfSize; //文件大小,字节单位表示(4bytes)
 7     unsigned short    bfReserved1;//保留,必须设0(2bytes)
 8     unsigned short    bfReserved2;//保留,必须设0(2bytes)
 9     unsigned long    bfOffBits;//说明从文件头到实际图像数据之间的偏移量(4bytes)
10 } ClBitMapFileHeader;
11 
12 //C语言结构体大小计算规则:
13 //1、每个成员的偏移量都必须是当前成员所占内存大小的整数倍如果不是编译器会在成员之间加上填充字节。
14 //2、当所有成员大小计算完毕后,编译器判断当前结构体大小是否是结构体中最宽的成员变量大小的整数倍
15 //如果不是会在最后一个成员后做字节填充。
16 
17 typedef struct
18 {
19     unsigned long  biSize;//说明位图信息头结构所需要的字节数(4bytes)
20     long   biWidth;//列出,像素为单位(4bytes)
21     long   biHeight;//行数,像素为单位(4bytes)
22     unsigned short   biPlanes;//为目标设备说明位面数,其值将总是被设为1(2bytes)
23     unsigned short   biBitCount;//说明比特数/象素,其值为1、4、8、16、24、或32,平时用到的图像绝大部分是24位(真彩色)和8位256色(2bytes)
24     unsigned long  biCompression;//说明图象数据压缩的类型,一般没有没有压缩的类型,一般为0  (4bytes) 
25     unsigned long  biSizeImage;//说明图象的大小,以字节为单位(4bytes) 
26     long   biXPelsPerMeter; //说明水平分辨率,用象素/米表示(4bytes) 
27     long   biYPelsPerMeter;//说明垂直分辨率,用象素/米表示(4bytes) 
28     unsigned long   biClrUsed;//说明位图实际使用的彩色表中的颜色索引数(设为0的话,则说明使用所有调色板项)。(4bytes) 
29     unsigned long   biClrImportant;//说明对图象显示有重要影响的颜色索引的数目,如果是0,表示都重要(4bytes) 
30 } ClBitMapInfoHeader;
31 
32 typedef struct
33 {
34     unsigned char rgbBlue; //该颜色的蓝色分量  
35     unsigned char rgbGreen; //该颜色的绿色分量  
36     unsigned char rgbRed; //该颜色的红色分量  
37     unsigned char rgbReserved; //保留值  
38 } ClRgbQuad;
39 
40 typedef struct
41 {
42     int width;  //宽度,像素单位
43     int height;//高度,像素单位
44     int channels;//通道数
45     unsigned char* imageData;//图像数据
46 }ClImage;
47 
48 //读取文件
49 ClImage* clLoadImage(char* path); 
50 //保存文件
51 bool clSaveImage(char* path, ClImage* bmpImg);

了不起就是这般重大呢?为了她,与全的神佛为敌?信念是这么之机要吗?为了保障它,不惜割舍去有,用闪电击毁自己,投入轮回,从走西圣的路?人生一样世,草木一肉欲,也许你是针对性的,三藏。人若没有了妙,那和鲍鱼又产生什么分别!

13)39-42:用象素/米代表的程度分辨率。A00F 0000为0000 0FA0h=4000。

其三窖藏,所以您质疑佛祖,质疑小就佛法,在和佛祖的辩解中败下阵来。三珍藏,你是佛祖的大弟子,你的一模一样根本手指也克接触破天穹,你几千年来之苦修,大乘教义,这些公都乐意舍弃去吧?你说如果来是什么,是不容置疑道来。所以您坚守你自己之自信心。

bmp.cpp文件:

五百年生长远吗?,你忘掉了哭,也不再笑,唯有沉默,长久之默不作声。

17)(55+0)到(50-1+2^biBitCount):彩色板规范。对于调色板中的每个表项,用下述方法来讲述RGB的价:

如果天压我,劈开那天,若地拘我,踏碎那地,我顶生来自由身,谁胆敢高高在上。

 1 #include "bmp.h"  
 2 #include <stdio.h>
 3 
 4 void main()
 5 {
 6     ClImage* img = clLoadImage("c:/122.bmp");
 7     bool flag = clSaveImage("c:/result.bmp", img);
 8     if (flag)
 9     {
10         printf("save ok... \n");
11     }
12 }

“天蓬,你可知罪?”“知道,因为我拉起了自我所爱之口。

15)47-50:位图使用的颜色索引数。设为0的言辞,则印证以所有调色板项。

悟空,为什么要你回顾过去虽头痛不已呢?是;师傅吗帮助不了你,悟空,是匪是忘记了整套就真没痛苦?你沉默了,你真的忘记了500年前也?在当时无异生出给布置好结果的西游戏上,你悄悄远去。你说而毕竟理解,手中的金箍棒上无克高,下未可知探海,没有齐天大圣,只发生相同才猕猴,悟空,你实在忘了500年前?

语言 3语言 4

怎能忘掉了西游?

6)15-18:位图图信息头长度。

西游记,讲诉一只有猴,一条猪,一匹马,一个总人口的故事。讲诉的凡一样截峥嵘岁月。明知道么有下文,但历经百世千生之后,天蓬还是无法忘记对阿月的深爱,明知道与如来为敌虽是暨世界诸神作战,绝对无法战胜,为什么三藏还是那么执着跟和谐之精也?

1、图像文件头

八防范,你是啊师的独自弟众最奇特之一个。因为你又前世的记,还记得你同阿月对笑而看来乎?还记得银河优美的来由为?八戒,你如果提防什么吧?你为掩护所爱之人头,宁愿跟齐天大圣战斗,八防护,还接的当年倒以金箍棒下的次数为?为师其实整个都懂,你针对悟空说罢,心中无爱,就未清楚珍惜二配。

六、写BMP文件

悟空,你输了,正是你心中发出善,佛祖才能够降你。可是你在我心中并无败,做一个良心有爱的总人口,远胜过无欲无爱的仙。

2)3-6:整个文件大小。4690 0000,为00009046h=36934。

老三收藏,你说,这潭水又是何许人也掌心上的一样滴水呢?它后凡会成大海或者一个困境呢?你看那么江水滔滔不尽,又何曾又干涸的同等龙?它的源流是呀也?我之源又是什么吗?

2、位图信息头

悟空,佛祖也束手无策预料一切。因为若宁愿死,也非情愿意输。悟空已失去,此地空留花果山。悟空,为师为无力回天,你协调的选,我完全尊重您。雨水过后底花果山,巍然而就,诉说在公的故事。

10)29-30:每个像素的位数。有1(单色),4(16色),8(256色),16(64K色,高彩色),24(16M色,真彩色),32(4096M色,增强型真彩色)。1000吗0010h=16。

悟空,当你还在花果山之上,你无忧无虑,是啊吃你去花果山?是若的爱侣都先你只要失去为?你是先天的石猴,你有度的生,悟空,你说而来一个企盼,你相你想不到起时,那天也深受开路,入海时,水吗分为两度,众神诸佛见自己哉称兄道弟,天下在无可拘我之东西,再无可管我之人,再不管我到不了之处在,再随便我做不成为的务。

14)43-46:用象素/米代表的垂直分辨率。A00F 0000为0000 0FA0h=4000。

孙悟空 500年 花果山

源代码:

主持:你还太小,不要想那么多。

BMP文件之数以自文本头开始的先后顺序分为四个组成部分:

500年后 西游路上

各类图数据记录了位图的每一个如素值,记录顺序是在围观行内是从漏洞百出至右手,扫描行之间是自下到上。位图的一个如素值所占用的字节数: 
当biBitCount=1时不时,8只像从占1只字节; 
当biBitCount=4时,2个像从占1个字节; 
当biBitCount=8时,1单像从占1只字节; 
当biBitCount=24常常,1个像素占3个字节; 
Windows规定一个扫描行所占有的字节数必须是 
4的倍数(即以long为单位),不足之以0填充, 
一个扫描行所占据的字节数计算方法: 
DataSizePerLine=   (biWidth*   biBitCount+31)/8;   
//   一个扫描行所占的字节数 
DataSizePerLine=   DataSizePerLine/4*4;   //   字节数必须是4的翻番 
 

纷纷落叶飘向中外,白雪下种子沉睡,一朵花开了又快萎缩,在流转的单独之黑影中,星图不断变幻,海水受到矗立起高山,草木几百替代之荣枯,总有一片片之顶风挺立,酷似它们的上代。

3)1bit位图(黑白图、二值图)

悟空,我们同时碰到了。你说师傅,徒儿这些年来好辛苦。是呀,他们还惦记你十分,只要您可知忘怀过去,你不怕会见没痛苦。悟空你说,我可以淡忘我要好,可是我遗忘不了东海历届,忘不了花果山,忘不了西天路,忘不了中途的丁。所以您而搏,战,胜。可是若现在的能力从胜不了高空的神佛,为什么您还要去?明知会输,却为何还未放弃?

【3】CSDN博客:BMP格式介绍

“大圣,此去需何?”,“踏南天,碎凌霄,”,“若一去不回……”,“便一去不回!。

11)31-34:压缩说明:有0(不打折扣),1(RLE 8,8员RLE压缩),2(RLE
4,4位RLE压缩,3(Bitfields,位域存放)。RLE简单地就是采用像素数+像素值的方开展削减(行程编码)。T408用的凡位域存放方式,用有限只字节表示一个像素,位域分配为r5b6g5。图中0300
0000乎00000003h=3(这张图纸未在颜色板)。

老三窖藏,那道闪电阵的击毁了卿为?你究竟说,何人生自,生自又何以?既带自己来,又休带与自我。苍天默默,唯有一滴泪滑得嘴边。我盼望正在您回去的那么同样龙。

将掩码跟像素值进行“与”运算再进行移动操作就好得各色分量值。看看掩码,就可以掌握事实上在每个像素值的少个字节16员受,按自大及没有取5、6、5位分别就是r、g、b分量值。取出重值后把r、g、b值分别乘以8、4、8便可以补齐第个份量也一个字节,再把当下三单字节按rgb组合,放入存储器(同样要反序),就好变为24员专业BMP格式了。

16)51-54:对图象显示出要影响之水彩索引的数目。如果是0,表示还至关重要。

主程序文件:

 

 

BMP文件格式,是Windows系统中常见采取的图像文件格式。由于它可以不发其它移地保留图像像素域的数目,因此成我们赢得原始数据的最主要根源。Windows的图形用户界面(graphical
user interfaces)也在她的内建图像子系统GDI中对BMP格式提供了支持。

其三、通过C语言结构体定义说明BMP主要的季只有

bmp.h 

若,彩色板为00F8 0000 E007 0000 1F00 0000 0000 0000,其中:

2、位图信息头

 

1F00乎001Fh = 0000 0000 0001  1111(二进制),是红色分量的掩码。

1 typedef struct
2 {
3     unsigned short    bfType; //文件类型:0x4D42(十六进制ASCII码'BM'
4     unsigned long    bfSize;//文件大小,字节单位表示
5     unsigned short    bfReserved1;//保留,必须设0
6     unsigned short    bfReserved2;//保留,必须设0
7     unsigned long    bfOffBits;//说明从文件头到实际图像数据之间的偏移量
8 } ClBitMapFileHeader;

8)23-26:位图高度,以像素为单位。9000 0000,为00000090h=144。

0000 总设置为0。

1、bmp文件头

4、图像数据阵列

1)8bit位图读取

typedef   struct   tagRGBQUAD   { 
BYTErgbBlue;//   蓝色之亮度(值范围吗0-255) 
BYTErgbGreen;   //   绿色的亮度(值范围也0-255) 
BYTErgbRed;   //   红色的亮度(值范围为0-255) 
BYTErgbReserved;//   保留,必须为0 
}   RGBQUAD; 
颜色表中布局数据的个数有biBitCount来确定: 
当biBitCount=1,4,8时,分别有2,16,256个表项; 
当biBitCount=24不时,没有颜色表项。 
各队图信息头和颜料表组成位图信息,BITMAPINFO结构定义如下: 
typedef   struct   tagBITMAPINFO   { 
BITMAPINFOHEADER   bmiHeader;   //   位图信息头 
RGBQUAD   bmiColors[1];   //   颜色表 
}   BITMAPINFO; 

2)24bit位图读取

bmp.cpp

  1 #include "bmp.h"  
  2 #include <stdio.h>  
  3 #include <stdlib.h>  
  4 #include <math.h>
  5 
  6 //获取一个字节中pos位的值(0或1)
  7 unsigned char  read_bit(char c, int   pos)
  8 {
  9     char   b_mask = 0x01;
 10     b_mask = b_mask << pos;
 11     //字符c和b_mask做位运算如果还是等于b_mask,说明该位为1 
 12     if ((c&b_mask) == b_mask)
 13         return   1;
 14     else
 15         return   0;
 16 }
 17 
 18 //将一个Char的所有bit以单个数值(0、1)的形式解析出来
 19 void  get_bitsofchar(unsigned char bits[8], char c)
 20 {
 21     int k = 0;
 22     unsigned char t;
 23     for (k = 0; k < 8; k++)
 24     {
 25         bits[k] = read_bit(c, k);
 26     }
 27     //逆序排列各个bit位——计算机中顺序是从低位向高位排列的
 28     for (k = 0; k < 4; k++)
 29     {
 30         t = bits[k];
 31         bits[k] = bits[7 - k];
 32         bits[7 - k] = t;
 33     }
 34 }
 35 /*
 36 读取BMP文件,返回一个ClImage对象
 37 */
 38 ClImage* clLoadImage(char* path)
 39 {
 40     ClImage* bmpImg;
 41     FILE* pFile;
 42     unsigned short fileType;
 43     ClBitMapFileHeader bmpFileHeader;
 44     ClBitMapInfoHeader bmpInfoHeader;
 45     int channels = 1;
 46     int width = 0;
 47     int height = 0;
 48     int step = 0;
 49     int offset = 0;
 50     unsigned char pixVal;
 51     ClRgbQuad* quad;
 52     int i, j, k;
 53 
 54     bmpImg = (ClImage*)malloc(sizeof(ClImage));
 55     //pFile = fopen(path, "rb");
 56     fopen_s(&pFile, path, "rb");
 57     if (!pFile)
 58     {
 59         free(bmpImg);
 60         return NULL;
 61     }
 62     //如果不先读取bifType,根据C语言结构体Sizeof运算规则——整体大于部分之和,从而导致读文件错位
 63     fread(&fileType, sizeof(unsigned short), 1, pFile);
 64     if (fileType == 0x4D42)
 65     {
 66         printf("文件类型标识正确! \n");
 67         //读文件头(12bytes,除去bifType)
 68         fread(&bmpFileHeader, sizeof(ClBitMapFileHeader), 1, pFile);
 69         printf("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n");
 70         printf("bmp文件头信息:\n");
 71         printf("文件大小:%d \n", bmpFileHeader.bfSize);
 72         printf("保留字:%d \n", bmpFileHeader.bfReserved1);
 73         printf("保留字:%d \n", bmpFileHeader.bfReserved2);
 74         printf("位图数据偏移字节数:%d \n", bmpFileHeader.bfOffBits);
 75         //读位图信息头40bytes
 76         fread(&bmpInfoHeader, sizeof(ClBitMapInfoHeader), 1, pFile);
 77         printf("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n");
 78         printf("bmp文件信息头\n");
 79         printf("结构体长度:%d \n", bmpInfoHeader.biSize);
 80         printf("位图宽度:%d \n", bmpInfoHeader.biWidth);
 81         printf("位图高度:%d \n", bmpInfoHeader.biHeight);
 82         printf("位图平面数:%d \n", bmpInfoHeader.biPlanes);
 83         printf("颜色位数:%d \n", bmpInfoHeader.biBitCount);
 84         printf("压缩方式:%d \n", bmpInfoHeader.biCompression);
 85         printf("实际位图数据占用的字节数:%d \n", bmpInfoHeader.biSizeImage);
 86         printf("X方向分辨率:%d \n", bmpInfoHeader.biXPelsPerMeter);
 87         printf("Y方向分辨率:%d \n", bmpInfoHeader.biYPelsPerMeter);
 88         printf("使用的颜色数:%d \n", bmpInfoHeader.biClrUsed);
 89         printf("重要颜色数:%d \n", bmpInfoHeader.biClrImportant);
 90         printf("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n");
 91 
 92         //获取图像宽度,高度
 93         width = bmpInfoHeader.biWidth;
 94         height = bmpInfoHeader.biHeight;
 95         bmpImg->width = width;
 96         bmpImg->height = height;
 97 
 98         if (bmpInfoHeader.biBitCount == 1) {//二值图
 99             printf("该文件有调色板,即该位图二值图\n\n");
100             channels = 1;
101             offset = ((int)ceil(width / 8.0)) % 4;  //一个字节存8个像素
102 
103             //求每行末尾的空字节数
104             if (offset != 0)
105             {
106                 offset = 4 - offset;
107             }
108             bmpImg->channels = 1;
109             bmpImg->imageData = (unsigned char*)malloc(sizeof(unsigned char)*width*height);
110             step = channels*width; //每行宽度
111 
112             quad = (ClRgbQuad*)malloc(sizeof(ClRgbQuad) * 2); //读取调色板
113             fread(quad, sizeof(ClRgbQuad), 2, pFile);
114             free(quad);
115 
116 
117             int w = (int)ceil(width / 8.0);//每行占的字节数
118             unsigned char bits[8];
119             int m = 0;
120             for (i = 0; i < height; i++)
121             {
122                 m = 0;
123                 for (j = 0; j < w; j++)
124                 {
125                     fread(&pixVal, sizeof(unsigned char), 1, pFile);
126                     //获取字符中没一位的值,以一个unsigned char[8]的数组存储
127                     get_bitsofchar(bits, pixVal);
128                     //把每个字节的8位值解析出来,分别存入8个字节
129                     for (int k = 0; k < 8; k++) {
130                         if (m < width) {
131                             //    count[(height - 1 - i)*step + m] = bits[k];
132                             if (bits[k] == 1) { //把值1映射为8位图中的255
133                                 bits[k] = 255;
134                             }
135                             // 坐标原点在左下角=》(height - 1 - i)*step+j,通过这个变换坐标原点变为左上角
136                             bmpImg->imageData[(height - 1 - i)*step + m] = bits[k];
137                         }
138                         m++;
139                     }
140                 }
141                 if (offset != 0)
142                 {
143                     for (j = 0; j < offset; j++)
144                     {
145                         fread(&pixVal, sizeof(unsigned char), 1, pFile);  //读取每行的空字节
146                     }
147                 }
148             }
149             for (int i = 0; i < height; i++) {
150                 for (int j = 0; j < width; j++) {
151                     printf("%d ", bmpImg->imageData[i*width + j]);
152                 }
153                 printf("\n");
154             }
155         }
156 
157 
158         else if (bmpInfoHeader.biBitCount == 4) {//十六色位图
159             //一般不用这种格式
160         }
161         else if (bmpInfoHeader.biBitCount == 8)//256色位图
162         {
163             printf("该文件有调色板,即该位图为非真彩色8位256色位图\n\n");
164             channels = 1;
165             offset = (channels*width) % 4;
166             if (offset != 0)
167             {
168                 offset = 4 - offset;
169             }
170             bmpImg->channels = 1;
171             bmpImg->imageData = (unsigned char*)malloc(sizeof(unsigned char)*width*height);
172             step = channels*width; //每行宽度
173 
174             quad = (ClRgbQuad*)malloc(sizeof(ClRgbQuad) * 256); //读取调色板
175             fread(quad, sizeof(ClRgbQuad), 256, pFile);
176             free(quad);
177 
178             for (i = 0; i < height; i++)
179             {
180                 for (j = 0; j < width; j++)
181                 {
182                     fread(&pixVal, sizeof(unsigned char), 1, pFile);
183                     // 坐标原点在左下角=》(height - 1 - i)*step+j,通过这个变换坐标原点变为左上角
184                     bmpImg->imageData[(height - 1 - i)*step + j] = pixVal;
185                 }
186                 if (offset != 0)
187                 {
188                     for (j = 0; j < offset; j++)
189                     {
190                         fread(&pixVal, sizeof(unsigned char), 1, pFile);  //读取每行的空字节
191                     }
192                 }
193             }
194         }
195         //16位高彩色图
196         else if (bmpInfoHeader.biBitCount == 16) {
197             //一般不用这种格式
198         }
199         //真彩色
200         else if (bmpInfoHeader.biBitCount == 24)
201         {
202             printf("该位图为位真彩色\n\n");
203             channels = 3;
204             bmpImg->channels = 3;  //每个像元占3列
205             bmpImg->imageData = (unsigned char*)malloc(sizeof(unsigned char)*width * 3 * height);
206             step = channels*width;
207             offset = (channels*width) % 4;
208             if (offset != 0)
209             {
210                 offset = 4 - offset; //计算空白数据,因为每行的长度只能是4的整数倍,如果不是,则以空白补上
211             }
212 
213             for (i = 0; i < height; i++)
214             {
215                 for (j = 0; j < width; j++)
216                 {
217                     for (k = 0; k < 3; k++) //三个通道分别读取
218                     {
219                         fread(&pixVal, sizeof(unsigned char), 1, pFile);
220                         bmpImg->imageData[(height - 1 - i)*step + j * 3 + k] = pixVal;
221                     }
222                     //kzSetMat(bmpImg->mat, height-1-i, j, kzScalar(pixVal[0], pixVal[1], pixVal[2]));  
223                 }
224                 if (offset != 0)
225                 {
226                     for (j = 0; j < offset; j++)
227                     {
228                         fread(&pixVal, sizeof(unsigned char), 1, pFile); //读空白
229                     }
230                 }
231             }
232         }
233         else if (bmpInfoHeader.biBitCount == 32) { //32位位图--具有透明透明通道
234             //一般不用这种格式
235         }
236     }
237     return bmpImg;
238 }
239 
240 bool clSaveImage(char* path, ClImage* bmpImg)
241 {
242     FILE *pFile;
243     unsigned short fileType;
244     ClBitMapFileHeader bmpFileHeader;
245     ClBitMapInfoHeader bmpInfoHeader;
246     int step;
247     int offset;
248     unsigned char pixVal = '\0';
249     int i, j;
250     ClRgbQuad* quad;
251 
252     //pFile = fopen(path, "wb");
253     fopen_s(&pFile, path, "wb");
254     if (!pFile)
255     {
256         return false;
257     }
258 //
259        fileType = 0x4D42;
260     fwrite(&fileType, sizeof(unsigned short), 1, pFile);
261 
262 
263     if (bmpImg->channels == 3)//24位,通道,彩图  
264     {
265         step = bmpImg->channels*bmpImg->width;
266         offset = step % 4;
267         if (offset != 0)
268         {
269             offset = 4 - offset;
270             step += offset;
271         }
272         /*一个BUG
273         if (offset != 4) {
274             step += 4 - offset;
275         }*/
276         //bmpFileHeader.bfType = 0x4D42;
277         bmpFileHeader.bfSize = bmpImg->height*step + 54;
278         bmpFileHeader.bfReserved1 = 0;
279         bmpFileHeader.bfReserved2 = 0;
280         bmpFileHeader.bfOffBits = 54;
281         fwrite(&bmpFileHeader, sizeof(ClBitMapFileHeader), 1, pFile);
282 
283         bmpInfoHeader.biSize = 40;
284         bmpInfoHeader.biWidth = bmpImg->width;
285         bmpInfoHeader.biHeight = bmpImg->height;
286         bmpInfoHeader.biPlanes = 1;
287         bmpInfoHeader.biBitCount = 24;
288         bmpInfoHeader.biCompression = 0;
289         bmpInfoHeader.biSizeImage = bmpImg->height*step;
290         bmpInfoHeader.biXPelsPerMeter = 0;
291         bmpInfoHeader.biYPelsPerMeter = 0;
292         bmpInfoHeader.biClrUsed = 0;
293         bmpInfoHeader.biClrImportant = 0;
294         fwrite(&bmpInfoHeader, sizeof(ClBitMapInfoHeader), 1, pFile);
295 
296         for (i = bmpImg->height - 1; i > -1; i--)
297         {
298             for (j = 0; j < bmpImg->width; j++)
299             {
300                 pixVal = bmpImg->imageData[i*bmpImg->width * 3 + j * 3];
301                 fwrite(&pixVal, sizeof(unsigned char), 1, pFile);
302                 pixVal = bmpImg->imageData[i*bmpImg->width * 3 + j * 3 + 1];
303                 fwrite(&pixVal, sizeof(unsigned char), 1, pFile);
304                 pixVal = bmpImg->imageData[i*bmpImg->width * 3 + j * 3 + 2];
305                 fwrite(&pixVal, sizeof(unsigned char), 1, pFile);
306             }
307             if (offset != 0)
308             {
309                 for (j = 0; j < offset; j++)
310                 {
311                     pixVal = 0;
312                     fwrite(&pixVal, sizeof(unsigned char), 1, pFile);
313                 }
314             }
315         }
316     }
317 
318     else if (bmpImg->channels == 1)//8位,单通道,灰度图  
319     {
320         step = bmpImg->width;
321         offset = step % 4;
322         if (offset != 0)
323         {
324             offset = 4 - offset;
325             step += offset;
326         }
327         //bmpFileHeader.bfType = 0x4D42;
328         bmpFileHeader.bfSize = 54 + 256 * 4 + bmpImg->width;
329         bmpFileHeader.bfReserved1 = 0;
330         bmpFileHeader.bfReserved2 = 0;
331         bmpFileHeader.bfOffBits = 54 + 256 * 4;
332         fwrite(&bmpFileHeader, sizeof(ClBitMapFileHeader), 1, pFile);
333 
334         bmpInfoHeader.biSize = 40;
335         bmpInfoHeader.biWidth = bmpImg->width;
336         bmpInfoHeader.biHeight = bmpImg->height;
337         bmpInfoHeader.biPlanes = 1;
338         bmpInfoHeader.biBitCount = 8;
339         bmpInfoHeader.biCompression = 0;
340         bmpInfoHeader.biSizeImage = bmpImg->height*step;
341         bmpInfoHeader.biXPelsPerMeter = 0;
342         bmpInfoHeader.biYPelsPerMeter = 0;
343         bmpInfoHeader.biClrUsed = 256;
344         bmpInfoHeader.biClrImportant = 256;
345         fwrite(&bmpInfoHeader, sizeof(ClBitMapInfoHeader), 1, pFile);
346 
347         //调色板是一个灰度图
348         quad = (ClRgbQuad*)malloc(sizeof(ClRgbQuad) * 256);
349         for (i = 0; i < 256; i++)
350         {
351             quad[i].rgbBlue = i;
352             quad[i].rgbGreen = i;
353             quad[i].rgbRed = i;
354             quad[i].rgbReserved = 0;
355         }
356         fwrite(quad, sizeof(ClRgbQuad), 256, pFile);
357         free(quad);
358 
359         for (i = bmpImg->height - 1; i > -1; i--)
360         {
361             for (j = 0; j < bmpImg->width; j++)
362             {
363                 pixVal = bmpImg->imageData[i*bmpImg->width + j];
364                 fwrite(&pixVal, sizeof(unsigned char), 1, pFile);
365             }
366             if (offset != 0)
367             {
368                 for (j = 0; j < offset; j++)
369                 {
370                     pixVal = 0;
371                     fwrite(&pixVal, sizeof(unsigned char), 1, pFile);
372                 }
373             }
374         }
375     }
376     fclose(pFile);
377 
378     return true;
379 }

3)7-8:保留,必须设置为0。

代码中,为了从字节的8各项受剖析出8只像素值,定义了位运算函数如下:

一、简介

【2】CSDN博客:故而C语言对BMP进行读写

每当文书头、位图信息头和调色板(如果部分言语)之后,就是个图数据阵列了,

参考资料:

位图的一个诸如素值所占据的字节数不以,每个像素的积存大小不等,读取位图图像数据经常需针对不同的位图采用不同之处理,8员以及24员为常用的有数种植类型,这里首先介绍,1各类的第二值图一个字节表示8只像从信息,需要经过各类运算解析出每个像素的值(0或1),通过以对8员各图读取方法进行扩张实现。

【4】博客园:C语言编写BMP读写程序

9)27-28:位图的位面数,该值总是1。0100,为0001h=1。

 

【1】百度百科:BMP文件

1 typedef struct
2 {
3     int width;  //宽度,像素单位
4     int height;//高度,像素单位
5     int channels;//通道数
6     unsigned char* imageData;//图像数据
7 }ClImage;

注:根据C语言中结构体大小的计量规则(参考:C语言结构体大小计算),结构体变量的Size并不一定是该抱有字段size之和,导致如果直接用一个结构体变量作为读入数据块的器皿,可能有偏差。因此,对文本头之布局体定义去丢了字段bfType语言,而是于念文件之先后中独用一个变量读博该消息。

 1 if (bmpInfoHeader.biBitCount == 8)//256色位图
 2         {
 3             channels = 1;
 4             //每行数据量是4字节整数倍
 5             offset = (channels*width) % 4;
 6             //计算每行需要在有效数据后填充的无意义字节数
 7             if (offset != 0)
 8             {
 9                 offset = 4 - offset;
10             }
11             bmpImg->channels = 1;
12             bmpImg->imageData = (unsigned char*)malloc(sizeof(unsigned char)*width*height);
13             step = channels*width; //每行宽度(字节为单位)
14             quad = (ClRgbQuad*)malloc(sizeof(ClRgbQuad) * 256); 
15             //读取调色板,8位字符调色板包含256种颜色
16             fread(quad, sizeof(ClRgbQuad), 256, pFile);
17             free(quad);
18             //读每个像素的值
19             for (i = 0; i < height; i++)
20             {
21                 for (j = 0; j < width; j++)
22                 {
23                     fread(&pixVal, sizeof(unsigned char), 1, pFile);
24                     // 坐标原点在左下角=》(height - 1 - i)*step+j,通过这个变换坐标原点变为左上角
25                     bmpImg->imageData[(height - 1 - i)*step + j] = pixVal;
26                 }
27                //读行末尾无意义的字节
28                 if (offset != 0)
29                 {
30                     for (j = 0; j < offset; j++)
31                     {
32                         fread(&pixVal, sizeof(unsigned char), 1, pFile);  //读取每行的空字节
33                     }
34                 }
35             }
36         }

四、读取BMP文件

 1 //获取一个字节中pos位的值(0或1)
 2 unsigned char  read_bit(char c, int   pos)
 3 {
 4     char   b_mask = 0x01;
 5     b_mask = b_mask << pos;
 6     //字符c和b_mask做位运算如果还是等于b_mask,说明该位为1 
 7     if ((c&b_mask) == b_mask)
 8         return   1;
 9     else
10         return   0;
11 }
12 
13 //将一个Char的所有bit以单个数值(0、1)的形式解析出来
14 void  get_bitsofchar(unsigned char bits[8], char c)
15 {
16     int k = 0;
17     unsigned char t;
18     for (k = 0; k < 8; k++)
19     {
20         bits[k] = read_bit(c, k);
21     }
22     //逆序排列各个bit位——计算机中顺序是从低位向高位排列的
23     for (k = 0; k < 4; k++)
24     {
25         t = bits[k];
26         bits[k] = bits[7 - k];
27         bits[7 - k] = t;
28     }
29 }

7) 19-22:位图幅,以像素为单位。8000 0000,为00000080h=128。

2、写24bit位图

 1       fileType = 0x4D42;
 2     fwrite(&fileType, sizeof(unsigned short), 1, pFile);
 3           //24位,3通道,真彩图  
 4     if (bmpImg->channels == 3)
 5     {
 6         step = bmpImg->channels*bmpImg->width;
 7         offset = step % 4;
 8         if (offset != 0)
 9         {
10             offset = 4 - offset;
11             step += offset;
12         }
13                 //写文件头
14         bmpFileHeader.bfSize = bmpImg->height*step + 54;
15         bmpFileHeader.bfReserved1 = 0;
16         bmpFileHeader.bfReserved2 = 0;
17         bmpFileHeader.bfOffBits = 54;
18         fwrite(&bmpFileHeader, sizeof(ClBitMapFileHeader), 1, pFile);
19                 //写位图信息头
20         bmpInfoHeader.biSize = 40;
21         bmpInfoHeader.biWidth = bmpImg->width;
22         bmpInfoHeader.biHeight = bmpImg->height;
23         bmpInfoHeader.biPlanes = 1;
24         bmpInfoHeader.biBitCount = 24;
25         bmpInfoHeader.biCompression = 0;
26         bmpInfoHeader.biSizeImage = bmpImg->height*step;
27         bmpInfoHeader.biXPelsPerMeter = 0;
28         bmpInfoHeader.biYPelsPerMeter = 0;
29         bmpInfoHeader.biClrUsed = 0;
30         bmpInfoHeader.biClrImportant = 0;
31         fwrite(&bmpInfoHeader, sizeof(ClBitMapInfoHeader), 1, pFile);
32                //写像素每个像素有3个值(R,G,B)
33         for (i = bmpImg->height - 1; i > -1; i--)
34         {
35             for (j = 0; j < bmpImg->width; j++)
36             {
37                 pixVal = bmpImg->imageData[i*bmpImg->width * 3 + j * 3];
38                 fwrite(&pixVal, sizeof(unsigned char), 1, pFile);
39                 pixVal = bmpImg->imageData[i*bmpImg->width * 3 + j * 3 + 1];
40                 fwrite(&pixVal, sizeof(unsigned char), 1, pFile);
41                 pixVal = bmpImg->imageDat,a[i*bmpImg->width * 3 + j * 3 + 2];
42                 fwrite(&pixVal, sizeof(unsigned char), 1, pFile);
43             }
44             if (offset != 0)
45             {
46                 for (j = 0; j < offset; j++)
47                 {
48                     pixVal = 0;
49                     fwrite(&pixVal, sizeof(unsigned char), 1, pFile);
50                 }
51             }
52         }
53     }

3、彩色板

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图