diff --git a/output/bw2x3(output).bmp b/output/bw2x3(output).bmp index 1bd6edb..e1b1830 100644 Binary files a/output/bw2x3(output).bmp and b/output/bw2x3(output).bmp differ diff --git a/tempCodeRunnerFile.c b/tempCodeRunnerFile.c deleted file mode 100644 index a1147f4..0000000 --- a/tempCodeRunnerFile.c +++ /dev/null @@ -1,2 +0,0 @@ - - *height = info_h.biHeight; \ No newline at end of file diff --git a/test/hello.bmp b/test/hello.bmp deleted file mode 100644 index 7c6eeea..0000000 Binary files a/test/hello.bmp and /dev/null differ diff --git a/test/image.cpp b/test/image.cpp deleted file mode 100644 index 2a90733..0000000 --- a/test/image.cpp +++ /dev/null @@ -1,619 +0,0 @@ -#include "image.h" -#include -#include -#include -#include -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; -} diff --git a/test/image.h b/test/image.h deleted file mode 100644 index fbbf861..0000000 --- a/test/image.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef IMAGE_H -#define IMAGE_H -#include "struct.h" - -class Image -{ -public: - //构造函数及其重载 - Image(){}//创建行列都为零的Image对象 - Image(int h, int w);//创建h行,w列的Image对象 - Image(int h, int w, unsigned char val); //创建的图像像素值都为val; - Image(const char* ImageName); //利用文件名从硬盘加载图像文件成为Image对象; - Image(unsigned char *m, int rows, int cols); //从一维静态数组创建Image对象,图像的行数和列数由后面两个参数给出; - Image(unsigned char m[][100], int rows); //从静态二维数组创建Image对象,图像的行数(二维数组的第一个维度)由第二个参数rows给出; - Image(unsigned char **m, int h, int w); //从动态数组(二级指针)创建Image对象,图像的行数和列数由后面两个参数给出; - Image(Image &im); //拷贝构造函数; - ~Image(); //析构函数; - - - void ReadBMP(const char* filename); //从BMP文件中读入图像数据; - void WriteBMP(const char* filename); //将图像数据保存为BMP图像文件; - void WriteBMP(const char *filename, unsigned char** data);//翻转时写图片 - void WriteBMP(const char *filename, unsigned char** data,//放缩时写图片 - BMPFILEHEADER bmpfileheader, BITMAPINFOHEADER bitmapinfoheader); - - - void ReadText(const char* filename); //从文本文件中读入图像数据; - void WriteText(const char* filename); //将图像数据保存为文本文件; - - - unsigned char& At(int row, int col); //获取第row行第col列的像素点的值; - void Set(int row, int col, unsigned char value); //设置像素(row,col)为某值; - void Set(unsigned char value); //设置图像所有像素为同一值; - - - void Flip(int code); //图像的翻转; 根据code的值:0:左右翻转,1:上下翻转; - void Resize(int code); //图像的缩放;根据code的值:0:缩小一倍,1:放大一倍; - - - void Cut(int x1, int y1, int x2, int y2);//裁剪点(x1,y1)到点(x2,y2)的图像 - - - void Rotate(int degree);//图像旋转的函数(简单起见,旋转角度为90度的整数倍) - - - void Mean_Variance(float &m, float &var);//求图像的均值和方差,利用参数输出 - - friend void Swap(Image &a, Image &b);//使用友元函数交换两个Image对象的数据 - void myFree(unsigned char** data, int h); - Image& operator=(Image& val);//重载操作符 - -private: - unsigned char **data; - int height; - int width; - BMPFILEHEADER bmpfileheader; - BITMAPINFOHEADER bitmapinfoheader; -}; - -#endif diff --git a/test/main.cpp b/test/main.cpp deleted file mode 100644 index 7dd6237..0000000 --- a/test/main.cpp +++ /dev/null @@ -1,75 +0,0 @@ -#include "image.h" -#include -#include - -int main(int argc, char* argv[]) -{ - Image img; //创建对象 - //读写BMP文件 - img.ReadBMP("hello.bmp"); - img.WriteBMP("FruitsCopy.bmp"); - img.WriteText("FruitsCopy.text"); - - - //读写text文件 - Image readtxtImage; - readtxtImage.ReadText("FruitsCopy.text"); - readtxtImage.WriteText("writeFruits.text"); - - - //图像的上下翻转,并保存结果图像文件 - img.Flip(true); - //图像的左右翻转,如img.Flip(true);并保存结果图像文件 - img.Flip(false); - //左右翻转需要注意,每个像数占3个字节,翻转时不能简单直接翻转, - //而需要每个字节对应地翻转 - - - //图像的缩放,并保存结果图像文件 - img.Resize(false);//图像缩小 - img.Resize(true);//图像放大 - //缩小时也需要注意,每个像数占3个字节,不能简单通过删除字节而缩小, - //而需要每个字节对应地删除 - //放大也是一样的道理 - - - //获取图像的某点的像素值,并修改, 并保存结果图像文件 - int row = 100; - int col = 100; - img.At(row, col); - img.Set(row, col, 10); - img.Set(100); - - - //使用拷贝构造函数创建新的对象 - Image new_img(img); - new_img.WriteBMP("new_img.bmp"); - - - //截取指定区域内的图像,并保存结果图像文件(x1,y1) (x2,y2) - new_img.Cut(120,120,360,360); - //需要保证 x2 > x1 && y2 > y1 - - - //顺时针旋转图像并保存结果图像文件(简单起见,旋转角度为90度的整数倍) - img.Rotate(90); - img.Rotate(180); - img.Rotate(270); - - - //求图像的均值和方差,并在命令行输出 - float ave = 0; - float vAve = 0; - img.Mean_Variance(ave, vAve); - printf("平均值为:%f\n方差为:%f\n", ave, vAve); - - - //交换两个图像的数据 - Image img1("Baboon.bmp"); - Image img2("Lena.bmp"); - Swap(img1, img2); - //保存交换完的结果图像文件 - img1.WriteBMP("S_img1_baboon.bmp"); - img2.WriteBMP("S_img2_lena.bmp"); - return 0; -} diff --git a/test/struct.h b/test/struct.h deleted file mode 100644 index 10216cd..0000000 --- a/test/struct.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef STRUCT_H -#define STRUCT_H - -// 针对该结构体的字节对齐问题调整对齐策略 -#pragma pack(push,1) -struct BMPFILEHEADER -{ - unsigned short bfType; - unsigned int bfSize; - unsigned short bfReserved1; - unsigned short bfReserved2; - unsigned int bfOffBits; -}; -#pragma pack(pop) - -struct BITMAPINFOHEADER -{ - unsigned long biSize; //本结构所占用字节数 40字节 - long biWidth; //位图的宽度,以像素为单位 - long biHeight; //位图的高度,以像素为单位 - unsigned short biPlanes; //目标设备的级别,必须为1 - unsigned short biBitCount; //每个像素所需的位数,必须是1(双色)、 - //4(16色)、8(256色)或24(真彩色)之一 - unsigned long biCompression; //位图压缩类型,必须是 0(BI_RGB不压缩)、 - //1(BI_RLE8压缩类型) - //2(BI_RLE压缩类型)之一 - unsigned long biSizeImage; //位图的大小,以字节为单位 - long biXPelsPerMeter; //位图水平分辨率,每米像素数 - long biYPelsPerMeter; //位图垂直分辨率,每米像素数 - unsigned long biClrUsed; //位图实际使用的颜色表中的颜色数 - unsigned long biClrImportant; //位图显示过程中重要的颜色数 -}; - -#endif - diff --git a/transfer.exe b/transfer.exe index b04c173..9e99bef 100644 Binary files a/transfer.exe and b/transfer.exe differ diff --git a/try.c b/try.c index 9a3c71e..e0f4368 100644 --- a/try.c +++ b/try.c @@ -5,7 +5,7 @@ typedef unsigned char uch; -// 妾旀绲愭 +// 濡炬梹顢嶇徊鎰潗 #pragma pack(2) struct BmpFileHeader { uint16_t bfTybe; @@ -29,17 +29,17 @@ struct BmpInfoHeader { }; #pragma pack() -//杈呭姪璁$畻鍑芥暟 +//鏉堝懎濮拋锛勭暬閸戣姤鏆 float linear_single(float x, float x1, float x2, float f1, float f2){ return floor(f1 * (x2 - x) / (x2 - x1) + f2 * (x - x1) / (x2 - x1)); } -// 鍙岀嚎鎬ф彃鍊煎嚱鏁 -// 鍙傝 https://zh.wikipedia.org/wiki/%E5%8F%8C%E7%BA%BF%E6%80%A7%E6%8F%92%E5%80%BC +// 閸欏瞼鍤庨幀褎褰冮崐鐓庡毐閺侊拷 +// 閸欏倽鈧拷 https://zh.wikipedia.org/wiki/%E5%8F%8C%E7%BA%BF%E6%80%A7%E6%8F%92%E5%80%BC char** linear_insert(uch** old_pixels, uint32_t row, uint32_t col, uint32_t old_width, uint32_t old_height, float radio_w, float radio_h){ float x = row / radio_h; float y = col / radio_w; - // 濡傛灉鏁存暟鏍肩偣灏辩洿鎺ヨ繑鍥 + // 婵″倹鐏夐弫瀛樻殶閺嶈偐鍋g亸杈╂纯閹恒儴绻戦崶锟 int x1 = floor(x); int x2 = ceil(x); int y1 = floor(y); @@ -49,7 +49,7 @@ char** linear_insert(uch** old_pixels, uint32_t row, uint32_t col, uint32_t old_ if (y2 >= old_width){y2 = y1;} if (x1 == x2 && y1 == y2){ uint32_t idx = x1*old_width+y1; - return old_pixels[x1][idx + 0], old_pixels[x1][idx + 1], old_pixels[x1][idx + 2];} + return old_pixels[idx + 0], old_pixels[idx + 1], old_pixels[idx + 2];} if (x1 == x2){ int x = x1; uint32_t idx1 = x*old_width+y; @@ -86,7 +86,7 @@ void bmpWrite(const char* name, const uch* raw_img, uint32_t width, uint32_t hei perror("Error bmpWrite."); return; } - // 妾旀璩囪▕ + // 濡炬梹顢嶇挬鍥枙 struct BmpFileHeader file_h = { .bfTybe=0x4d42, .bfReserved1=0, @@ -100,7 +100,7 @@ void bmpWrite(const char* name, const uch* raw_img, uint32_t width, uint32_t hei if(bits==8) {file_h.bfSize+= 1024, file_h.bfOffBits+= 1024;} - // 鍦栫墖璩囪▕ + // 閸︽牜澧栫挬鍥枙 struct BmpInfoHeader info_h = { .biSize=40, .biPlanes=1, @@ -112,10 +112,10 @@ void bmpWrite(const char* name, const uch* raw_img, uint32_t width, uint32_t hei }; info_h.biWidth = new_width; info_h.biHeight = new_height; - info_h.biBitCount = bits;// 澶氬皯浣嶇殑鍦 + info_h.biBitCount = bits;// 婢舵艾鐨担宥囨畱閸︼拷 info_h.biSizeImage = new_width*new_height * bits/8; if(bits == 8) {info_h.biClrUsed=256;} - // 瀵叆妾旈牠 + // 鐎殿偄鍙嗗鏃堢墵 FILE *pFile = NULL; // pFile = fopen(name,"wb+"); fopen_s(&pFile, name,"wb+"); @@ -125,7 +125,7 @@ void bmpWrite(const char* name, const uch* raw_img, uint32_t width, uint32_t hei } fwrite((char*)&file_h, sizeof(char), sizeof(file_h), pFile); fwrite((char*)&info_h, sizeof(char), sizeof(info_h), pFile); - // 瀵鑹茬洡 + // 鐎殿偉顎為懝鑼础 if(bits == 8) { for(unsigned i = 0; i < 256; ++i) { uch c = i; @@ -137,44 +137,50 @@ void bmpWrite(const char* name, const uch* raw_img, uint32_t width, uint32_t hei } // char newpixels[new_width*new_height]; - unsigned char **newpixels=(unsigned char**)malloc(new_width*new_height*3);// 娌掔敤鍒 + unsigned char **newpixels=(unsigned char**)malloc(new_width*new_height*3);// 濞屾帞鏁ら崚锟 - // 瀵叆鍦栫墖璩囪▕ + // 鐎殿偄鍙嗛崷鏍鐠╁洩鈻 size_t alig = ((new_width*bits/8)*3) % 4; - // for(int j = new_height-1; j >= 0; --j) { - // for(unsigned i = 0; i < new_width; ++i) { - // uint32_t idx = j*new_width +i; - // if(bits == 24) { // RGB鍦栫墖 - // fwrite((char*)&raw_img[idx*3 +2], sizeof(char), sizeof(uch), pFile); - // fwrite((char*)&raw_img[idx*3 +1], sizeof(char), sizeof(uch), pFile); - // fwrite((char*)&raw_img[idx*3 +0], sizeof(char), sizeof(uch), pFile); - // } else if(bits == 8) { // 鐏伴殠鍦 - // fwrite((char*)&raw_img[idx], sizeof(char), sizeof(uch), pFile); - // } - // } - - for(int j = new_height-1; j >= 0; --j) { for(unsigned i = 0; i < new_width; ++i) { uint32_t idx = j*new_width +i; - if(bits == 24) { // RGB鍦栫墖 - char** r, g, b = linear_insert(&(raw_img), j, i, width, height, radio_w, radio_h); - fwrite(b, sizeof(char), sizeof(uch), pFile); - fwrite(g, sizeof(char), sizeof(uch), pFile); - fwrite(r, sizeof(char), sizeof(uch), pFile); - } else if(bits == 8) { // 鐏伴殠鍦 + if(bits == 24) { // RGB閸︽牜澧 + fwrite((char*)&raw_img[idx*3 +2], sizeof(char), sizeof(uch), pFile); + fwrite((char*)&raw_img[idx*3 +1], sizeof(char), sizeof(uch), pFile); + fwrite((char*)&raw_img[idx*3 +0], sizeof(char), sizeof(uch), pFile); + // printf("%x",(raw_img)[idx*3 +2]); + // printf("%x",(raw_img)[idx*3 +1]); + // printf("%x",(raw_img)[idx*3 +0]); + // printf(" "); + } + else if(bits == 8) { // 閻忎即娈犻崷锟 fwrite((char*)&raw_img[idx], sizeof(char), sizeof(uch), pFile); } + // printf("\n"); } - //# 璁$畻鏂板儚绱 - // 灏嶉綂4byte + + + // for(int j = new_height-1; j >= 0; --j) { + // for(unsigned i = 0; i < new_width; ++i) { + // uint32_t idx = j*new_width +i; + // if(bits == 24) { // RGB閸︽牜澧 + // char** r, g, b = linear_insert(&(raw_img), j, i, width, height, radio_w, radio_h); + // fwrite(b, sizeof(char), sizeof(uch), pFile); + // fwrite(g, sizeof(char), sizeof(uch), pFile); + // fwrite(r, sizeof(char), sizeof(uch), pFile); + // } else if(bits == 8) { // 閻忎即娈犻崷锟 + // fwrite((char*)&raw_img[idx], sizeof(char), sizeof(uch), pFile); + // } + // } + //# 鐠侊紕鐣婚弬鏉垮剼缁憋拷 + // 鐏忓秹缍4byte for(size_t i = 0; i < alig; ++i) { fwrite("", sizeof(char), sizeof(uch), pFile); } } fclose(pFile); - free(newpixels); //瑷樺緱閲嬫斁绌洪枔 + free(newpixels); //鐟锋ê绶遍柌瀣杹缁屾椽鏋 } void bmpRead(const char* name, uch** oldpixels, uint32_t* width, uint32_t* height, uint16_t* bits) { @@ -182,11 +188,11 @@ void bmpRead(const char* name, uch** oldpixels, uint32_t* width, uint32_t* heigh perror("Error bmpRead."); return; } - // 妾旀璩囪▕ + // 濡炬梹顢嶇挬鍥枙 struct BmpFileHeader file_h; - // 鍦栫墖璩囪▕ + // 閸︽牜澧栫挬鍥枙 struct BmpInfoHeader info_h; - // 璁鍙栨獢闋 + // 鐠佲偓閸欐牗鐛㈤棆锟 FILE *pFile = NULL; // pFile = fopen(name, "rb+"); fopen_s(&pFile, name, "rb+"); @@ -196,25 +202,25 @@ void bmpRead(const char* name, uch** oldpixels, uint32_t* width, uint32_t* heigh } fread((char*)&file_h, sizeof(char), sizeof(file_h), pFile); fread((char*)&info_h, sizeof(char), sizeof(info_h), pFile); - // 璁鍙栭暦瀵 + // 鐠佲偓閸欐牠鏆︾碉拷 *width = info_h.biWidth; *height = info_h.biHeight; *bits = info_h.biBitCount; - **oldpixels=(unsigned char**)malloc((*width)*(*height)*3); + // **oldpixels=(unsigned char**)malloc((*width)*(*height)*3); - // size_t ImgSize = ((size_t)*width) * ((size_t)*height) * 3; - // *raw_img = (uch*)calloc(ImgSize, sizeof(uch)); - // 璁鍙栬畝鐗囪硣瑷婅綁RAW妾旇硣瑷 + size_t ImgSize = ((size_t)*width) * ((size_t)*height) * 3; + *oldpixels = (uch*)calloc(ImgSize, sizeof(uch)); + // 鐠佲偓閸欐牞鐣濋悧鍥。鐟峰﹨缍丷AW濡炬棁纭g懛锟 fseek(pFile, file_h.bfOffBits, SEEK_SET); size_t alig = ((info_h.biWidth*info_h.biBitCount/8)*3) % 4; for(int j = *height-1; j >= 0; --j) { for(unsigned i = 0; i < *width; ++i) { uint32_t idx = j*(*width)+i; - if(*bits == 24) { // RGB鍦栫墖 + if(*bits == 24) { // RGB閸︽牜澧 fread((char*)&(*oldpixels)[idx*3 +2], sizeof(char), sizeof(uch), pFile); fread((char*)&(*oldpixels)[idx*3 +1], sizeof(char), sizeof(uch), pFile); fread((char*)&(*oldpixels)[idx*3 +0], sizeof(char), sizeof(uch), pFile); - } else if(*bits == 8) { // 鐏伴殠鍦 + } else if(*bits == 8) { // 閻忎即娈犻崷锟 fread((char*)&(*oldpixels)[idx], sizeof(char), sizeof(uch), pFile); } } @@ -226,17 +232,17 @@ void bmpRead(const char* name, uch** oldpixels, uint32_t* width, uint32_t* heigh //--------------------------------------------------------------------------- // size_t ImgSize = ((size_t)*width) * ((size_t)*height) * 3; // *raw_img = (uch*)calloc(ImgSize, sizeof(uch)); - // // 璁鍙栬畝鐗囪硣瑷婅綁RAW妾旇硣瑷 + // // 鐠佲偓閸欐牞鐣濋悧鍥。鐟峰﹨缍丷AW濡炬棁纭g懛锟 // fseek(pFile, file_h.bfOffBits, SEEK_SET); // size_t alig = ((info_h.biWidth*info_h.biBitCount/8)*3) % 4; // for(int j = *height-1; j >= 0; --j) { // for(unsigned i = 0; i < *width; ++i) { // uint32_t idx = j*(*width)+i; - // if(*bits == 24) { // RGB鍦栫墖 + // if(*bits == 24) { // RGB閸︽牜澧 // fread((char*)&(*raw_img)[idx*3 +2], sizeof(char), sizeof(uch), pFile); // fread((char*)&(*raw_img)[idx*3 +1], sizeof(char), sizeof(uch), pFile); // fread((char*)&(*raw_img)[idx*3 +0], sizeof(char), sizeof(uch), pFile); - // } else if(*bits == 8) { // 鐏伴殠鍦 + // } else if(*bits == 8) { // 閻忎即娈犻崷锟 // fread((char*)&(*raw_img)[idx], sizeof(char), sizeof(uch), pFile); // } // } @@ -249,16 +255,17 @@ void bmpRead(const char* name, uch** oldpixels, uint32_t* width, uint32_t* heigh for(unsigned i = 0; i < *width; ++i) { uint32_t idx = j*(*width)+i; for(int k = 0; k < 3; k++){ - printf((char*)&(*oldpixels)[idx*3 + k]); - printf("\t"); + printf("%x",(*oldpixels)[idx*3 +k]); + printf(" "); } - printf("\t done \t"); + printf("\t"); } printf("\n"); } + printf("done \n"); } -// 鍦栧儚绲愭 +// 閸︽牕鍎氱徊鎰潗 typedef struct Imgraw { uint32_t width, height; uint16_t bits; @@ -281,11 +288,11 @@ int main(int argc, char const *argv[]) { printf("Enter a radio of height :") ; scanf("%f", &radio_h); printf("\n"); - // 寤烘 + // 瀵ょ儤顫 Imgraw img = {0, 0, 0, NULL}; - // 璁鍦 + // 鐠佲偓閸︼拷 Imgraw_Read(&img, "./input/bw2x1.bmp"); - // 瀵湒 + // 鐎殿偄婀 Imgraw_Writ(&img, "./output/bw2x1(output).bmp", radio_w, radio_h); return 0; } diff --git a/try.exe b/try.exe index 1d98d5d..720aa16 100644 Binary files a/try.exe and b/try.exe differ