通过我这些天用C++读写bmp图像的经历,摸索再摸索,终于对bmp文件的结构、操作有了一定的了解,下面就大概介绍bmp图片纯C++的读取、旋转和保存的实现过程。

要用C++读取bmp图片文件,首先要弄清楚bmp格式图片文件的结构。可以参考这篇文章:http://blog.csdn.net/xiajun07061225/article/details/5813726

有几点需要注意的是:

在读取bmp图片的时候,一定要注意内存对齐的问题,譬如文件头,否则无法读取出正确结果。

关于图片的像素数据,每一行的像素的字节数必须是4的整数倍。如果不是,则需要补齐。一般来说,bmp图像文件的数据是从下到上,从左到右的。即从文件中最先读到的是图像最下面一行的左边第一个像素,然后是坐标第二个.....接下来是倒数第二行的第一个像素。

采用的编译环境是VS2008。

关于图像旋转,并不难。只需要搞清楚像素坐标变换公式就行。我以图像的中心点为坐标原点。先把像素在目标图像中的位置变化为坐标系中的位置,做旋转变换求出变换之前的在坐标系中的坐标,再变换为在图片中的位置。

公式:(x1,y1)是变换之前的坐标系中的坐标,(x2,y2)是变换之后的坐标系中的坐标。angle为逆时针旋转的角度数。

x1 = cos(angle)*x2-sin(angle)*y2;
y1 = sin(angle)*x2-cos(angle)*y2;

我的代码分为两个版本:灰度图的和彩色图的。

灰度图:

灰度图是只含亮度信息,不含彩色信息的图像。bmp格式文件中并没有灰度图这个概念,但是我们很容易地用bmp文件来表示灰度图。方法是用256色的调色板,只不过这个调色板有点特殊,每一项的RGB值都是相同的,从(0,0,0),(1,1,1),...,一直到(255,255,255)。这样,灰度图就可以用256色图来表示了。其图像数据就是调色板索引值,也就是实际的RGB的亮度值。另外因为是256色的调色板,所以图像数据中的一个字节代表一个像素。如果是彩色的256色图,图像处理后可能会产生不属于这256色的颜色,所以,图像处理一般采用灰度图。这也可以更好地将重点放在算法上。

下面是灰度图旋转代码,能处理任意尺寸的bmp灰度图,以及旋转任意角度(逆时针)。

代码包括两个文件:BmpRot.h和BmpRot.cpp

BmpRot.h:

typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned int DWORD;
typedef long LONG;//位图文件头定义;
//其中不包含文件类型信息(由于结构体的内存结构决定,
//要是加了的话将不能正确读取文件信息)
typedef struct  tagBITMAPFILEHEADER{//WORD bfType;//文件类型,必须是0x424D,即字符“BM”DWORD bfSize;//文件大小WORD bfReserved1;//保留字WORD bfReserved2;//保留字DWORD bfOffBits;//从文件头到实际位图数据的偏移字节数
}BITMAPFILEHEADER;typedef struct tagBITMAPINFOHEADER{DWORD biSize;//信息头大小LONG biWidth;//图像宽度LONG biHeight;//图像高度WORD biPlanes;//位平面数,必须为1WORD biBitCount;//每像素位数DWORD  biCompression; //压缩类型DWORD  biSizeImage; //压缩图像大小字节数LONG  biXPelsPerMeter; //水平分辨率LONG  biYPelsPerMeter; //垂直分辨率DWORD  biClrUsed; //位图实际用到的色彩数DWORD  biClrImportant; //本位图中重要的色彩数
}BITMAPINFOHEADER; //位图信息头定义typedef struct tagRGBQUAD{BYTE rgbBlue; //该颜色的蓝色分量BYTE rgbGreen; //该颜色的绿色分量BYTE rgbRed; //该颜色的红色分量BYTE rgbReserved; //保留值
}RGBQUAD;//调色板定义//像素信息
typedef struct tagIMAGEDATA
{BYTE blue;//BYTE green;//BYTE red;
}IMAGEDATA;

BmpRot.cpp:

#include <stdio.h>
#include "BmpRot.h"
#include "stdlib.h"
#include "math.h"
#include <iostream>#define PI 3.14159//圆周率宏定义
#define LENGTH_NAME_BMP 30//bmp图片文件名的最大长度using namespace std;//变量定义
BITMAPFILEHEADER strHead;
RGBQUAD strPla[256];//256色调色板
BITMAPINFOHEADER strInfo;//显示位图文件头信息
void showBmpHead(BITMAPFILEHEADER pBmpHead){cout<<"位图文件头:"<<endl;cout<<"文件大小:"<<pBmpHead.bfSize<<endl;cout<<"保留字_1:"<<pBmpHead.bfReserved1<<endl;cout<<"保留字_2:"<<pBmpHead.bfReserved2<<endl;cout<<"实际位图数据的偏移字节数:"<<pBmpHead.bfOffBits<<endl<<endl;
}void showBmpInforHead(tagBITMAPINFOHEADER pBmpInforHead){cout<<"位图信息头:"<<endl;cout<<"结构体的长度:"<<pBmpInforHead.biSize<<endl;cout<<"位图宽:"<<pBmpInforHead.biWidth<<endl;cout<<"位图高:"<<pBmpInforHead.biHeight<<endl;cout<<"biPlanes平面数:"<<pBmpInforHead.biPlanes<<endl;cout<<"biBitCount采用颜色位数:"<<pBmpInforHead.biBitCount<<endl;cout<<"压缩方式:"<<pBmpInforHead.biCompression<<endl;cout<<"biSizeImage实际位图数据占用的字节数:"<<pBmpInforHead.biSizeImage<<endl;cout<<"X方向分辨率:"<<pBmpInforHead.biXPelsPerMeter<<endl;cout<<"Y方向分辨率:"<<pBmpInforHead.biYPelsPerMeter<<endl;cout<<"使用的颜色数:"<<pBmpInforHead.biClrUsed<<endl;cout<<"重要颜色数:"<<pBmpInforHead.biClrImportant<<endl;
}int main(){char strFile[LENGTH_NAME_BMP];//bmp文件名IMAGEDATA *imagedata = NULL;//动态分配存储原图片的像素信息的二维数组IMAGEDATA *imagedataRot = NULL;//动态分配存储旋转后的图片的像素信息的二维数组int width,height;//图片的宽度和高度cout<<"请输入所要读取的文件名:"<<endl;cin>>strFile;FILE *fpi,*fpw;fpi=fopen(strFile,"rb");if(fpi != NULL){//先读取文件类型WORD bfType;fread(&bfType,1,sizeof(WORD),fpi);if(0x4d42!=bfType){cout<<"the file is not a bmp file!"<<endl;return NULL;}//读取bmp文件的文件头和信息头fread(&strHead,1,sizeof(tagBITMAPFILEHEADER),fpi);//showBmpHead(strHead);//显示文件头fread(&strInfo,1,sizeof(tagBITMAPINFOHEADER),fpi);//showBmpInforHead(strInfo);//显示文件信息头//读取调色板for(unsigned int nCounti=0;nCounti<strInfo.biClrUsed;nCounti++){fread((char *)&(strPla[nCounti].rgbBlue),1,sizeof(BYTE),fpi);fread((char *)&(strPla[nCounti].rgbGreen),1,sizeof(BYTE),fpi);fread((char *)&(strPla[nCounti].rgbRed),1,sizeof(BYTE),fpi);fread((char *)&(strPla[nCounti].rgbReserved),1,sizeof(BYTE),fpi);}width = strInfo.biWidth;height = strInfo.biHeight;//图像每一行的字节数必须是4的整数倍width = (width * sizeof(IMAGEDATA) + 3) / 4 * 4;//imagedata = (IMAGEDATA*)malloc(width * height * sizeof(IMAGEDATA));imagedata = (IMAGEDATA*)malloc(width * height);imagedataRot = (IMAGEDATA*)malloc(2 * width * 2 * height * sizeof(IMAGEDATA));//初始化原始图片的像素数组for(int i = 0;i < height;++i){for(int j = 0;j < width;++j){(*(imagedata + i * width + j)).blue = 0;//(*(imagedata + i * width + j)).green = 0;//(*(imagedata + i *  width + j)).red = 0;}}//初始化旋转后图片的像素数组for(int i = 0;i < 2 * height;++i){for(int j = 0;j < 2 * width;++j){(*(imagedataRot + i * 2 * width + j)).blue = 0;//(*(imagedataRot + i * 2 * width + j)).green = 0;//(*(imagedataRot + i * 2 * width + j)).red = 0;}}//fseek(fpi,54,SEEK_SET);//读出图片的像素数据fread(imagedata,sizeof(struct tagIMAGEDATA) * width,height,fpi);fclose(fpi);}else{cout<<"file open error!"<<endl;return NULL;}//图片旋转处理int RotateAngle;//要旋转的角度数double angle;//要旋转的弧度数int midX_pre,midY_pre,midX_aft,midY_aft;//旋转所围绕的中心点的坐标midX_pre = width / 2;midY_pre = height / 2;midX_aft = width;midY_aft = height;int pre_i,pre_j,after_i,after_j;//旋转前后对应的像素点坐标cout<<"输入要旋转的角度(0度到360度,逆时针旋转):"<<endl;cin>>RotateAngle;angle = 1.0 * RotateAngle * PI / 180;for(int i = 0;i < 2 * height;++i){for(int j = 0;j < 2 * width;++j){after_i = i - midX_aft;//坐标变换after_j = j - midY_aft;pre_i = (int)(cos((double)angle) * after_i - sin((double)angle) * after_j) + midX_pre;pre_j = (int)(sin((double)angle) * after_i + cos((double)angle) * after_j) + midY_pre;if(pre_i >= 0 && pre_i < height && pre_j >= 0 && pre_j < width)//在原图范围内*(imagedataRot + i * 2 * width + j) = *(imagedata + pre_i * width + pre_j);}}//保存bmp图片if((fpw=fopen("b.bmp","wb"))==NULL){cout<<"create the bmp file error!"<<endl;return NULL;}WORD bfType_w=0x4d42;fwrite(&bfType_w,1,sizeof(WORD),fpw);//fpw +=2;fwrite(&strHead,1,sizeof(tagBITMAPFILEHEADER),fpw);strInfo.biWidth = 2 * width;strInfo.biHeight = 2 * height;fwrite(&strInfo,1,sizeof(tagBITMAPINFOHEADER),fpw);//保存调色板数据for(unsigned int nCounti=0;nCounti<strInfo.biClrUsed;nCounti++){fwrite(&strPla[nCounti].rgbBlue,1,sizeof(BYTE),fpw);fwrite(&strPla[nCounti].rgbGreen,1,sizeof(BYTE),fpw);fwrite(&strPla[nCounti].rgbRed,1,sizeof(BYTE),fpw);fwrite(&strPla[nCounti].rgbReserved,1,sizeof(BYTE),fpw);}//保存像素数据for(int i =0;i < 2 * height;++i){for(int j = 0;j < 2 * width;++j){fwrite( &((*(imagedataRot + i * 2 * width + j)).blue),1,sizeof(BYTE),fpw);//fwrite( &((*(imagedataRot + i * 2 * width + j)).green),1,sizeof(BYTE),fpw);//fwrite( &((*(imagedataRot + i * 2 * width + j)).red),1,sizeof(BYTE),fpw);}}fclose(fpw);//释放内存delete[] imagedata;delete[] imagedataRot;
}

数据测试:

旋转前和旋转后的对比(45度):

彩色图:

彩色图的处理和灰度图略有不一样。主要是像素数据不同。由于每行数据的字节数必须是4的整数倍,这个地方处理起来要比灰度图麻烦很多,多以暂时还 没做好。本程序的局限性就是只能处理尺寸是4的整数倍的图片,可以旋转任意角度(逆时针)。

参考代码:分两个文件:BmpRot.h和BmpRot.cpp

BmpRot.h:

typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned int DWORD;
typedef long LONG;//位图文件头定义;
//其中不包含文件类型信息(由于结构体的内存结构决定,
//要是加了的话将不能正确读取文件信息)
typedef struct  tagBITMAPFILEHEADER{//WORD bfType;//文件类型,必须是0x424D,即字符“BM”DWORD bfSize;//文件大小WORD bfReserved1;//保留字WORD bfReserved2;//保留字DWORD bfOffBits;//从文件头到实际位图数据的偏移字节数
}BITMAPFILEHEADER;typedef struct tagBITMAPINFOHEADER{DWORD biSize;//信息头大小LONG biWidth;//图像宽度LONG biHeight;//图像高度WORD biPlanes;//位平面数,必须为1WORD biBitCount;//每像素位数DWORD  biCompression; //压缩类型DWORD  biSizeImage; //压缩图像大小字节数LONG  biXPelsPerMeter; //水平分辨率LONG  biYPelsPerMeter; //垂直分辨率DWORD  biClrUsed; //位图实际用到的色彩数DWORD  biClrImportant; //本位图中重要的色彩数
}BITMAPINFOHEADER; //位图信息头定义typedef struct tagRGBQUAD{BYTE rgbBlue; //该颜色的蓝色分量BYTE rgbGreen; //该颜色的绿色分量BYTE rgbRed; //该颜色的红色分量BYTE rgbReserved; //保留值
}RGBQUAD;//调色板定义//像素信息
typedef struct tagIMAGEDATA
{BYTE red;BYTE green;BYTE blue;
}IMAGEDATA;

BmpRot.cpp:

#include <stdio.h>
#include "BmpRot.h"
#include "stdlib.h"
#include "math.h"
#include <iostream>#define PI 3.14159//圆周率宏定义
#define LENGTH_NAME_BMP 30//bmp图片文件名的最大长度using namespace std;//变量定义
BITMAPFILEHEADER strHead;
RGBQUAD strPla[256];//256色调色板
BITMAPINFOHEADER strInfo;//显示位图文件头信息
void showBmpHead(BITMAPFILEHEADER pBmpHead){cout<<"位图文件头:"<<endl;cout<<"文件大小:"<<pBmpHead.bfSize<<endl;cout<<"保留字_1:"<<pBmpHead.bfReserved1<<endl;cout<<"保留字_2:"<<pBmpHead.bfReserved2<<endl;cout<<"实际位图数据的偏移字节数:"<<pBmpHead.bfOffBits<<endl<<endl;
}void showBmpInforHead(tagBITMAPINFOHEADER pBmpInforHead){cout<<"位图信息头:"<<endl;cout<<"结构体的长度:"<<pBmpInforHead.biSize<<endl;cout<<"位图宽:"<<pBmpInforHead.biWidth<<endl;cout<<"位图高:"<<pBmpInforHead.biHeight<<endl;cout<<"biPlanes平面数:"<<pBmpInforHead.biPlanes<<endl;cout<<"biBitCount采用颜色位数:"<<pBmpInforHead.biBitCount<<endl;cout<<"压缩方式:"<<pBmpInforHead.biCompression<<endl;cout<<"biSizeImage实际位图数据占用的字节数:"<<pBmpInforHead.biSizeImage<<endl;cout<<"X方向分辨率:"<<pBmpInforHead.biXPelsPerMeter<<endl;cout<<"Y方向分辨率:"<<pBmpInforHead.biYPelsPerMeter<<endl;cout<<"使用的颜色数:"<<pBmpInforHead.biClrUsed<<endl;cout<<"重要颜色数:"<<pBmpInforHead.biClrImportant<<endl;
}int main(){char strFile[LENGTH_NAME_BMP];//bmp文件名IMAGEDATA *imagedata = NULL;//动态分配存储原图片的像素信息的二维数组IMAGEDATA *imagedataRot = NULL;//动态分配存储旋转后的图片的像素信息的二维数组int width,height;//图片的宽度和高度cout<<"请输入所要读取的文件名:"<<endl;cin>>strFile;FILE *fpi,*fpw;fpi=fopen(strFile,"rb");if(fpi != NULL){//先读取文件类型WORD bfType;fread(&bfType,1,sizeof(WORD),fpi);if(0x4d42!=bfType){cout<<"the file is not a bmp file!"<<endl;return NULL;}//读取bmp文件的文件头和信息头fread(&strHead,1,sizeof(tagBITMAPFILEHEADER),fpi);//showBmpHead(strHead);//显示文件头fread(&strInfo,1,sizeof(tagBITMAPINFOHEADER),fpi);//showBmpInforHead(strInfo);//显示文件信息头//读取调色板for(unsigned int nCounti=0;nCounti<strInfo.biClrUsed;nCounti++){//存储的时候,一般去掉保留字rgbReservedfread((char *)&strPla[nCounti].rgbBlue,1,sizeof(BYTE),fpi);fread((char *)&strPla[nCounti].rgbGreen,1,sizeof(BYTE),fpi);fread((char *)&strPla[nCounti].rgbRed,1,sizeof(BYTE),fpi);cout<<"strPla[nCounti].rgbBlue"<<strPla[nCounti].rgbBlue<<endl;cout<<"strPla[nCounti].rgbGreen"<<strPla[nCounti].rgbGreen<<endl;cout<<"strPla[nCounti].rgbRed"<<strPla[nCounti].rgbRed<<endl;}width = strInfo.biWidth;height = strInfo.biHeight;imagedata = (IMAGEDATA*)malloc(width * height * sizeof(IMAGEDATA));imagedataRot = (IMAGEDATA*)malloc(2 * width * 2 * height * sizeof(IMAGEDATA));//初始化原始图片的像素数组for(int i = 0;i < height;++i){for(int j = 0;j < width;++j){(*(imagedata + i * width + j)).blue = 0;(*(imagedata + i * width + j)).green = 0;(*(imagedata + i *  width + j)).red = 0;}}//初始化旋转后图片的像素数组for(int i = 0;i < 2 * height;++i){for(int j = 0;j < 2 * width;++j){(*(imagedataRot + i * 2 * width + j)).blue = 0;(*(imagedataRot + i * 2 * width + j)).green = 0;(*(imagedataRot + i * 2 * width + j)).red = 0;}}//fseek(fpi,54,SEEK_SET);//读出图片的像素数据fread(imagedata,sizeof(struct tagIMAGEDATA) * width,height,fpi);/*for(int i = 0;i < height;++i){fread(imagedata + i * width * sizeof(IMAGEDATA),sizeof(struct tagIMAGEDATA) * width,height,fpi);}*/fclose(fpi);}else{cout<<"file open error!"<<endl;return NULL;}//图片旋转处理int RotateAngle;//要旋转的角度数double angle;//要旋转的弧度数int midX_pre,midY_pre,midX_aft,midY_aft;//旋转所围绕的中心点的坐标midX_pre = width / 2;midY_pre = height / 2;midX_aft = width;midY_aft = height;int pre_i,pre_j,after_i,after_j;//旋转前后对应的像素点坐标cout<<"输入要旋转的角度(0度到360度,逆时针旋转):"<<endl;cin>>RotateAngle;angle = 1.0 * RotateAngle * PI / 180;for(int i = 0;i < 2 * height;++i){for(int j = 0;j < 2 * width;++j){after_i = i - midY_aft;//坐标变换after_j = j - midX_aft;pre_i = (int)(cos((double)angle) * after_i - sin((double)angle) * after_j) + midY_pre;pre_j = (int)(sin((double)angle) * after_i + cos((double)angle) * after_j) + midX_pre;if(pre_i >= 0 && pre_i < height && pre_j >= 0 && pre_j < width)//在原图范围内*(imagedataRot + i * 2 * width + j) = *(imagedata + pre_i * width + pre_j);}}//保存bmp图片if((fpw=fopen("b.bmp","wb"))==NULL){cout<<"create the bmp file error!"<<endl;return NULL;}WORD bfType_w=0x4d42;fwrite(&bfType_w,1,sizeof(WORD),fpw);//fpw +=2;fwrite(&strHead,1,sizeof(tagBITMAPFILEHEADER),fpw);strInfo.biWidth = 2 * width;strInfo.biHeight = 2 * height;fwrite(&strInfo,1,sizeof(tagBITMAPINFOHEADER),fpw);//保存调色板数据for(unsigned int nCounti=0;nCounti<strInfo.biClrUsed;nCounti++){fwrite(&strPla[nCounti].rgbBlue,1,sizeof(BYTE),fpw);fwrite(&strPla[nCounti].rgbGreen,1,sizeof(BYTE),fpw);fwrite(&strPla[nCounti].rgbRed,1,sizeof(BYTE),fpw);}//保存像素数据for(int i =0;i < 2 * height;++i){for(int j = 0;j < 2 * width;++j){fwrite( &(*(imagedataRot + i * 2 * width + j)).red,1,sizeof(BYTE),fpw);//注意三条语句的顺序:否则颜色会发生变化fwrite( &(*(imagedataRot + i * 2 * width + j)).green,1,sizeof(BYTE),fpw);fwrite( &(*(imagedataRot + i * 2 * width + j)).blue,1,sizeof(BYTE),fpw);}}fclose(fpw);//释放内存delete[] imagedata;delete[] imagedataRot;
}

数据测试:(旋转10°)

注意:颜色问题已解决。请看代码中注释部分。

我的宫伀号【编程学习指南】有更多编程学习干货,欢迎围观~

【数字图像处理】C++读取、旋转和保存bmp图像文件编程实现相关推荐

  1. MATLAB数字图像处理(一)——图像打开、保存与显示

    文章目录 准备工作 读入与显示图像 分离RGB图像 添加噪声 准备工作 本篇博客所用图像都保存在Matlab安装目录下的\toolbox\images\imdemos子目录中.我们在当前matlab新 ...

  2. 数字图像处理基础——读取并显示图片

    © Fu Xianjun. All Rights Reserved 1.图像读取 代码: import cv2 img = cv2.imread("dog.jpg") import ...

  3. VC数字图像处理编程

    本文转自:http://www.rosoo.net/a/200909/7444.html 前 言 数字图像处理技术与理论是计算机应用的一个重要领域,许多工程应用都涉及到图像处理. 图是物体透射光或反射 ...

  4. C++ 保存bmp图片

    在 C 语言中,你可以使用 Windows 图像处理库(Windows GDI)来保存 BMP 图片.你需要使用到两个重要的函数:CreateBitmap 和 SaveBitmap. CreateBi ...

  5. 数字图像处理的研究方法

    数字图像处理是近年来电子.通讯和计算机等领域的热门研究领域,其在科研.经济.军事.娱乐等等国计民生的各个领域都具有非常广阔的应用前景.数字图像处理处是一门交叉学科,涉及数学.计算机.电子.通讯.物理等 ...

  6. 【数字图像处理】BMP图片的读取显示存储(C语言实现)

    (一)背景介绍 这段时间接到了一个新活,是关于图像处理的一个探地摄像头的项目.所以也差不多是时候开始学习一下数字图像处理的知识了.本来我们的方案是直接移植opencv,编译一下以后其他就基本啥都不用管 ...

  7. 数字图像处理实验(一)|图像的基本操作和基本统计指标计算{图像读取imread、图像写入imwrite、图像显示imshow、图像的相关统计量|均值、方差、大小尺寸裁减旋转|}(附实验代码和实验截图)

    文章目录 一.实验目的 二.实验主要仪器设备 三.实验原理 (1)将一幅图像视为一个二维矩阵. (2)利用MATLAB图像处理工具箱读.写和显示图像文件. (3)计算图像的有关统计参数. (4)改变图 ...

  8. 【数字图像处理】一.MFC详解显示BMP格式图片

    本文主要是讲述<数字图像处理>系列栏目中的第一篇文章.主要详细介绍了BMP图片格式,同时使用C++和MFC显示BMP格式,主要结合自己的<数字图像处理>课程和以前的项目叙述讲解 ...

  9. Matlab数字图像处理——图像文件的读取

    文章目录 一.Matlab中获取图像信息的函数 imfinfo 二.Matlab读取图像文件的函数 imread 三.Matlab保存图像文件的函数 imwrite 完整目录 一.Matlab中获取图 ...

最新文章

  1. Oracle的REGEXP_INSTR再mysql中实现
  2. DeepMind论文:深度压缩感知,新框架提升GAN性能
  3. 为什么我的电脑输入法的图标和原来的活动窗口离得那么远
  4. 【数据结构与算法】之深入解析“组合总和Ⅳ”的求解思路与算法示例
  5. 查看服务器物理内存大小,如何看服务器的物理内存大小
  6. Java EE 7是最终版本。 思想,见解和进一步的指针。
  7. iphone数据迁移到新iphone_Mac专业iPhone数据恢复软件----Omni Recover
  8. (life)新的一年新的一页
  9. 全站仪和手机连接软件_不懂全站仪?看这篇就够用了
  10. Android:eclipse新建android工程style文件里的Theme老是报错
  11. Intellig idea导入项目第一次运行报错- Error running ‘Application‘: Command line is too long—— 解决方法
  12. 甘特图制作_甘特图是用什么软件制作?
  13. MySQL 报错:Translating SQLException with SQL state '42000', error code '1064', message
  14. 第一行代码(Android)第二版PDF和源码
  15. 企业信息化整体架构图
  16. Windows 变慢原因分析及解决方法
  17. 我为什么建议大家一定要考研?
  18. 简单的复习下箭头函式
  19. Dpark的安装测试
  20. Python 使用Pandas在原有Excel文件中创建子表格

热门文章

  1. [Unity][FlowCanvas] FlowScript 搜索功能不可用的解决办法:更新 UnityEditor 的版本
  2. [有限元] 四结点三角形单元和五结点三角形单元的形函数
  3. vue框架:变更页面background背景颜色 - 代码篇
  4. phpcms 怎样实现PC端、手机端的双模版
  5. linux 关闭自动升级,开启关闭Centos的自动更新(转)
  6. khv是什么虚拟服务器,服务器虚拟化vSphere4 vs Hyper-V R2,选择谁?
  7. 机器学习实战 基于_机器学习实战:基于Scikit-Learn和TensorFlow—第四章笔记
  8. 快约 - PHP社交约会平台源码开心版
  9. wireshark 十六进制过滤_Wireshark过滤表达式大全
  10. mysql升级后乱码_Mysql转换或者升级以后出现乱码情况的说明