BMP图像格式

xiaoxiao2021-02-28  82

文件参照:http://blog.csdn.net/o_sun_o/article/details/8351037

代码:

.h 文件:  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;//位平面数,必须为1 WORD 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;

.cpp文件: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;//图片的宽度和高度 const char *txtname = "C://Users//Administrator//Desktop//ConsoleApplication2//HS1P-2013-07-24-15-30.txt"; //cout << "请输入所要读取的文件名:" << endl; //cin >> strFile; FILE *fpi, *fpw; //fpi = fopen(strFile, "rb"); fpi = fopen("10.bmp", "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);//显示文件信息头 unsigned char *bmpData = new unsigned char[strInfo.biHeight*strInfo.biWidth * 3]; fseek(fpi, strHead.bfOffBits, SEEK_SET); fread(bmpData, 1, strInfo.biHeight*strInfo.biWidth * 3, fpi); FILE *temp; if ((temp = fopen(txtname, "wb")) == NULL)//写TXT文件 { cout << "the file can not be built!" << endl; exit(1); } for (int i = 0; i<strInfo.biHeight; i++) { for (int j = 0; j<strInfo.biWidth; j++) { fprintf(temp, "%d ", bmpData[i*strInfo.biWidth * 3 + j * 3]); fprintf(temp, "%d ", bmpData[i*strInfo.biWidth * 3 + j * 3 + 1]); fprintf(temp, "%d \n", bmpData[i*strInfo.biWidth * 3 + j * 3 + 2]); //fprintf(temp,"%d ",bmpData[i*bmpInfHeader.biWidth + j]);//黑白图像 } fprintf(temp, "\n"); } //读取调色板 for (unsigned int nCounti = 0; nCounti<strInfo.biClrUsed; nCounti++) { //存储的时候,一般去掉保留字rgbReserved 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); 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) { cout << (*(imagedataRot + i * 2 * width + j)).blue << endl; (*(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; }

如果出现错误:

 warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

 

解决方法: 右击工程 - 属性 - 配置属性 - C/C++  -预处理器-预处理器定义

 

命令行增加 _CRT_SECURE_NO_WARNINGS

转载请注明原文地址: https://www.6miu.com/read-19585.html

最新回复(0)