620 lines
18 KiB
C++
620 lines
18 KiB
C++
#include "image.h"
|
||
#include <cstdio>
|
||
#include <cstdlib>
|
||
#include <string>
|
||
#include <cstring>
|
||
using namespace std;
|
||
//普通构造函数
|
||
Image::Image(int h, int w) :height(h), width(w)
|
||
{
|
||
this->height = h;
|
||
this->width = w;
|
||
// 动态分配二维数组存储像素数据,注意先申请一个存放指针的数组,
|
||
data = (unsigned char **)malloc(sizeof(unsigned char*) * this->height);
|
||
//其大小为sizeof(unsigned char*) * bitmapinfoheader.biHeight,这点很容易错
|
||
//申请行指针
|
||
for (int i = 0; i < this->height; i++)
|
||
{
|
||
//注意3通道,每个像素3个字节
|
||
data[i] = (unsigned char *)malloc(this->width * 3);
|
||
// 读取像素数据
|
||
for (int j = 0; j < this->width; j++)
|
||
{
|
||
data[i][j] = 0;
|
||
}
|
||
}
|
||
}
|
||
Image::Image(int h, int w, unsigned char val)//创建的图像像素值都为val;
|
||
{
|
||
this->height = h;
|
||
this->width = w;
|
||
// 动态分配二维数组存储像素数据,注意先申请一个存放指针的数组,
|
||
data = (unsigned char **)malloc(sizeof(unsigned char*) * this->height);
|
||
//其大小为sizeof(unsigned char*) * bitmapinfoheader.biHeight,这点很容易错
|
||
//申请行指针
|
||
for (int i = 0; i < this->height; i++)
|
||
{
|
||
//注意3通道,每个像素3个字节
|
||
data[i] = (unsigned char *)malloc(this->width * 3);
|
||
// 读取像素数据
|
||
for (int j = 0; j < this->width; j++)
|
||
{
|
||
data[i][j] = val;
|
||
}
|
||
}
|
||
}
|
||
Image::Image(const char* ImageName)//利用文件名从硬盘加载图像文件成为Image对象;
|
||
{
|
||
this->ReadBMP(ImageName);
|
||
}
|
||
Image::Image(unsigned char *m, int rows, int cols)//从一维静态数组创建Image对象,图像的行数和列数由后面两个参数给出;
|
||
{
|
||
this->height = rows;
|
||
this->width = cols;
|
||
// 动态分配二维数组存储像素数据,注意先申请一个存放指针的数组,
|
||
data = (unsigned char **)malloc(sizeof(unsigned char*) * this->height);
|
||
//其大小为sizeof(unsigned char*) * bitmapinfoheader.biHeight,这点很容易错
|
||
//申请行指针
|
||
for (int i = 0; i < this->height; i++)
|
||
{
|
||
//注意3通道,每个像素3个字节
|
||
data[i] = (unsigned char *)malloc(this->width * 3);
|
||
// 读取像素数据
|
||
for (int j = 0; j < this->width; j++)
|
||
{
|
||
data[i][j] = *m;
|
||
m++;
|
||
}
|
||
}
|
||
}
|
||
Image::Image(unsigned char m[][100], int rows)//从静态二维数组创建Image对象,图像的行数(二维数组的第一个维度)由第二个参数rows给出;
|
||
{
|
||
this->height = rows;
|
||
this->width = 100;
|
||
// 动态分配二维数组存储像素数据,注意先申请一个存放指针的数组,
|
||
data = (unsigned char **)malloc(sizeof(unsigned char*) * this->height);
|
||
//其大小为sizeof(unsigned char*) * bitmapinfoheader.biHeight,这点很容易错
|
||
//申请行指针
|
||
for (int i = 0; i < this->height; i++)
|
||
{
|
||
//注意3通道,每个像素3个字节
|
||
data[i] = (unsigned char *)malloc(this->width * 3);
|
||
// 读取像素数据
|
||
for (int j = 0; j < this->width; j++)
|
||
{
|
||
data[i][j] = m[i][j];
|
||
}
|
||
}
|
||
}
|
||
Image::Image(unsigned char **m, int h, int w)//从动态数组(二级指针)创建Image对象,图像的行数和列数由后面两个参数给出;
|
||
{
|
||
this->height = h;
|
||
this->width = w;
|
||
// 动态分配二维数组存储像素数据,注意先申请一个存放指针的数组,
|
||
data = (unsigned char **)malloc(sizeof(unsigned char*) * this->height);
|
||
//其大小为sizeof(unsigned char*) * bitmapinfoheader.biHeight,这点很容易错
|
||
//申请行指针
|
||
for (int i = 0; i < this->height; i++)
|
||
{
|
||
//注意3通道,每个像素3个字节
|
||
data[i] = (unsigned char *)malloc(this->width * 3);
|
||
// 读取像素数据
|
||
for (int j = 0; j < this->width; j++)
|
||
{
|
||
data[i][j] = m[i][j];
|
||
}
|
||
}
|
||
}
|
||
//拷贝构造函数
|
||
Image::Image(Image &im)
|
||
{
|
||
if (this->data)
|
||
{
|
||
delete[] this->data;
|
||
this->data = NULL;
|
||
}
|
||
|
||
*this = im;
|
||
}
|
||
|
||
|
||
//释放堆区数据
|
||
void Image::myFree(unsigned char** data, int h)
|
||
{
|
||
for (int i = 0; i < h; i++)
|
||
{
|
||
free(data[i]);
|
||
data[i] = NULL;
|
||
}
|
||
free(data);
|
||
data = NULL;
|
||
puts("释放堆区数据");
|
||
}
|
||
//析构函数
|
||
Image::~Image()
|
||
{
|
||
this->myFree(this->data, this->height);
|
||
}
|
||
|
||
|
||
//从硬盘读入图像文件,存储到image类中
|
||
void Image::ReadBMP(const char* filename)
|
||
{
|
||
FILE* fp = NULL; // C标准库的文件指针
|
||
fp = fopen(filename, "rb"); // 二进制读取方式打开文件
|
||
|
||
// 读取文件头
|
||
fread(&bmpfileheader, sizeof(bmpfileheader), 1, fp);
|
||
// 读取信息头
|
||
fread(&bitmapinfoheader, sizeof(bitmapinfoheader), 1, fp);
|
||
|
||
// 动态分配二维数组存储像素数据,注意先申请一个存放指针的数组,
|
||
data = (unsigned char **)malloc(sizeof(unsigned char*) * bitmapinfoheader.biHeight);
|
||
//其大小为sizeof(unsigned char*) * bitmapinfoheader.biHeight,这点很容易错
|
||
//申请行指针
|
||
for (int i = 0; i < bitmapinfoheader.biHeight; i++)
|
||
{
|
||
//注意3通道,每个像素3个字节
|
||
data[i] = (unsigned char *)malloc(bitmapinfoheader.biWidth * 3);
|
||
// 读取像素数据
|
||
for (int j = 0; j < bitmapinfoheader.biWidth * 3; j++)
|
||
{
|
||
fread(&data[i][j], 1, 1, fp);
|
||
}
|
||
}
|
||
this->height = this->bitmapinfoheader.biHeight;
|
||
this->width = this->bitmapinfoheader.biWidth;
|
||
printf("height = %d width = %d\n",this->height,this->width);
|
||
|
||
// 关闭读取的文件
|
||
fclose(fp);
|
||
}
|
||
|
||
|
||
//保存bmp图像
|
||
void Image::WriteBMP(const char *filename)
|
||
{
|
||
FILE* fp = NULL; // 保存文件的文件指针
|
||
fp = fopen(filename, "wb"); // 二进制写入方式打开文件
|
||
// 写入文件头
|
||
fwrite(&bmpfileheader, sizeof(bmpfileheader), 1, fp);
|
||
// 写入信息头
|
||
fwrite(&bitmapinfoheader, sizeof(bitmapinfoheader), 1, fp);
|
||
// 写入数据
|
||
for (int i = 0; i < bitmapinfoheader.biHeight; i++)
|
||
{
|
||
fwrite(data[i], bitmapinfoheader.biWidth * 3, 1, fp);
|
||
}
|
||
// 关闭写入的文件
|
||
fclose(fp);
|
||
}
|
||
//保存bmp图像
|
||
void Image::WriteBMP(const char *filename, unsigned char** data)
|
||
{
|
||
FILE* fp = NULL; // 保存文件的文件指针
|
||
fp = fopen(filename, "wb"); // 二进制写入方式打开文件
|
||
// 写入文件头
|
||
fwrite(&bmpfileheader, sizeof(bmpfileheader), 1, fp);
|
||
// 写入信息头
|
||
fwrite(&bitmapinfoheader, sizeof(bitmapinfoheader), 1, fp);
|
||
// 写入数据
|
||
for (int i = 0; i < bitmapinfoheader.biHeight; i++)
|
||
{
|
||
fwrite(data[i], bitmapinfoheader.biWidth * 3, 1, fp);
|
||
}
|
||
// 关闭写入的文件
|
||
fclose(fp);
|
||
}
|
||
//保存bmp图像
|
||
void Image::WriteBMP(const char *filename, unsigned char** t_data,
|
||
BMPFILEHEADER bmpfileheader, BITMAPINFOHEADER t_bitmapinfoheader)
|
||
{
|
||
FILE* fp = NULL; // 保存文件的文件指针
|
||
fp = fopen(filename, "wb"); // 二进制写入方式打开文件
|
||
// 写入文件头
|
||
fwrite(&bmpfileheader, sizeof(bmpfileheader), 1, fp);
|
||
// 写入信息头
|
||
fwrite(&t_bitmapinfoheader, sizeof(t_bitmapinfoheader), 1, fp);
|
||
// 写入数据
|
||
for (int i = 0; i < t_bitmapinfoheader.biHeight; i++)
|
||
{
|
||
fwrite(t_data[i], t_bitmapinfoheader.biWidth * 3, 1, fp);
|
||
}
|
||
// 关闭写入的文件
|
||
fclose(fp);
|
||
}
|
||
|
||
|
||
//从文本文件读取
|
||
void Image::ReadText(const char* filename)
|
||
{
|
||
FILE* fp = NULL; // C标准库的文件指针
|
||
fp = fopen(filename, "rb"); // 二进制读取方式打开文件
|
||
|
||
fread(&bitmapinfoheader.biHeight, sizeof(bitmapinfoheader.biHeight), 1, fp);
|
||
fread(&bitmapinfoheader.biWidth, sizeof(bitmapinfoheader.biWidth), 1, fp);
|
||
|
||
// 动态分配二维数组存储像素数据,注意先申请一个存放指针的数组,
|
||
data = (unsigned char **)malloc(sizeof(unsigned char*) * bitmapinfoheader.biHeight);
|
||
//其大小为sizeof(unsigned char*) * bitmapinfoheader.biHeight,这点很容易错
|
||
//申请行指针
|
||
for (int i = 0; i < bitmapinfoheader.biHeight; i++)
|
||
{
|
||
//注意3通道,每个像素3个字节
|
||
data[i] = (unsigned char *)malloc(bitmapinfoheader.biWidth * 3);
|
||
// 读取像素数据
|
||
for (int j = 0; j < bitmapinfoheader.biWidth * 3; j++)
|
||
{
|
||
fread(&data[i][j], 1, 1, fp);
|
||
}
|
||
}
|
||
|
||
// 关闭读取的文件
|
||
fclose(fp);
|
||
}
|
||
//保存成文本文件
|
||
void Image::WriteText(const char *filename)
|
||
{
|
||
FILE* fp = NULL; // 保存文件的文件指针
|
||
fp = fopen(filename, "wb"); // 二进制写入方式打开文件
|
||
// 写入信息头
|
||
fwrite(&bitmapinfoheader.biHeight, sizeof(bitmapinfoheader.biHeight), 1, fp);
|
||
fwrite(&bitmapinfoheader.biWidth, sizeof(bitmapinfoheader.biWidth), 1, fp);
|
||
// 写入数据
|
||
for (int i = 0; i < bitmapinfoheader.biHeight; i++)
|
||
{
|
||
fwrite(data[i], bitmapinfoheader.biWidth * 3, 1, fp);
|
||
}
|
||
// 关闭写入的文件
|
||
fclose(fp);
|
||
}
|
||
|
||
|
||
//获取图像中指定点的值
|
||
unsigned char& Image::At(int row, int col)
|
||
{
|
||
return this->data[row * 3][col * 3];
|
||
}
|
||
//设置像素(row,col)为某值
|
||
void Image::Set(int row, int col, unsigned char value)
|
||
{
|
||
//重新读取数据
|
||
unsigned char** t_data = (unsigned char**)malloc(sizeof(unsigned char*) * bitmapinfoheader.biHeight);
|
||
for (int i = 0; i < bitmapinfoheader.biHeight; i++)
|
||
{
|
||
t_data[i] = (unsigned char*)malloc(bitmapinfoheader.biWidth * 3);
|
||
for (int j = 0; j < bitmapinfoheader.biWidth * 3; j++)
|
||
{
|
||
t_data[i][j] = data[i][j];
|
||
}
|
||
}
|
||
//修改像数值
|
||
for (int i = 0; i < 3; i++)
|
||
{
|
||
t_data[row * 3 + i][col * 3 + i] = value;
|
||
}
|
||
//保存图像
|
||
this->WriteBMP("setImg.bmp", t_data);
|
||
myFree(t_data, bitmapinfoheader.biHeight);
|
||
}
|
||
//设置图像所有像素为同一值
|
||
void Image::Set(unsigned char value)
|
||
{
|
||
//重新读取数据
|
||
unsigned char** t_data = (unsigned char**)malloc(sizeof(unsigned char*) * bitmapinfoheader.biHeight);
|
||
for (int i = 0; i < bitmapinfoheader.biHeight; i++)
|
||
{
|
||
t_data[i] = (unsigned char*)malloc(bitmapinfoheader.biWidth * 3);
|
||
for (int j = 0; j < bitmapinfoheader.biWidth * 3; j++)
|
||
{
|
||
t_data[i][j] = data[i][j];
|
||
}
|
||
}
|
||
//修改像数值
|
||
for (int i = 0; i < this->bitmapinfoheader.biHeight; i++)
|
||
{
|
||
for (int j = 0; j < this->bitmapinfoheader.biWidth * 3; j++)
|
||
{
|
||
t_data[i][j] = value;
|
||
}
|
||
}
|
||
//保存图像
|
||
this->WriteBMP("setAllImg.bmp", t_data);
|
||
myFree(t_data, bitmapinfoheader.biHeight);
|
||
}
|
||
|
||
|
||
//false 左右,true 上下
|
||
void Image::Flip(int code)
|
||
{
|
||
//重新读取数据
|
||
unsigned char** t_data = (unsigned char**)malloc(sizeof(unsigned char*) * bitmapinfoheader.biHeight);
|
||
for (int i = 0; i < bitmapinfoheader.biHeight; i++)
|
||
{
|
||
t_data[i] = (unsigned char*)malloc(bitmapinfoheader.biWidth * 3);
|
||
for (int j = 0; j < bitmapinfoheader.biWidth * 3; j++)
|
||
{
|
||
t_data[i][j] = data[i][j];
|
||
}
|
||
}
|
||
|
||
if (code)
|
||
{
|
||
//上下翻转图片
|
||
for (int i = 0; i < bitmapinfoheader.biHeight / 2; i++)
|
||
{
|
||
unsigned char* temp = t_data[i];
|
||
t_data[i] = t_data[bitmapinfoheader.biHeight - 1 - i];
|
||
t_data[bitmapinfoheader.biHeight - 1 - i] = temp;
|
||
}
|
||
this->WriteBMP("flipImageUpDown.bmp",t_data);
|
||
}
|
||
else
|
||
{
|
||
//左右翻转图片
|
||
for (int i = 0; i < bitmapinfoheader.biHeight; i++)
|
||
{
|
||
for (int j = 0; j < bitmapinfoheader.biWidth * 3 / 2; j += 3)
|
||
{
|
||
unsigned char temp = t_data[i][j];
|
||
t_data[i][j] = t_data[i][bitmapinfoheader.biWidth * 3 - 1 - j - 2];
|
||
t_data[i][bitmapinfoheader.biWidth * 3 - 1 - j - 2] = temp;
|
||
|
||
unsigned char temp1 = t_data[i][j+1];
|
||
t_data[i][j + 1] = t_data[i][bitmapinfoheader.biWidth * 3 - 1 - j - 1];
|
||
t_data[i][bitmapinfoheader.biWidth * 3 - 1 - j - 1] = temp1;
|
||
|
||
unsigned char temp2 = t_data[i][j + 2];
|
||
t_data[i][j+2] = t_data[i][bitmapinfoheader.biWidth * 3 - 1 - j];
|
||
t_data[i][bitmapinfoheader.biWidth * 3 - 1 - j] = temp2;
|
||
}
|
||
}
|
||
this->WriteBMP("flipImageLeftRight.bmp",t_data);
|
||
}
|
||
|
||
this->myFree(t_data, this->bitmapinfoheader.biHeight);
|
||
}
|
||
|
||
|
||
//图像缩小,放大
|
||
//false缩小,true放大
|
||
void Image::Resize(int code)
|
||
{
|
||
if (code)//放大
|
||
{
|
||
/* *
|
||
*难点主要在于对索引的控制,
|
||
*因为这里需要两个索引控制四个变量,需要找到它们对应的关系式
|
||
*/
|
||
unsigned char** t_data = (unsigned char**)malloc(sizeof(unsigned char*) * bitmapinfoheader.biHeight * 2);
|
||
for (int i = 0; i < bitmapinfoheader.biHeight ; i++)
|
||
{
|
||
t_data[2 * i] = (unsigned char*)malloc(bitmapinfoheader.biWidth * 3 * 2);
|
||
for (int j = 0; j < bitmapinfoheader.biWidth; j++)
|
||
{
|
||
t_data[2 * i][6 * j] = data[i][3 * j];
|
||
t_data[2 * i][6 * j + 1] = data[i][3 * j + 1];
|
||
t_data[2 * i][6 * j + 2] = data[i][3 * j + 2];
|
||
|
||
t_data[2 * i][6 * j + 3] = data[i][3 * j];
|
||
t_data[2 * i][6 * j + 3 + 1] = data[i][3 * j + 1];
|
||
t_data[2 * i][6 * j + 3 + 2] = data[i][3 * j + 2];
|
||
}
|
||
|
||
t_data[2 * i + 1] = (unsigned char*)malloc(bitmapinfoheader.biWidth * 3 * 2);
|
||
for (int j = 0; j < bitmapinfoheader .biWidth * 6; j++)
|
||
{
|
||
t_data[2 * i + 1][j] = t_data[2 * i][j];
|
||
}
|
||
}
|
||
|
||
BMPFILEHEADER t_bmpfileheader = this->bmpfileheader;
|
||
BITMAPINFOHEADER t_bitmapinfoheader = this->bitmapinfoheader;
|
||
|
||
t_bitmapinfoheader.biHeight *= 2;
|
||
t_bitmapinfoheader.biWidth *= 2;
|
||
t_bitmapinfoheader.biSizeImage *= 4;
|
||
|
||
this->WriteBMP("magnifyImage.bmp", t_data, t_bmpfileheader, t_bitmapinfoheader);
|
||
this->myFree(t_data, t_bitmapinfoheader.biHeight);//释放内存
|
||
}
|
||
else//缩小
|
||
{
|
||
unsigned char** t_data = (unsigned char**)malloc(sizeof(unsigned char*) * bitmapinfoheader.biHeight / 2);
|
||
for (int i = 0; i < bitmapinfoheader.biHeight / 2; i++)
|
||
{
|
||
t_data[i] = (unsigned char*)malloc(bitmapinfoheader.biWidth * 3 / 2);
|
||
for (int j = 0, index = 0; j < bitmapinfoheader.biWidth / 2; j++)
|
||
{
|
||
t_data[i][index++] = data[2 * i][6 * j];
|
||
t_data[i][index++] = data[2 * i][6 * j + 1];
|
||
t_data[i][index++] = data[2 * i][6 * j + 2];
|
||
}
|
||
}
|
||
|
||
BMPFILEHEADER t_bmpfileheader = this->bmpfileheader;
|
||
BITMAPINFOHEADER t_bitmapinfoheader = this->bitmapinfoheader;
|
||
|
||
t_bitmapinfoheader.biHeight /= 2;
|
||
t_bitmapinfoheader.biWidth /= 2;
|
||
t_bitmapinfoheader.biSizeImage /= 4;
|
||
|
||
this->WriteBMP("shrinkImage.bmp", t_data, t_bmpfileheader, t_bitmapinfoheader);
|
||
this->myFree(t_data, t_bitmapinfoheader.biHeight);//释放内存
|
||
}
|
||
}
|
||
|
||
|
||
//图像裁剪的函数
|
||
void Image::Cut(int x1, int y1, int x2, int y2)
|
||
{//裁剪点(x1,y1)到点(x2,y2)的图像——(0,120) (512,360) h = y2 - y1 = 240, w = x2 - x1 = 512
|
||
if (x2 > x1 && y2 > y1)
|
||
{
|
||
int h = y2 - y1 + 1;
|
||
int w = x2 - x1 + 1;
|
||
while (w % 4)
|
||
{
|
||
w++;
|
||
}
|
||
//重新载入数据
|
||
unsigned char **t_data = (unsigned char**)malloc(h * sizeof(unsigned char*));
|
||
//m,n控制t_data的下标,i,j控制data下标
|
||
for (int i = y1,m = 0; i <= y2; i++, m++)
|
||
{
|
||
t_data[m] = (unsigned char*)malloc(w * 3);
|
||
memset(t_data[m],0, w * 3);
|
||
for (int j = x1*3, n = 0; j <= x2*3 + 2; j++, n++)
|
||
{
|
||
t_data[m][n] = data[i][j];
|
||
}
|
||
}
|
||
//重新载入头文件
|
||
BMPFILEHEADER t_bmpfileheader = this->bmpfileheader;
|
||
BITMAPINFOHEADER t_bitmapinfoheader = this->bitmapinfoheader;
|
||
t_bitmapinfoheader.biHeight = h;
|
||
t_bitmapinfoheader.biWidth = w;
|
||
//通过公式重新计算biSize
|
||
t_bitmapinfoheader.biSizeImage = (((w*t_bitmapinfoheader.biBitCount) + 31) / 32 * 4)*h;
|
||
//保存数据
|
||
WriteBMP("cutImage.bmp", t_data, t_bmpfileheader, t_bitmapinfoheader);
|
||
//释放数据
|
||
myFree(t_data, h);
|
||
}
|
||
else
|
||
{
|
||
puts("输入坐标有误");
|
||
}
|
||
}
|
||
|
||
|
||
//图像旋转的函数
|
||
void Image::Rotate(int degree)//图像旋转的函数(简单起见,旋转角度为90度的整数倍)
|
||
{
|
||
BMPFILEHEADER t_bmpfileheader = this->bmpfileheader;
|
||
BITMAPINFOHEADER t_bitmapinfoheader = this->bitmapinfoheader;
|
||
if (degree == 90)
|
||
{
|
||
unsigned char** t_data = (unsigned char**)malloc(sizeof(unsigned char*) * bitmapinfoheader.biWidth);
|
||
for (int i = 0; i < bitmapinfoheader.biWidth; i++)
|
||
{
|
||
t_data[i] = (unsigned char*)malloc(bitmapinfoheader.biHeight * 3);
|
||
for (int j = 0; j < bitmapinfoheader.biHeight; j++)
|
||
{
|
||
t_data[i][j * 3] = data[bitmapinfoheader.biHeight - j - 1][3 * i];
|
||
t_data[i][j * 3 + 1] = data[bitmapinfoheader.biHeight - j - 1][3 * i + 1];
|
||
t_data[i][j * 3 + 2] = data[bitmapinfoheader.biHeight - j - 1][3 * i + 2];
|
||
}
|
||
}
|
||
//重写信息头
|
||
t_bitmapinfoheader.biHeight = this->bitmapinfoheader.biWidth;
|
||
t_bitmapinfoheader.biWidth = this->bitmapinfoheader.biHeight;
|
||
//保存图片
|
||
this->WriteBMP("rotate90.bmp", t_data, t_bmpfileheader, t_bitmapinfoheader);
|
||
this->myFree(t_data, t_bitmapinfoheader.biHeight);
|
||
}
|
||
else if (degree == 180)
|
||
{
|
||
unsigned char** t_data = (unsigned char**)malloc(sizeof(unsigned char*) * bitmapinfoheader.biHeight);
|
||
for (int i = 0; i < bitmapinfoheader.biHeight; i++)
|
||
{
|
||
t_data[i] = (unsigned char*)malloc(bitmapinfoheader.biWidth * 3);
|
||
for (int j = 0; j < bitmapinfoheader.biWidth; j++)
|
||
{
|
||
t_data[i][j * 3] = data[bitmapinfoheader.biHeight - i - 1][bitmapinfoheader.biWidth * 3 - j * 3 - 3];
|
||
t_data[i][j * 3 + 1] = data[bitmapinfoheader.biHeight - i - 1][bitmapinfoheader.biWidth * 3 - j * 3 - 3 + 1];
|
||
t_data[i][j * 3 + 2] = data[bitmapinfoheader.biHeight - i - 1][bitmapinfoheader.biWidth * 3 - j * 3 - 3 + 2];
|
||
}
|
||
}
|
||
//保存图片
|
||
this->WriteBMP("rotate180.bmp", t_data);
|
||
this->myFree(t_data, t_bitmapinfoheader.biHeight);
|
||
}
|
||
else if (degree == 270)
|
||
{
|
||
unsigned char** t_data = (unsigned char**)malloc(sizeof(unsigned char*) * bitmapinfoheader.biWidth);
|
||
for (int i = 0; i < bitmapinfoheader.biWidth; i++)
|
||
{
|
||
t_data[i] = (unsigned char*)malloc(bitmapinfoheader.biHeight * 3);
|
||
for (int j = 0; j < bitmapinfoheader.biHeight; j++)
|
||
{
|
||
t_data[i][j * 3] = data[j][bitmapinfoheader.biWidth * 3 - 3 -i * 3];
|
||
t_data[i][j * 3 + 1] = data[j][bitmapinfoheader.biWidth * 3 - 3 - i * 3 + 1];
|
||
t_data[i][j * 3 + 2] = data[j][bitmapinfoheader.biWidth * 3 - 3 - i * 3 + 2];
|
||
}
|
||
}
|
||
//重写信息头
|
||
t_bitmapinfoheader.biHeight = this->bitmapinfoheader.biWidth;
|
||
t_bitmapinfoheader.biWidth = this->bitmapinfoheader.biHeight;
|
||
//保存图片
|
||
this->WriteBMP("rotate270.bmp", t_data, t_bmpfileheader, t_bitmapinfoheader);
|
||
this->myFree(t_data, t_bitmapinfoheader.biHeight);
|
||
}
|
||
else
|
||
{
|
||
puts("输入的角度不符合要求");
|
||
}
|
||
}
|
||
|
||
|
||
//求均值方差
|
||
void Image::Mean_Variance(float &m, float &var)//求图像的均值和方差,利用参数输出
|
||
{
|
||
float sum = 0;
|
||
float ave = 0;
|
||
float vSum = 0;
|
||
float vAve = 0;
|
||
for (int i = 0; i < bitmapinfoheader.biHeight; i++)
|
||
{
|
||
for (int j = 0; j < bitmapinfoheader.biWidth * 3; j++)
|
||
{
|
||
sum += this->data[i][j];
|
||
}
|
||
}
|
||
ave = sum / (bitmapinfoheader.biHeight*bitmapinfoheader.biWidth * 3);
|
||
for (int i = 0; i < bitmapinfoheader.biHeight; i++)
|
||
{
|
||
for (int j = 0; j < bitmapinfoheader.biWidth * 3; j++)
|
||
{
|
||
vSum += (data[i][j] - ave)*(data[i][j] - ave);
|
||
}
|
||
}
|
||
vAve = vSum / (bitmapinfoheader.biHeight*bitmapinfoheader.biWidth * 3);
|
||
|
||
m = ave;
|
||
var = vAve;
|
||
}
|
||
|
||
|
||
Image& Image::operator=(Image& val)//重载操作符
|
||
{
|
||
this->bitmapinfoheader = val.bitmapinfoheader;
|
||
this->bmpfileheader = val.bmpfileheader;
|
||
this->height = val.height;
|
||
this->width = val.width;
|
||
// 动态分配二维数组存储像素数据,注意先申请一个存放指针的数组,
|
||
this->data = (unsigned char **)malloc(sizeof(unsigned char*) * bitmapinfoheader.biHeight);
|
||
//其大小为sizeof(unsigned char*) * bitmapinfoheader.biHeight,这点很容易错
|
||
//申请行指针
|
||
for (int i = 0; i < bitmapinfoheader.biHeight; i++)
|
||
{
|
||
//注意3通道,每个像素3个字节
|
||
this->data[i] = (unsigned char *)malloc(bitmapinfoheader.biWidth * 3);
|
||
// 读取像素数据
|
||
for (int j = 0; j < bitmapinfoheader.biWidth * 3; j++)
|
||
{
|
||
this->data[i][j] = val.data[i][j];
|
||
}
|
||
}
|
||
|
||
return *this;
|
||
}
|
||
|
||
|
||
//实现友元函数,交换两个Image对象的数据
|
||
void Swap(Image &a, Image &b)
|
||
{
|
||
Image t(a);
|
||
a = b;
|
||
b = t;
|
||
}
|