This commit is contained in:
parent
cbbda43098
commit
df85a8810b
Binary file not shown.
Before Width: | Height: | Size: 66 B After Width: | Height: | Size: 134 B |
|
@ -1,2 +0,0 @@
|
|||
|
||||
*height = info_h.biHeight;
|
BIN
test/hello.bmp
BIN
test/hello.bmp
Binary file not shown.
Before Width: | Height: | Size: 169 KiB |
619
test/image.cpp
619
test/image.cpp
|
@ -1,619 +0,0 @@
|
|||
#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;
|
||||
}
|
60
test/image.h
60
test/image.h
|
@ -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
|
|
@ -1,75 +0,0 @@
|
|||
#include "image.h"
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
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;
|
||||
}
|
|
@ -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
|
||||
|
BIN
transfer.exe
BIN
transfer.exe
Binary file not shown.
117
try.c
117
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
|
||||
// 鍙岀嚎鎬ф彃鍊煎嚱鏁<EFBFBD>
|
||||
// 鍙傝€<EFBFBD> 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;
|
||||
// 如果整数格点就直接返回
|
||||
// 濡傛灉鏁存暟鏍肩偣灏辩洿鎺ヨ繑鍥<EFBFBD>
|
||||
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;// 澶氬皯浣嶇殑鍦<EFBFBD>
|
||||
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);// 娌掔敤鍒<EFBFBD>
|
||||
|
||||
// 寫入圖片資訊
|
||||
// 瀵叆鍦栫墖璩囪▕
|
||||
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) { // 鐏伴殠鍦<E6AEA0>
|
||||
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) { // 鐏伴殠鍦<E6AEA0>
|
||||
// fwrite((char*)&raw_img[idx], sizeof(char), sizeof(uch), pFile);
|
||||
// }
|
||||
// }
|
||||
//# 璁$畻鏂板儚绱<E5849A>
|
||||
// 灏嶉綂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;
|
||||
// 讀取檔頭
|
||||
// 璁€鍙栨獢闋<EFBFBD>
|
||||
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);
|
||||
// 讀取長寬
|
||||
// 璁€鍙栭暦瀵<EFBFBD>
|
||||
*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));
|
||||
// 璁€鍙栬畝鐗囪硣瑷婅綁RAW妾旇硣瑷<EFBFBD>
|
||||
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) { // 鐏伴殠鍦<EFBFBD>
|
||||
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檔資訊
|
||||
// // 璁€鍙栬畝鐗囪硣瑷婅綁RAW妾旇硣瑷<EFBFBD>
|
||||
// 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) { // 鐏伴殠鍦<EFBFBD>
|
||||
// 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};
|
||||
// 讀圖
|
||||
// 璁€鍦<EFBFBD>
|
||||
Imgraw_Read(&img, "./input/bw2x1.bmp");
|
||||
// 寫圖
|
||||
// 瀵湒
|
||||
Imgraw_Writ(&img, "./output/bw2x1(output).bmp", radio_w, radio_h);
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue