1 代码
包含三个文件:把bmp.h、bmp.cpp、main.cpp
1.1 bmp.h
#pragma once
#include <cstdio>
#include <cstdlib>
using namespace std;
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned int DWORD;
//位图文件头定义
typedef struct tagBITMAPFILEHEADER {
// WORD bfType;//单独读取,结构体中就不定义了
DWORD bfSize;//文件大小
WORD bfReserved1;//保留字
WORD bfReserved2;//保留字
DWORD bfOffBits;//从文件头到实际位图数据的偏移字节数
}BITMAPFILEHEADER;
//位图信息头定义
typedef struct tagBITMAPINFOHEADER {
DWORD biSize;//信息头大小
DWORD biWidth;//图像宽度
DWORD biHeight;//图像高度
WORD biPlanes;//位平面数,必须为1
WORD biBitCount;//每像素位数
DWORD biCompression; //压缩类型
DWORD biSizeImage; //压缩图像大小字节数
DWORD biXPelsPerMeter; //水平分辨率
DWORD biYPelsPerMeter; //垂直分辨率
DWORD biClrUsed; //位图实际用到的色彩数
DWORD biClrImportant; //本位图中重要的色彩数
}BITMAPINFOHEADER; //位图信息头定义
//彩色图像的像素信息
typedef struct tagRgbImgData
{
BYTE blue;
BYTE green;
BYTE red;
}DATA;
// 灰度图像的像素信息
typedef struct tagGrayBmpData
{
BYTE gray;
}GRAYDATA;
// 调色板的结构定义,灰度图有256个调色板
typedef struct tagRGBQUAD {
BYTE rgbBlue; // 蓝色的亮度(值范围为0-255)
BYTE rgbGreen; // 绿色的亮度(值范围为0-255)
BYTE rgbRed; // 红色的亮度(值范围为0-255)
BYTE rgbReserved;// 保留,必须为0
} RGBQUAD;
double xAfterRot(int x, int y, double theta, int cx, int cy);
double yAfterRot(int x, int y, double theta, int cx, int cy);
// 检查图片类型是不是BMP
int checkImgType(const char* filename);
// 彩色BMP图像读取操作
DATA* readRgbBmp(const char* filename, WORD* bfType, BITMAPFILEHEADER* strHead, BITMAPINFOHEADER* strInfo, int* h, int* mw, int* imgSize, int* cx, int* cy);
// 灰色BMP图像读取操作
GRAYDATA* readGrayBmp(const char* filename, WORD* bfType, BITMAPFILEHEADER* strHead, BITMAPINFOHEADER* strInfo, RGBQUAD* ipRGB, int* h, int* mw, int* imgSize, int* cx, int* cy);
int modifyWidth(int biWidth);
int getImageSize(int biWidth, int biHeight, int bitCount);
DATA* scale(const DATA* src, float x, float y, int mh, int mw, int imgSize, int cx, int cy, BITMAPFILEHEADER strHead, BITMAPINFOHEADER strInfo, WORD bfType);
GRAYDATA* scaleGray(const GRAYDATA* src, float x, float y, int mh, int mw, int imgSize, int cx, int cy, BITMAPFILEHEADER strHead, BITMAPINFOHEADER strInfo, WORD bfType, RGBQUAD* ipRGB);
DATA* rotation(const DATA* src, double theta, int mh, int mw, int imgSize, int cx, int cy, BITMAPFILEHEADER strHead, BITMAPINFOHEADER strInfo, WORD bfType);
GRAYDATA* rotationGray(const GRAYDATA* src, double theta, int mh, int mw,
int imgSize, int cx, int cy, BITMAPFILEHEADER strHead, BITMAPINFOHEADER strInfo,WORD bfType, RGBQUAD* ipRGB);
1. 2 bmp.cpp
#include <cstdio>
#include <iostream>
#include <vector>
#include<algorithm>
#include <cmath>
#define PI acos(-1)
#include <cstdlib>
#include<exception>
#include<set>
#include "bmp.h"
using namespace std;
int checkImgType(const char* filename) {
FILE* fpi = fopen(filename, "rb");
WORD bfType;
if (fpi == NULL) {
cout << filename << " 文件未能找到" << endl;
return 0;
}
else {
fread(&bfType, 1, sizeof(WORD), fpi);
if (0x4d42 != bfType) {
cout << "Error: The file is not a bmp image!" << endl;
return 0;
}
}
return 1;
}
int modifyWidth(int biWidth) {
if (biWidth % 4 == 0)
return biWidth;
return (biWidth / 4 + 1) * 4;
}
int getImageSize(int biWidth, int biHeight, int bitCount) {
int bytePerPixel = bitCount / 8;
int LineBytes = (biWidth * bytePerPixel + 3) / 4 * 4; //这个其实也相当于是每行的宽度,但是这里的宽度指的是字节数,而不是像素数
return LineBytes * biWidth;
}
DATA * readRgbBmp(const char* filename, WORD * bfType, BITMAPFILEHEADER* strHead, BITMAPINFOHEADER* strInfo, int* h, int* mw, int* imgSize, int * cx, int* cy) {
FILE* fpi = fopen(filename, "rb");
fread(bfType, 1, sizeof(WORD), fpi);
fread(strHead, 1, sizeof(tagBITMAPFILEHEADER), fpi);
fread(strInfo, 1, sizeof(tagBITMAPINFOHEADER), fpi);
*h = (*strInfo).biHeight;
*mw = modifyWidth((*strInfo).biWidth);
*imgSize = (*h) * (*mw);
*cx = (*mw) / 2;
*cy = (*h) / 2;
DATA* imgData = new DATA[*imgSize];
fread(imgData, 1, sizeof(DATA) * (*imgSize), fpi);
return imgData;
}
GRAYDATA* readGrayBmp(const char* filename, WORD* bfType, BITMAPFILEHEADER* strHead, BITMAPINFOHEADER* strInfo, RGBQUAD