BMP图片格式

BMP图片,是Bitmap(位图)的简称,它是windows显示图片的基本格式。在windows下,任何格式的图片文件(包括视频播放)都要转化为位图才能显示出来。各种格式的图片文件也都是在位图格式的基础上采用不同的压缩算法生成的。

位图文件主要分为如下3个部分:

块名称 对应Windows结构体定义 大小(Byte)
文件信息头 BITMAPFILEHEADER 14
位图信息头 BITMAPINFOHEADER 40
RGB颜色阵列 BYTE* 由图像长宽尺寸决定

文件信息头结构体定义如下:

typedef struct BMP_FILE_HEADER
{//WORD bType;      // 文件标识符,这里为0x4d42 DWORD bSize;     // 文件的大小 WORD bReserved1; // 保留值,必须设置为0  WORD bReserved2; // 保留值,必须设置为0 DWORD bOffset;  // 文件头的最后到图像数据位开始的偏移量,//说明从文件头开始到实际的图象数据之间的字节的偏移量//因为位图信息头和调色板的长度会根据不同情况而变化//所以你可以用这个偏移值迅速的从文件中读取到位数据
} BMPFILEHEADER;    // 14 字节
bType 说明文件的类型,该值必需是0x4D42(十六进制ASCII码4D代表“B”,42代表“M”),也就是字符'BM'
bSize 说明该位图文件的大小,用字节为单位
bReserved1 保留,必须设置为0
bfReserved2 保留,必须设置为0
bOffBits 说明从文件头开始到实际的图象数据之间的字节的偏移量。这个参数是非常有用的,因为位图信息头和调色板的长度会根据不同情况而变化,所以你可以用这个偏移值迅速的从文件中读取到位数据

位图信息头结构体定义如下:

typedef struct BMP_INFO
{DWORD bInfoSize;            // 信息头的大小   DWORD bWidth;               // 图像的宽度     DWORD bHeight;              // 图像的高度,如果该值是一个正数,说明图像是倒向的,如果该值是一个负数,则说明图像是正向的。  WORD bPlanes;               // 图像的位面数,其值将总是被设为1 WORD bBitCount;             // 每个像素的位数,这里为 24位DWORD bCompression;         // 压缩类型 DWORD bmpImageSize;         // 图像的大小,以字节为单位 DWORD bXPelsPerMeter;       // 水平分辨率 DWORD bYPelsPerMeter;       // 垂直分辨率 DWORD bClrUsed;             // 位图实际使用的彩色表中的颜色索引数(设为0的话,则说明使用所有调色板项)DWORD bClrImportant;        // 对图象显示有重要影响的颜色索引的数目,如果是0,表示都重要
} BMPINF;            // 40 字节
bInfoSize 说明BITMAPINFOHEADER结构所需要的字数。
bWidth 说明图象的宽度,以象素为单位。
bHeight 说明图象的高度,以象素为单位。注:这个值除了用于描述图像的高度之外,它还有另一个用处,就是指明该图像是倒向的位图,还是正向的位图。如果该值是一个正数,说明图像是倒向的,如果该值是一个负数,则说明图像是正向的。大多数的BMP文件都是倒向的位图,也就是说,高度值是一个正数。
bPlanes 为目标设备说明位面数,其值将总是被设为1。
BitCount 说明比特数/象素,其值为1、4、8、16、24、或32。我们平时用到的图像绝大部分是24位和32位的
bCompression 说明图象数据压缩的类型,同样我们只讨论没有压缩的类型:BI_RGB。
bmpImageSize 说明图象的大小,以字节为单位。当用BI_RGB格式时,可设置为0。
bXPelsPerMeter 说明水平分辨率,用象素/米表示。
bYPelsPerMeter 说明垂直分辨率,用象素/米表示。
bClrUsed 说明位图实际使用的彩色表中的颜色索引数(设为0的话,则说明使用所有调色板项)。
bClrImportant 说明对图象显示有重要影响的颜色索引的数目,如果是0,表示都重要。

RGB颜色通道:

在windows下面,RGB颜色矩阵的存储格式是BGR。颜色数据区记录着每个像素对应的颜色值。其记录方式随着颜色模式的不同而不同。

BitCount=1
    表示位图最多有两种颜色,缺省情况下是黑色和白色,你也可以自己定义这两种颜色。图像信息头调色板中将有两个调色板项,称为索引0和索引1。图象数据阵列中的每一位表示一个象素。如果一个位是0,显示时就使用索引0的RGB值,如果位是1,则使用索引1的RGB值。
BitCount=4
    表示位图最多有16种颜色。每个象素用4位表示,并用这4位作为彩色表的表项来查找该象素的颜色。例如,如果位图中的第一个字节为0x1F,它表示有两个象素,第一象素的颜色就在彩色表的第2表项中查找,而第二个象素的颜色就在彩色表的第16表项中查找。此时,调色板中缺省情况下会有16个RGB项。对应于索引0到索引15。
BitCount=8
    表示位图最多有256种颜色。每个象素用8位表示,并用这8位作为彩色表的表项来查找该象素的颜色。例如,如果位图中的第一个字节为0x1F,这个象素的颜色就在彩色表的第32表项中查找。此时,缺省情况下,调色板中会有256个RGB项,对应于索引0到索引255。

BitCount=16
    表示位图最多有65536种颜色。每个色素用16位(2个字节)表示。这种格式叫作高彩色,或叫增强型16位色,或64K色。它的情况比较复杂。

当 biCompression成员的值是BI_RGB时,它没有调色板。16位中,最低的5位表示蓝色分量,中间的5位表示绿色分量,高的5位表示红色分量,一共占用了15位,最高的一位保留,设为0。这种格式也被称作555。

当biCompression成员的值是BI_BITFIELDS,那么情况就复杂了,首先是原来调色板的位置被三个DWORD变量占据,称为红、绿、蓝掩码。分别用于描述红、绿、蓝分量在16位中所占的位置。在Windows95(或98)中,系统可接受两种格式的位域:555和565,在555格式下,红、绿、蓝的掩码分别是:0x7C00、0x03E0、0x001F,而在565格式下,它们则分别为:0xF800、0x07E0、0x001F。你在读取一个像素之后,可以分别用掩码“与”上像素值,从而提取出想要的颜色分量(当然还要再经过适当的左右移操作)。在NT系统中,则没有格式限制,只不过要求掩码之间不能有重叠。(注:这种格式的图像使用起来是比较麻烦的,不过因为它的显示效果接近于真彩,而图像数据又比真彩图像小的多,所以,它更多的被用于游戏软件)。

BitCount=24
    表示位图最多有2的24次方,大约1670万种颜色。这种位图没有调色板(bmiColors成员尺寸为0),在位数组中,每3个字节代表一个象素,分别对应于颜色R、G、B。
BitCount=32
    表示位图最多有2的32次方种颜色。这种位图的结构与16位位图结构非常类似

当biCompression成员的值是BI_RGB时,它也没有调色板,32位中有24位用于存放RGB值,顺序是:最高位—保留,红8位、绿8位、蓝8位。这种格式也被成为888。

当biCompression成员的值是BI_BITFIELDS时,原来调色板的位置将被三个DWORD变量占据,成为红、绿、蓝掩码,分别用于描述红、绿、蓝分量在32位中所占的位置。在Windows95(or 98)中,系统只接受888格式,也就是说三个掩码的值将只能是:0xFF0000、0xFF00、0xFF。而在NT系统中,你只要注意使掩码之间不产生重叠就行。(注:这种图像格式比较规整,因为它是DWORD对齐的,所以在内存中进行图像处理时可进行汇编级的代码优化(简单))。

注意:
BMP图像数据区在存储时,2色图像每点占1位(8位为1字节);16色图像每点占4位(半字节);256色图像每点占8位(1字节);真彩色图像每点占24位(3字节)。所以,整个数据区的大小也会随之变化。究其规律而言,可的出如下计算公式:图像数据信息大小=(图像宽度*图像高度*记录像素的位数)/8。
对于未压缩的图像信息区的大小。除了真彩色模式外,其余的均大于或等于数据信息的大小。这是为什么呢?原因有两个:
1.BMP文件记录一行图像是以字节为单位的。因此,就不存在一个字节中的数据位信息表示的点在不同的两行中。也就是说,设显示模式为16色,在每个字节分配两个点信息时,如果图像的宽度位奇数,那么最后一个像素点的信息将独占一个字节,这个字节的后4位将没有意义。接下来的一个字节将开始记录下一行的信息。
2.为了显示的方便,除了真彩色外,其他的每种颜色模式的行字节数要用数据“00”补齐为4的整数倍。如果显示模式为16色,当图像宽为19时,存储时每行则要补充4-(19/2+1)%4=2个字节(加1是因为里面有一个像素点要独占了一字节)。如果显示模式为256色,当图像宽为19时,每行也要补充4-19%4=1个字节。

24位BMP图片

由上面BMP图片格式可知,24位BMP图像称为真彩色图像,这种位图没有调色板,并且每三个字节代表一个像素,分别对应于R、G、B。对于24位BMP图片,大小计算公式为:图像宽度*图像高度*3字节。

注意:每次读取图片都是三个字节三个字节地读取(分别为BGR),对于图像宽度不是4的整数倍的图片,读取像素的时候需要在读取每一行像素的时候,跳过最后所补的0。计算跳过的0的个数公式如下:4 - ((width * 3 )%4),其中width是图像的宽度。

具体实现代码细节如下:

#include <stdio.h>
#include <stdlib.h>
#include<malloc.h>
#include <string>
#include <iostream>
typedef unsigned char  BYTE;//一字节
typedef unsigned short WORD;//两字节
typedef unsigned long DWORD;//四字节
typedef long LONG;
/* 位图文件头主要是对位图文件的一些描述 位图信息头主要是对位图图像方面信息的描述 *//*************************** 位图标准信息(54字节) ******************************************/
/* 位图文件头 (位图头的字节数 = 位图文件字节数 - 位图图像数据字节数)*/
typedef struct BMP_FILE_HEADER
{//WORD bType;      // 文件标识符,这里为0x4d42 DWORD bSize;     // 文件的大小 WORD bReserved1; // 保留值,必须设置为0  WORD bReserved2; // 保留值,必须设置为0 DWORD bOffset;  // 文件头的最后到图像数据位开始的偏移量,//说明从文件头开始到实际的图象数据之间的字节的偏移量//因为位图信息头和调色板的长度会根据不同情况而变化//所以你可以用这个偏移值迅速的从文件中读取到位数据
} BMPFILEHEADER;    // 14 字节/* 位图信息头 */
typedef struct BMP_INFO
{DWORD bInfoSize;            // 信息头的大小   DWORD bWidth;               // 图像的宽度     DWORD bHeight;              // 图像的高度,如果该值是一个正数,说明图像是倒向的,如果该值是一个负数,则说明图像是正向的。  WORD bPlanes;               // 图像的位面数,其值将总是被设为1 WORD bBitCount;             // 每个像素的位数,这里为 24位DWORD bCompression;         // 压缩类型 DWORD bmpImageSize;         // 图像的大小,以字节为单位 DWORD bXPelsPerMeter;       // 水平分辨率 DWORD bYPelsPerMeter;       // 垂直分辨率 DWORD bClrUsed;             // 位图实际使用的彩色表中的颜色索引数(设为0的话,则说明使用所有调色板项)DWORD bClrImportant;        // 对图象显示有重要影响的颜色索引的数目,如果是0,表示都重要
} BMPINF;            // 40 字节/* 彩色表:调色板 */// 24位的真彩图不需要调色板
typedef struct RGB_QUAD
{WORD rgbBlue;     // 蓝色强度 WORD rgbGreen;    // 绿色强度 WORD rgbRed;      // 红色强度 WORD rgbReversed; // 保留值
} RGBQUAD;//位图数据:这部分的内容根据BMP位图使用的位数不同而不同
//在24位真彩图中,直接使用RGB
//其他的小于24位的则使用调色板中颜色的索引值
typedef struct tagIMAGEDATA
{BYTE blue;BYTE green;BYTE red;
}IMAGEDATA;typedef struct {int width;int height;BYTE  *imageData;}IMAGE;//函数声明
void rotation90();
void rotation270();
void rotation180();
WORD bType;//文件标识符,BMP文件为0x4d42,这里单独读取
BMPFILEHEADER bmpFileHeader;  // 定义一个 BMP 文件头的结构体
BMPINF bmpInfo;               // 定义一个 BMP 文件信息结构体
FILE *fp;                     // 定义一个文件指针
IMAGE *bmpImg = (IMAGE*)malloc(sizeof(IMAGE));             //定义一个bmp指针,并分配地址空间
BYTE  pixVal;               //定义一个一字节的数据int width,height;
int offset;
int i, j, k;int main()
{if ((fp = fopen("pic.bmp", "rb")) == NULL) // fp = 0x00426aa0{printf("Cann't open the file!\n");return 0;}// 让 fp 指向 bmp 文件的开始 // 第 2 个参数是偏移量 第三个参数是文件起始地址 所以此函数执行成功后文件指针会指向文件的开始fseek(fp, 0, SEEK_SET);fread(&bType, sizeof(WORD), 1, fp);//读取文件类型if (bType != 0x4d42){printf("不是bmp文件");return 0;}fread(&bmpFileHeader, sizeof(BMPFILEHEADER), 1, fp);fread(&bmpInfo, sizeof(BMPINF), 1, fp);/*// 输出BMP文件的位图文件头的所有信息printf("位图文件头主要是对位图文件的一些描述:BMPFileHeader\n\n");printf("文件标识符 = 0X%X\n", bType);printf("BMP 文件大小 = %d 字节\n", bmpFileHeader.bSize);printf("保留值1 = %d \n", bmpFileHeader.bReserved1);printf("保留值2 = %d \n", bmpFileHeader.bReserved2);printf("文件头的最后到图像数据位开始的偏移量 = %d 字节\n", bmpFileHeader.bOffset);// 输出BMP文件的位图信息头的所有信息printf("\n\n位图信息头主要是对位图图像方面信息的描述:BMPInfo\n\n");printf("信息头的大小 = %d 字节\n", bmpInfo.bInfoSize);printf("位图的高度 = %d \n", bmpInfo.bHeight);printf("位图的宽度 = %d \n", bmpInfo.bWidth);printf("图像的位面数(位面数是调色板的数量,默认为1个调色板) = %d \n", bmpInfo.bPlanes);printf("每个像素的位数 = %d 位\n", bmpInfo.bBitCount);printf("压缩类型 = %d \n", bmpInfo.bCompression);printf("图像的大小 = %d 字节\n", bmpInfo.bmpImageSize);printf("水平分辨率 = %d \n", bmpInfo.bXPelsPerMeter);printf("垂直分辨率 = %d \n", bmpInfo.bYPelsPerMeter);printf("使用的色彩数 = %d \n", bmpInfo.bClrUsed);printf("重要的色彩数 = %d \n", bmpInfo.bClrImportant);printf("\n\n\n压缩说明:有0(不压缩),1(RLE 8,8位RLE压缩),2(RLE 4,4位RLE压缩,3(Bitfields,位域存放)");fclose(fp);*/width = bmpInfo.bWidth;height = bmpInfo.bHeight;bmpImg->width = width;bmpImg->height = height;bmpImg->imageData = (BYTE*)malloc(sizeof(BYTE)*width*height*3);//如果行的字节数不是4的整数倍,则进行如下处理offset = (3 * width) % 4;if (offset != 0){offset = 4 - offset;}//读取数据for (i = 0; i < height; i++){for (j = 0; j < width; j++){for (k = 0; k < 3; k++){fread(&pixVal, sizeof(BYTE), 1, fp);bmpImg->imageData[i * width * 3 + j * 3 + k] = pixVal;}}if (offset != 0){for (j = 0; j < offset; j++){fread(&pixVal, sizeof(BYTE), 1, fp);}}}//输出数据//将原始图片输出/*for (i = 0; i<height; i++){for (j = 0; j<width; j++){pixVal = bmpImg->imageData[i*bmpImg->width * 3 + j * 3];fwrite(&pixVal, sizeof(BYTE), 1, pFile);pixVal = bmpImg->imageData[i*bmpImg->width * 3 + j * 3 + 1 ];fwrite(&pixVal, sizeof(BYTE), 1, pFile);pixVal = bmpImg->imageData[i*bmpImg->width * 3 + j * 3 + 2 ];fwrite(&pixVal, sizeof(BYTE), 1, pFile);}if (offset != 0){for (j = 0; j<offset; j++){pixVal = 0;fwrite(&pixVal, sizeof(BYTE), 1, pFile); }}}*///rotation90();rotation180();//rotation270();fclose(fp);return 0;}
void rotation180()
{//旋转180度FILE *pFile;pFile = fopen("D:\\C++-work\\rotate180.bmp", "wb");if (!pFile){printf("读取文件失败");}int step = bmpImg->width * 3;offset = step % 4;if (offset != 0){step += 4 - offset;offset = 4 - offset;}fwrite(&bType, sizeof(WORD), 1, pFile);fwrite(&bmpFileHeader, sizeof(BMPFILEHEADER), 1, pFile);fwrite(&bmpInfo, sizeof(BMPINF), 1, pFile);for (i = height-1; i>-1; i--){for (j = width-1; j>-1; j--){pixVal = bmpImg->imageData[i*bmpImg->width * 3 + j * 3];fwrite(&pixVal, sizeof(BYTE), 1, pFile);pixVal = bmpImg->imageData[i*bmpImg->width * 3 + j * 3 + 1];fwrite(&pixVal, sizeof(BYTE), 1, pFile);pixVal = bmpImg->imageData[i*bmpImg->width * 3 + j * 3 + 2];fwrite(&pixVal, sizeof(BYTE), 1, pFile);}if (offset != 0){for (j = 0; j<offset; j++){pixVal = 0;fwrite(&pixVal, sizeof(BYTE), 1, pFile);}}}fclose(pFile);}
void rotation90()
{FILE *pFile;pFile = fopen("D:\\C++-work\\rotate90.bmp", "wb");if (!pFile){printf("读取文件失败");}BMPFILEHEADER new_bmpFileHeader;  // 定义一个 BMP 文件头的结构体BMPINF new_bmpInfo;               // 定义一个 BMP 文件信息结构体 int new_w = bmpInfo.bHeight;int new_h = bmpInfo.bWidth;int step = new_w * 3;int offset = step % 4;if (offset != 0){step += 4 - offset;offset = 4 - offset;}new_bmpFileHeader.bSize = (DWORD)(step * new_h + sizeof(WORD) + sizeof(BMPFILEHEADER) + sizeof(BMPINF));new_bmpFileHeader.bReserved1 = bmpFileHeader.bReserved1;new_bmpFileHeader.bReserved2 = bmpFileHeader.bReserved2;new_bmpFileHeader.bOffset = bmpFileHeader.bOffset;new_bmpInfo.bBitCount = bmpInfo.bBitCount;new_bmpInfo.bClrImportant = bmpInfo.bClrImportant;new_bmpInfo.bClrUsed = bmpInfo.bClrUsed;new_bmpInfo.bCompression = bmpInfo.bCompression;new_bmpInfo.bHeight = bmpInfo.bWidth;new_bmpInfo.bWidth = bmpInfo.bHeight;new_bmpInfo.bInfoSize = bmpInfo.bInfoSize;new_bmpInfo.bmpImageSize = (DWORD)(step * new_h);new_bmpInfo.bPlanes = bmpInfo.bPlanes;new_bmpInfo.bXPelsPerMeter = bmpInfo.bXPelsPerMeter;new_bmpInfo.bYPelsPerMeter = bmpInfo.bYPelsPerMeter;fwrite(&bType, sizeof(WORD), 1, pFile);fwrite(&new_bmpFileHeader, sizeof(BMPFILEHEADER), 1, pFile);fwrite(&new_bmpInfo, sizeof(BMPINF), 1, pFile);//旋转90度for (i = width-1; i>-1; i--){for (j = 0; j<height; j++){pixVal = bmpImg->imageData[j*width * 3 + i * 3];fwrite(&pixVal, sizeof(BYTE), 1, pFile);pixVal = bmpImg->imageData[j*width * 3 + i * 3 + 1];fwrite(&pixVal, sizeof(BYTE), 1, pFile);pixVal = bmpImg->imageData[j*width * 3 + i * 3 + 2];fwrite(&pixVal, sizeof(BYTE), 1, pFile);}if (offset != 0){for (j = 0; j<offset; j++){pixVal = 0;fwrite(&pixVal, sizeof(BYTE), 1, pFile);}}}}
void rotation270()
{FILE *pFile;pFile = fopen("D:\\C++-work\\rotate270.bmp", "wb");if (!pFile){printf("读取文件失败");}BMPFILEHEADER new_bmpFileHeader;  // 定义一个 BMP 文件头的结构体BMPINF new_bmpInfo;               // 定义一个 BMP 文件信息结构体 int new_w = bmpInfo.bHeight;int new_h = bmpInfo.bWidth;int step = new_w * 3;int offset = step % 4;if (offset != 0){step += 4 - offset;offset = 4 - offset;}new_bmpFileHeader.bSize = (DWORD)(step * new_h + sizeof(WORD) + sizeof(BMPFILEHEADER) + sizeof(BMPINF));new_bmpFileHeader.bReserved1 = bmpFileHeader.bReserved1;new_bmpFileHeader.bReserved2 = bmpFileHeader.bReserved2;new_bmpFileHeader.bOffset = bmpFileHeader.bOffset;new_bmpInfo.bBitCount = bmpInfo.bBitCount;new_bmpInfo.bClrImportant = bmpInfo.bClrImportant;new_bmpInfo.bClrUsed = bmpInfo.bClrUsed;new_bmpInfo.bCompression = bmpInfo.bCompression;new_bmpInfo.bHeight = bmpInfo.bWidth;new_bmpInfo.bWidth = bmpInfo.bHeight;new_bmpInfo.bInfoSize = bmpInfo.bInfoSize;new_bmpInfo.bmpImageSize = (DWORD)(step * new_h);new_bmpInfo.bPlanes = bmpInfo.bPlanes;new_bmpInfo.bXPelsPerMeter = bmpInfo.bXPelsPerMeter;new_bmpInfo.bYPelsPerMeter = bmpInfo.bYPelsPerMeter;fwrite(&bType, sizeof(WORD), 1, pFile);fwrite(&new_bmpFileHeader, sizeof(BMPFILEHEADER), 1, pFile);fwrite(&new_bmpInfo, sizeof(BMPINF), 1, pFile);//旋转270度for (i = 0; i<width;i++){for (j = height-1; j>-1; j--){pixVal = bmpImg->imageData[j*width * 3 + i * 3];fwrite(&pixVal, sizeof(BYTE), 1, pFile);pixVal = bmpImg->imageData[j*width * 3 + i * 3 + 1];fwrite(&pixVal, sizeof(BYTE), 1, pFile);pixVal = bmpImg->imageData[j*width * 3 + i * 3 + 2];fwrite(&pixVal, sizeof(BYTE), 1, pFile);}if (offset != 0){for (j = 0; j<offset; j++){pixVal = 0;fwrite(&pixVal, sizeof(BYTE), 1, pFile);}}}}

参考博客:https://blog.csdn.net/carson2005/article/details/6227047

c语言读取24位BMP文件并实现翻转90度、180度、270度相关推荐

  1. c语言读取24位bmp图像,[原创]在TC下显示24位真彩色BMP位图

    [原创]在TC下显示24位真彩色BMP位图 在TC下显示24位BMP 虽然在TC显示24位图像上的速度远远比不上256色的速度快,但是真彩色色彩带给我们的视觉上的冲击是256色远远不能达到的.我们今天 ...

  2. opengl读取24位BMP文件为纹理并处理黑色背景为透明

    原理: 直接用BITMAP数据而未用到AUX库和windows  LoadImage API 24位BItMap文件格式不细说,见度娘 格式要求:24位无压缩位图,必须是2^n*2^n大小 代码(C/ ...

  3. C语言读取和存储bmp格式图片

    开发过程中有时候需要解析bmp数据,下面先简单介绍bmp数据组成,后面附上C语言读取和存储bmp格式图片代码. 典型的位图文件格式通常包含下面几个数据块: BMP文件头:保存位图文件的总体信息. 位图 ...

  4. Java_最不重要位替换(LSB)基于24位BMP图片

    隐写术的一个简单示例 向BMP图片中隐藏一段文字并保存,从保存的图片中提取文字. 原理:把需要隐藏的文本信息转换成二进制字符流,再将其拆分成一个个的0和1,隐藏在像素数据(RGB字节)中,因对RGB的 ...

  5. 【学习笔记】简易的24位BMP图片转换成灰度图片

    简易的24位BMP图片转换成灰度图片的C语言实现 使用C语言实现的一个简易的24位BMP图片转换成灰度图片的程序.需要先准备一张24位的BMP图片. 说明 RGB图片转换成灰度图片主要是使用这个公式: ...

  6. Python读取并解析 bmp 文件

    介绍 由于要开始学习图像方面的知识,读写图片是难免的.对图片的结构有一定的了解对理解图片存储还是很有帮助的.由于实验的代码是用 python 写的,因此读取文件就直接使用 python 了,虽然用 C ...

  7. 纯C++实现24位bmp格式图片的读取和修饰

    问题:现有一张bmp图片,要求将它读取到程序中并进行灰度化.水平翻转.模糊.茶色滤镜四种效果的一种,并输出新图片,如下所示: 命令行输入: 其中: 参数1:-b/g/s/r,先后表示blur(模糊), ...

  8. c++读取8位和24位BMP位图数据 俺的作业

    家人萌 我因为这个作业爆炸了好多天...所以我想发一下 菜鸡一个 别骂别骂 欢迎指正  关于这个作业要先了解一下这些登西... 1)BMP 位图的结构 1.BMP文件头(14字节) ,文件的第0字节到 ...

  9. c++ 24位bmp格式分析

    问题:现有一张bmp图片,要求将它读取到程序中并进行灰度化.水平翻转.模糊.茶色滤镜四种效果的一种,并输出新图片,如下所示: 命令行输入: 其中: 参数1:-b/g/s/r,先后表示blur(模糊), ...

最新文章

  1. hdu 2199 Can you solve this equation? 二分
  2. Python | 新手必会的 9 个 Python 技巧
  3. mysql练习用的数据集下载(转载+自己补充步骤)
  4. centos yum安装_centos7上yum安装碰到的坑
  5. 多线程完成连续打印1-100的数字, 要求一条线程专门打印奇数,另外一条专门用来打印偶数
  6. timer计时 wpf_『WPF』Timer的使用
  7. pcm5102a解码芯片音质评测_精品推荐:用家票选TOP 30款最佳便携式解码耳放(中)...
  8. 查看磁盘文件夹大小工具WinDirStat
  9. 主动学习、纯半监督学习、直推学习的联系与区别
  10. Visual Studio 2017 下创建ASP.NET网站程序详细步骤
  11. python网易云音乐爬虫歌词_一篇文章带你用Python网络爬虫实现网易云音乐歌词抓取...
  12. 不错的一个团队积分互换游戏
  13. 2019.2.21 对自定义页面的修改
  14. 灰狼算法(GWO)优化长短期记忆神经网络的数据回归预测,GWO-LSTM回归预测,多输入单输出模型。
  15. Flink学习之DataStream API(python版本)
  16. Mybatis中的多对一、一对一、一对多
  17. How to recognise a good programmer
  18. Python中的Scapy初探之六--找出非法的DHCP Server
  19. 基于Python的贝壳某城市二手房交易分析及预测系统 文档+项目源码+演示视频
  20. H5+JavaScript 剪刀石头布小游戏完整代码

热门文章

  1. Android SoundPool插入耳机后依然有外放声音
  2. Android Studio的项目太难配置?来看看,手把jio教你~
  3. 【UnityShader】云海效果模拟与视差映射
  4. 2016年清华特等奖答辩(观后感)
  5. Divide by 2 or 3
  6. python 文字转图片支持emoji_求教 Python 如何将字符串转化为 emoji?
  7. android 百度地图批量添加标注,百度地图API实战
  8. vscode同时编辑多行,插入递增数字
  9. RKMEDIA--VP使用
  10. Unity3D导航网格,矩阵旋转,欧拉旋转