这一系列的文章都将以BMP格式图像为主做处理,主要是为了让大家能对图像处理有一个良好的认知,后面会教大家写一个能支持BMP,JPG,JPEG,PNG等格式的图像处理库。

首先你要对图像处理以及图像理论有一个基本的认识,如果没有任何基本的图像知识的话我建议先看一下博主的这篇文章:Opencv学习笔记_计算机视觉是什么?Opencv的起源 虽然说这篇文章是介绍计算机视觉和opencv的但是其中包含了很多图像理论知识。

首先第一步要对BMP图像文件格式要有一个基本的认识:

BMP图像格式详解

一.简介
BMP(Bitmap-File)图形文件是Windows采用的图形文件格式,在Windows环境下运行的所有图象处理软件都支持BMP图象文件格式。Windows系统内部各图像绘制操作都是以BMP为基础的。Windows 3.0以前的BMP图文件格式与显示设备有关,因此把这种BMP图象文件格式称为设备相关位图DDB(device-dependent bitmap)文件格式。Windows 3.0以后的BMP图象文件与显示设备无关,因此把这种BMP图象文件格式称为设备无关位图DIB(device-independent bitmap)格式(注:Windows 3.0以后,在系统中仍然存在DDB位图,象BitBlt()这种函数就是基于DDB位图的,只不过如果你想将图像以BMP格式保存到磁盘文件中时,微软极力推荐你以DIB格式保存),目的是为了让Windows能够在任何类型的显示设备上显示所存储的图象。BMP位图文件默认的文件扩展名是BMP或者bmp(有时它也会以.DIB或.RLE作扩展名)。
二.BMP格式结构
BMP文件的数据按照从文件头开始的先后顺序分为四个部分:
◆ 位图文件头(bmp file header):  提供文件的格式、大小等信息
◆ 位图信息头(bitmap information):提供图像数据的尺寸、位平面数、压缩方式、颜色索引等信息
◆ 调色板(color palette):可选,如使用索引来表示图像,调色板就是索引与其对应的颜色的映射表
◆ 位图数据(bitmap data):图像数据区
BMP图片文件数据表如下:
数据段名称 大小(byte) 开始地址 结束地址
位图文件头(bitmap-file header)
14 0000h 000Dh
位图信息头(bitmap-information header)
40 000Eh 0035h
调色板(color table)
由biBitCount决定 0036h 未知
图片点阵数据(bitmap data)
由图片大小和颜色定 未知 未知
三.BMP文件头
BMP文件头结构体定义如下:
typedef struct tagBITMAPFILEHEADER
UINT16 bfType;        //2Bytes,必须为"BM",即0x424D 才是Windows位图文件
DWORD bfSize;         //4Bytes,整个BMP文件的大小
UINT16 bfReserved1;  //2Bytes,保留,为0
UINT16 bfReserved2;  //2Bytes,保留,为0
DWORD bfOffBits;     //4Bytes,文件起始位置到图像像素数据的字节偏移量
BITMAPFILEHEADER;
BMP文件头数据表如下:
变量名 地址偏移 大小 作用说明
bfType 0000h 2Bytes
文件标识符,必须为"BM",即0x424D 才是Windows位图文件
‘BM’:Windows 3.1x, 95, NT,…  ‘BA’:OS/2 Bitmap Array  ‘CI’:OS/2 Color Icon   
‘CP’:OS/2 Color Pointer   ‘IC’:OS/2 Icon   
‘PT’:OS/2 Pointer
因为OS/2系统并没有被普及开,所以在编程时,你只需判断第一个标识“BM”就行
bfSize 0002h 4Bytes 整个BMP文件的大小(以位B为单位)
bfReserved1 0006h 2Bytes 保留,必须设置为0
bfReserved2 0008h 2Bytes 保留,必须设置为0
bfOffBits 000Ah 4Bytes 说明从文件头0000h开始到图像像素数据的字节偏移量(以字节Bytes为单位),以为位图的调色板长度根据位图格式不同而变化,可以用这个偏移量快速从文件中读取图像数据
四.BMP信息头
BMP信息头结构体定义如下:
typedef struct _tagBMP_INFOHEADER
{
DWORD  biSize;    //4Bytes,INFOHEADER结构体大小,存在其他版本I NFOHEADER,用作区分
LONG   biWidth;    //4Bytes,图像宽度(以像素为单位)
LONG   biHeight;    //4Bytes,图像高度,+:图像存储顺序为Bottom2Top,-:Top2Bottom
WORD   biPlanes;    //2Bytes,图像数据平面,BMP存储RGB数据,因此总为1
WORD   biBitCount;         //2Bytes,图像像素位数
DWORD  biCompression;     //4Bytes,0:不压缩,1:RLE8,2:RLE4
DWORD  biSizeImage;       //4Bytes,4字节对齐的图像数据大小
LONG   biXPelsPerMeter;   //4 Bytes,用象素/米表示的水平分辨率
LONG   biYPelsPerMeter;   //4 Bytes,用象素/米表示的垂直分辨率
DWORD  biClrUsed;          //4 Bytes,实际使用的调色板索引数,0:使用所有的调色板索引
DWORD biClrImportant;     //4 Bytes,重要的调色板索引数,0:所有的调色板索引都重要
}BMP_INFOHEADER;
BMP信息头数据表如下:
变量名
地址偏移
大小
作用说明
biSize
000Eh
4Bytes
BNP信息头即BMP_INFOHEADER结构体所需要的字节数(以字节为单位)
biWidth
0012h
4Bytes
说明图像的宽度(以像素为单位)
biHeight
0016h
4Bytes
说明图像的高度(以像素为单位)。这个值还有一个用处,指明图像是正向的位图还是倒向的位图,该值是正数说明图像是倒向的即图像存储是由下到上;该值是负数说明图像是倒向的即图像存储是由上到下。大多数BMP位图是倒向的位图,所以此值是正值。
biPlanes
001Ah
2Bytes
为目标设备说明位面数,其值总设置为1
biBitCount
001Ch
2Bytes
说明一个像素点占几位(以比特位/像素位单位),其值可为1,4,8,16,24或32
biCompression
001Eh
4Bytes
说明图像数据的压缩类型,取值范围为:
0         BI_RGB 不压缩(最常用)
1         BI_RLE8 8比特游程编码(BLE),只用于8位位图
2         BI_RLE4 4比特游程编码(BLE),只用于4位位图
3         BI_BITFIELDS比特域(BLE),只用于16/32位位图
4          
biSizeImage
0022h
4Bytes
说明图像的大小,以字节为单位。当用BI_RGB格式时,总设置为0
biXPelsPerMeter
0026h
4Bytes
说明水平分辨率,用像素/米表示,有符号整数
biYPelsPerMeter
002Ah
4Bytes
说明垂直分辨率,用像素/米表示,有符号整数
biClrUsed 002Eh 4Bytes 说明位图实际使用的调色板索引数,0:使用所有的调色板索引
biClrImportant 0032h 4Bytes 说明对图像显示有重要影响的颜色索引的数目,如果是0,表示都重要。
五.BMP调色板
BMP调色板结构体定义如下:
typedef struct _tagRGBQUAD
{
BYTE  rgbBlue;       //指定蓝色强度
BYTE  rgbGreen;      //指定绿色强度
BYTE  rgbRed;        //指定红色强度
BYTE  rgbReserved;  //保留,设置为0
RGBQUAD;
1,4,8位图像才会使用调色板数据,16,24,32位图像不需要调色板数据,即调色板最多只需要256项(索引0 - 255)。
颜色表的大小根据所使用的颜色模式而定:2色图像为8字节;16色图像位64字节;256色图像为1024字节。其中,每4字节表示一种颜色,并以B(蓝色)、G(绿色)、R(红色)、alpha(32位位图的透明度值,一般不需要)。即首先4字节表示颜色号1的颜色,接下来表示颜色号2的颜色,依此类推。
颜色表中RGBQUAD结构数据的个数有biBitCount来确定,当biBitCount=1,4,8时,分别有2,16,256个表项。
当biBitCount=1时,为2色图像,BMP位图中有2个数据结构RGBQUAD,一个调色板占用4字节数据,所以2色图像的调色板长度为2*4为8字节。
当biBitCount=4时,为16色图像,BMP位图中有16个数据结构RGBQUAD,一个调色板占用4字节数据,所以16像的调色板长度为16*4为64字节。
当biBitCount=8时,为256色图像,BMP位图中有256个数据结构RGBQUAD,一个调色板占用4字节数据,所以256色图像的调色板长度为256*4为1024字节。
当biBitCount=16,24或32时,没有颜色表。
五.BMP图像数据区
位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右,扫描行之间是从下到上。位图的一个像素值所占的字节数:
当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的倍数
位图数据的大小(不压缩情况下):
DataSize= DataSizePerLine* biHeight;
颜色表接下来位为位图文件的图像数据区,在此部分记录着每点像素对应的颜色号,其记录方式也随颜色模式而定,既2色图像每点占1位(8位为1字节);16色图像每点占4位(半字节);256色图像每点占8位(1字节);真彩色图像每点占24位(3字节)。所以,整个数据区的大小也会随之变化。究其规律而言,可的出如下计算公式:图像数据信息大小=(图像宽度*图像高度*记录像素的位数)/8。

通过上面的描述,我们基本上对BMP图像文件格式有一个基本的认识了,那么我们可以通过c语言的结构体的内存对齐机制来依次读取这些头文件信息,并转化成可识别的十进制信息!

首先第一步,对c语言的基本类型定义别名,方便维护。

//8bit
typedef char UINT_8;
//16bit
typedef char UINT_16[2];
//22bit
typedef char UINT_22[3];
//256bit
typedef char UINT_256[256];
//32bit
typedef int  UINT_32;
//data
typedef char* DATA;
//64 fbit
typedef double FUINT_64;
//16bit int
typedef short SUINT_16;

然后根据头信息在文件中的字节偏移地址来定义结构体:

变量名 地址偏移 大小 作用说明
bfType 0000h 2Bytes
文件标识符,必须为"BM",即0x424D 才是Windows位图文件
‘BM’:Windows 3.1x, 95, NT,…  ‘BA’:OS/2 Bitmap Array  ‘CI’:OS/2 Color Icon   
‘CP’:OS/2 Color Pointer   ‘IC’:OS/2 Icon   
‘PT’:OS/2 Pointer
因为OS/2系统并没有被普及开,所以在编程时,你只需判断第一个标识“BM”就行
bfSize 0002h 4Bytes 整个BMP文件的大小(以位B为单位)
bfReserved1 0006h 2Bytes 保留,必须设置为0
bfReserved2 0008h 2Bytes 保留,必须设置为0
bfOffBits 000Ah 4Bytes 说明从文件头0000h开始到图像像素数据的字节偏移量(以字节Bytes为单位),以为位图的调色板长度根据位图格式不同而变化,可以用这个偏移量快速从文件中读取图像数据
变量名
地址偏移
大小
作用说明
biSize
000Eh
4Bytes
BNP信息头即BMP_INFOHEADER结构体所需要的字节数(以字节为单位)
biWidth
0012h
4Bytes
说明图像的宽度(以像素为单位)
biHeight
0016h
4Bytes
说明图像的高度(以像素为单位)。这个值还有一个用处,指明图像是正向的位图还是倒向的位图,该值是正数说明图像是倒向的即图像存储是由下到上;该值是负数说明图像是倒向的即图像存储是由上到下。大多数BMP位图是倒向的位图,所以此值是正值。
biPlanes
001Ah
2Bytes
为目标设备说明位面数,其值总设置为1
biBitCount
001Ch
2Bytes
说明一个像素点占几位(以比特位/像素位单位),其值可为1,4,8,16,24或32
biCompression
001Eh
4Bytes
说明图像数据的压缩类型,取值范围为:
0         BI_RGB 不压缩(最常用)
1         BI_RLE8 8比特游程编码(BLE),只用于8位位图
2         BI_RLE4 4比特游程编码(BLE),只用于4位位图
3         BI_BITFIELDS比特域(BLE),只用于16/32位位图
4          
biSizeImage
0022h
4Bytes
说明图像的大小,以字节为单位。当用BI_RGB格式时,总设置为0
biXPelsPerMeter
0026h
4Bytes
说明水平分辨率,用像素/米表示,有符号整数
biYPelsPerMeter
002Ah
4Bytes
说明垂直分辨率,用像素/米表示,有符号整数
biClrUsed 002Eh 4Bytes 说明位图实际使用的调色板索引数,0:使用所有的调色板索引
biClrImportant 0032h 4Bytes 说明对图像显示有重要影响的颜色索引的数目,如果是0,表示都重要。
注意这里一定要使用#pragma pack(1)告诉编译器结构体按1字节对齐(详细:详解C语言内存对齐)否则在读入文件流数据时会出现数据混淆的原因
//结构体
//图像结构体,防止结构体对齐否则读取文件流时出错,所以用pragma命令强制对齐
#pragma pack(1)
typedef struct image_struct{UINT_16   image_pil;                //文件标识符  UINT_32   image_Size;               //文件大小  UINT_16   image_Reserved1;          //无需过问  UINT_16   image_Reserved2;          //无需过问  UINT_32   image_Offbits;            //头文件到图像数据偏移量  UINT_32   image_Stsize;             //结构体所需大小  UINT_32   image_Width;              //图像宽度  UINT_32   image_Height;             //图像高度  UINT_16   image_Planes;             //目标设备位面数  SUINT_16  image_Bitcount;           //像素点占用多少bit位  UINT_32   image_Compression;        //图像压缩类型  UINT_32   image_Sizeimage;          //图像的大小  UINT_32   image_Xpelspermeter;      //水平分辨率  UINT_32   image_Ypelspermeter;      //垂直分辨率  UINT_32   image_ClrUsed;            //调色板索引数  UINT_32   image_Clrlmportant;       //图像显示重要颜色索引数目  DATA      image_Data;               //图像数据 UINT_32   image_Data_Size;           //图像数据大小
}image;
#pragma pack()  
下面开始写我们的第一个函数:image_load,加载图像文件
注意如果不使用c语言的内存对齐方式读取数据的话需要考虑大小端的问题,我们直接使用结构体来读取这样就不用考虑大小端的问题了,因为内存中的存储大小端与文件中是对应的!我们只需要直接读取到内存当中就行了!
//函数
//加载图像
int image_load(struct image_struct** im, char *path){FILE *image_path_fp;image_path_fp = fopen(path, "rb");if (image_path_fp == NULL){return -1;}//取文件大小fseek(image_path_fp, 0, SEEK_END); //定位到文件末 int nFileLen = ftell(image_path_fp); //文件长度fseek(image_path_fp, 0, SEEK_SET); //恢复到文件头,防止从文件尾读取数据//读取头信息if (fread((*im), (sizeof(struct image_struct) - ((sizeof(DATA/*image_Data*/)+(sizeof(UINT_32)/*image_Data_Size*/)))/*暂不读取数据,无法从头文件中获取数据偏移量,防止数据混乱*/), 1, image_path_fp) == 0){return -2;}//给data变量分配内存(*im)->image_Data = (DATA)malloc(nFileLen-(*im)->image_Offbits/*完整的数据大小*/);//判断是否分配成功if ((*im)->image_Data == NULL){    //如果没有可用堆内存则malloc返回NULLreturn -3;}//读取数据//读取前将文件指针挪移到文件头信息后,找到正确的数据存储区fseek(image_path_fp, 0, SEEK_SET);    //恢复到文件头,因为已经fread一次了,所以数据文件指针发生变更fseek(image_path_fp, (*im)->image_Offbits, SEEK_CUR);    //忽略头数据if (fread((*im)->image_Data, (nFileLen - (*im)->image_Offbits/*file - off = 实际大小*/), 1, image_path_fp) == 0){return -4;}//保存文件大小,方便读写操作(*im)->image_Data_Size = (nFileLen - (*im)->image_Offbits/*file - off = 实际大小*/);//文件指针释放,防止占用文件内核的临界资源fclose(image_path_fp);image_path_fp == NULL;return 0;
}
图像加载函数写完了,我们可能在使用结构体时会定义指针,所以为了方便我们在写一个用于分配内存的函数
//给图像数据分配内存
int image_malloc(struct image_struct** im){*im = (struct image_struct*)malloc(sizeof(struct image_struct));if (*im == NULL){return -1;}return 0;
}
还需要一个图像保存函数:
//保存图像数据到文件
int image_save_file(struct image_struct** im, char *path){FILE* file_fp = fopen(path, "wb+");   //以二进制可读写方式打开if (file_fp == NULL){    //判断文件指针是否为空return -1;}//写入头信息fwrite((*im), (*im)->image_Offbits/*直接写入头文件到数据的偏移量大小即可*/, 1, file_fp);//写入文件数据fwrite((*im)->image_Data, (*im)->image_Data_Size, 1, file_fp);return 0;}
基本函数编写完成了,那么来做一个测试吧:
int main(){image *imga;image_malloc(&imga);image_load(&imga, "test.bmp");printf("图像宽度:%d\n", imga->image_Width); printf("图像高度:%d\n", imga->image_Height);printf("图像文件占用字节:%d\n", imga->image_Size);printf("图像每个像素占用bit位:%d\n", imga->image_Bitcount);getchar();
}
完整代码:

/*Robust图像处理库
*版本:v1.0
*作者:周志豪
*4.17 19:09
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//类型定义
//8bit
typedef char UINT_8;
//16bit
typedef char UINT_16[2];
//22bit
typedef char UINT_22[3];
//256bit
typedef char UINT_256[256];
//32bit
typedef int  UINT_32;
//data
typedef char* DATA;
//64 fbit
typedef double FUINT_64;
//16bit int
typedef short SUINT_16;
//结构体
//图像结构体,防止结构体对齐否则读取文件流时出错,所以用pragma命令强制对齐
#pragma pack(1)
typedef struct image_struct{UINT_16   image_pil;                //文件标识符  UINT_32   image_Size;               //文件大小  UINT_16   image_Reserved1;          //无需过问  UINT_16   image_Reserved2;          //无需过问  UINT_32   image_Offbits;            //头文件到图像数据偏移量  UINT_32   image_Stsize;             //结构体所需大小  UINT_32   image_Width;              //图像宽度  UINT_32   image_Height;             //图像高度  UINT_16   image_Planes;             //目标设备位面数  SUINT_16  image_Bitcount;           //像素点占用多少bit位  UINT_32   image_Compression;        //图像压缩类型  UINT_32   image_Sizeimage;          //图像的大小  UINT_32   image_Xpelspermeter;      //水平分辨率  UINT_32   image_Ypelspermeter;      //垂直分辨率  UINT_32   image_ClrUsed;            //调色板索引数  UINT_32   image_Clrlmportant;       //图像显示重要颜色索引数目  DATA      image_Data;               //图像数据 UINT_32   image_Data_Size;           //图像数据大小
}image;
#pragma pack()
//函数
//加载图像
int image_load(struct image_struct** im, char *path){FILE *image_path_fp;image_path_fp = fopen(path, "rb");if (image_path_fp == NULL){return -1;}//取文件大小fseek(image_path_fp, 0, SEEK_END); //定位到文件末 int nFileLen = ftell(image_path_fp); //文件长度fseek(image_path_fp, 0, SEEK_SET); //恢复到文件头,防止从文件尾读取数据//读取头信息if (fread((*im), (sizeof(struct image_struct) - ((sizeof(DATA/*image_Data*/)+(sizeof(UINT_32)/*image_Data_Size*/)))/*暂不读取数据,无法从头文件中获取数据偏移量,防止数据混乱*/), 1, image_path_fp) == 0){return -2;}//给data变量分配内存(*im)->image_Data = (DATA)malloc(nFileLen-(*im)->image_Offbits/*完整的数据大小*/);//判断是否分配成功if ((*im)->image_Data == NULL){    //如果没有可用堆内存则malloc返回NULLreturn -3;}//读取数据//读取前将文件指针挪移到文件头信息后,找到正确的数据存储区fseek(image_path_fp, 0, SEEK_SET);    //恢复到文件头,因为已经fread一次了,所以数据文件指针发生变更fseek(image_path_fp, (*im)->image_Offbits, SEEK_CUR);    //忽略头数据if (fread((*im)->image_Data, (nFileLen - (*im)->image_Offbits/*file - off = 实际大小*/), 1, image_path_fp) == 0){return -4;}//保存文件大小,方便读写操作(*im)->image_Data_Size = (nFileLen - (*im)->image_Offbits/*file - off = 实际大小*/);//文件指针释放,防止占用文件内核的临界资源fclose(image_path_fp);image_path_fp == NULL;return 0;
}
//给图像数据分配内存
int image_malloc(struct image_struct** im){*im = (struct image_struct*)malloc(sizeof(struct image_struct));if (*im == NULL){return -1;}return 0;
}
//将图像转换成反向图_该方法只能用于真彩图
int image_reverse_rgb(struct image_struct** im){if ((*im) == NULL){   //判断传递进来的图像指针是否为空return -1;}//转换成反向图很简单只需要将每个图像里的像素点转换成负的就可以了,注意在一个24位的图像文件中一个字节对应一个颜色值三个字节则为一个完整的像素点,所以我们一个一个像素点的转换就可以了//算法公式为:S=-R-G-Bfor (int i = 0; i < (*im)->image_Data_Size; ++i){if ((*im)->image_Data[i] == (int)0){  //如果等于0则不处理continue;    //开始下一次循环}//i*(*im)->image_Width + j(*im)->image_Data[i] = -(*im)->image_Data[i];    //调用宏函数转换}return 0;
}
//保存图像数据到文件
int image_save_file(struct image_struct** im, char *path){FILE* file_fp = fopen(path, "wb+");   //以二进制可读写方式打开if (file_fp == NULL){    //判断文件指针是否为空return -1;}//写入头信息fwrite((*im), (*im)->image_Offbits/*直接写入头文件到数据的偏移量大小即可*/, 1, file_fp);//写入文件数据fwrite((*im)->image_Data, (*im)->image_Data_Size, 1, file_fp);return 0;}
int main(){image *imga;image_malloc(&imga);image_load(&imga, "test.bmp");printf("图像宽度:%d\n", imga->image_Width); printf("图像高度:%d\n", imga->image_Height);printf("图像文件占用字节:%d\n", imga->image_Size);printf("图像每个像素占用bit位:%d\n", imga->image_Bitcount);getchar();
}
运行结果:

本篇先让大家对BMP格式有一个基本的认知,和读取图像头信息中较为重要的信息

一步一步使用标c编写跨平台图像处理库相关推荐

  1. 一步一步使用标c编写跨平台图像处理库_让一个图像变成反向图像

    接着上一章 一步一步使用标c编写跨平台图像处理库,本章将介绍如何让一个图像变成反向图,其原理非常简单,只需要让每个像素点上的RGB三色取反即可!变成负数! 其公式为: s = -r-g-b 转换方式: ...

  2. [教程]JS从糊涂到明白:一步一步编写计算器2 – 简化代码

     [文章原始发表:This Is WWW : http://www.plrsoft.cn/blog/?p=69  转载请注明出处]  我在上一篇文章"一步一步编写计算器 – 构建和兼容&qu ...

  3. 一步一步实现STM32-FOTA系列教程之Bootloader编写

    一步一步实现STM32-FOTA系列教程之Bootloader编写 文章系列链接 <一步一步实现STM32-FOTA系列教程之bin文件生成> <一步一步实现STM32-FOTA系列 ...

  4. 【深度学习基础】一步一步讲解卷积神经网络

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送 本文转自:一步一步讲解卷积神经网络 卷积神经网络(Convoluti ...

  5. 一步一步学Silverlight 2系列(10):使用用户控件

    概述 Silverlight 2 Beta 1版本发布了,无论从Runtime还是Tools都给我们带来了很多的惊喜,如支持框架语言Visual Basic, Visual C#, IronRuby, ...

  6. 通过脚本案例学习shell(五) 通过创建DNS脚本一步一步教你将一个普通脚本规范到一个生产环境脚本...

    通过脚本案例学习shell(五) 通过创建DNS脚本一步一步教你将一个普通脚本规范到一个生产环境脚本   版权声明: 本文遵循"署名非商业性使用相同方式共享 2.5 中国大陆"协议 ...

  7. 一步一步学Silverlight 2系列(24):与浏览器交互相关辅助方法

    概述 Silverlight 2 Beta 1版本发布了,无论从Runtime还是Tools都给我们带来了很多的惊喜,如支持框架语言Visual Basic, Visual C#, IronRuby, ...

  8. 一步一步写算法(之prim算法 中)

    原文:一步一步写算法(之prim算法 中) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] C)编写最小生成树,涉及创建.挑选和添加过程 MI ...

  9. Python之美[从菜鸟到高手]--一步一步动手给Python写扩展(异常处理和引用计数)

    我们将继续一步一步动手给Python写扩展,通过上一篇我们学习了如何写扩展,本篇将介绍一些高级话题,如异常,引用计数问题等.强烈建议先看上一篇,Python之美[从菜鸟到高手]--一步一步动手给Pyt ...

最新文章

  1. 基于html5海贼王单页视差滚动特效
  2. 使用FFT来计算IFFT
  3. 学习编写用例是开发者走向项目经理的必经之路(《编写有效用例》书评) ——“Jolt大奖精选丛书”有奖征文...
  4. 洛谷1522牛的旅行
  5. 《Exchange Server 2010 SP1/SP2管理实践》一2.2 部署域名解析网络环境
  6. 海信电视服务器暂时不可用,一线也实惠 微星H61M-E35(B3)主板评测
  7. 实战演练:PostgreSQL在线扩容
  8. 概要设计 英文_JavaScript 中的位运算和权限设计
  9. 装配图中齿轮的画法_机械制图如何从入门到精通,金属结构件的表达画法,你会吗?...
  10. iOS Socket 客户端 基本使用
  11. 文化学刊杂志文化学刊杂志社文化学刊编辑部2022年第3期目录
  12. 计算机网络ppt背景,教大家使用ppt设计出高逼格的背景图
  13. mysql_stmt_precheck_COM_STMT_PREPARE 1
  14. Python向已有数据的Excel表写入数据
  15. 回顾过去。。展望未来
  16. wlop作品集_【图包】【wlop】作品合集
  17. 微软面试题:红帽子与黑帽子
  18. 毕节职业技术学院计算机网络技术专业,毕节职业技术学院计算机网络技术9.顶岗实习安排...
  19. VTM1.0代码阅读:CU、PU、TU
  20. InetAddress类常用方法

热门文章

  1. mysql主从复制原理详解_深入研究MySQL(三)、主从复制原理及演示
  2. xilinx set up debug
  3. gitee创建ssh公钥
  4. str python3_python3.4.3如何转换str字符串?
  5. python读写excel模块pandas_python3 基于pandas读写Excel
  6. springMVC+hibernate + layui分页
  7. object转换成Integer
  8. dist包编译html_npm package开发指南-包内容篇
  9. py2exe打包python_Python打包-py2exe使用
  10. python3d绘图代码_python机器学习之3D Matplotlib绘图