C++实验2——类和对象

实验目的

掌握类和对象的创建

掌握构造函数、构造函数的重载,拷贝构造函数、析构函数的设计和使用

掌握成员函数的设计和使用

实验内容

下面的代码已经创建了图像类的框架,请完善该图像类。在该类中,实现图像的读入、保存、显示,并实现图像的翻转、缩放、裁剪等操作。在主程序中,读入某个图像文件(比如“fruits.bmp”),对其进行缩小,上下翻转,左右翻转,指定区域裁剪等操作。

[使用多文件结构设计该类,即类的声明代码在.h文件中,类的实现代码在.cpp文件中,main函数的代码在另一个.cpp文件中。]

请编程实现:

图像类:

  1. 创建图像类Image,实现各个重载的构造函数,拷贝构造函数(深拷贝),析构函数。
  2. 实现对图像的读入,保存,显示。即实现函数ReadBMP,WriteBMP,ReadText,WriteText。类似实验4,从24位BMP图像文件读入时,把3通道转换为1通道,使其成为二维数组。文本文件可以仿照实验3的设计,第一行是图像的行数和列数,后面的每一行存储图像的一行像素值,每个像素的像素值为一个整数。
  3. 获取图像中某像素点的值。即实现函数At()。
  4. 将图像中给定像素点的像素值设置为某值,即实现函数Set。将图像所有像素的像素值设定为某值,即实现函数SetAll。
  5. 同一个函数实现图像的上下翻转、左右翻转。即实现函数Flip。
  6. 根据指定区域裁剪图像。
  7. 求图像的均值,方差。
  8. 图像的旋转,缩放。
  9. 定义友元函数交换两个Image对象的数据。

在函数中实现:

  1. 创建Image类对象img。
  2. 读入文件中的图像“fruits.bmp”。
  3. 利用Image类的成员函数,对图像进行翻转、旋转。
  4. 利用Image类的成员函数,将图像长宽缩小到1/2大小;将图像长宽放大2倍。
  5. 利用拷贝构造函数,创建新的对象new_img。
  6. 给定的两个点(Point):左上点(top_left)和右下点(bottom_right),将此指定区域内的new_img对象图像进行裁剪操作。
  7. 求图像的所有像素点的均值和方差,并输出。
  8. 交换两个Image对象的数据。
#ifndef IMAGE_H
#define IMAGE_H
#pragma pack(push,1)

#define _CRT_SECURE_NO_WARNINGS
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;    //位图显示过程中重要的颜色数
};

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(const Image &im); //拷贝构造函数;
	~Image(); //析构函数;

	void ReadBMP(const char* filename); //从BMP文件中读入图像数据;
	void WriteBMP(const char* filename); //将图像数据保存为BMP图像文件;
	void WriteBMP(const char *filename, unsigned char** pdata, BMPFILEHEADER pfileheader, BITMAPINFOHEADER pinfoheader);//重构函数
	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);//求图像的均值和方差,利用参数输出
	void wfree(unsigned char** data, int h);//删除空间
	friend void Swap(Image &a, Image &b);//使用友元函数交换两个Image对象的数据

private:
	unsigned char **data;
	int height;
	int width;
	BMPFILEHEADER fileheader;
	BITMAPINFOHEADER infoheader;//文件头和信息头作为成员,便于操作
};

#endif

#include <iostream>
#include <stdlib.h>
#include "Image.h"

using namespace std;

//构造函数
Image::Image()
{
    height = 0;
    width = 0;
    data=NULL;
}
//构造函数重载
Image::Image(int h, int w)
{
    height = h;
    width = w;
    int i,j;
    data = new unsigned char *[height];//动态内存开辟
    for (i = 0; i < height; i++)
    {
        data[i] = new unsigned char[width];
    }
    for(i=0;i<h;i++)
    {
        for(j=0;j<w;j++)
        {
            data[i][j]=0;
        }
    }
}

Image::Image(int h, int w, unsigned char val) //构造函数重载,创建的图像像素值都为val;
{
    height = h;
    width = w;
    int i, j;
    data = new unsigned char *[height];//动态内存开辟
    for (i = 0; i < height; i++)
    {
        data[i] = new unsigned char[width];
    }

    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            data[i][j] = val;
        }
    }
}

Image::Image(const char* ImageName)//构造函数重载,利用文件名从硬盘加载图像文件成为Image对象;
{
    ReadBMP(ImageName);
}

Image::Image(unsigned char *m, int rows, int cols)//构造函数重载,从一维静态数组创建Image对象,图像的行数和列数由后面两个参数给出;
{
    height = rows;
    width = cols;

    int i, j;
    data = new unsigned char *[height];//动态内存开辟
    for (i = 0; i < height; i++)
    {
        data[i] = new unsigned char[width];
    }

    for (i = 0; i < height; i++)
    {
        for (j = 0; j < width; j++)
        {
            data[i][j] = m[i*height + j * width];
        }
    }
}

Image::Image(unsigned char m[][100], int rows)//构造函数重载,从静态二维数组创建Image对象,图像的行数(二维数组的第一个维度)由第二个参数rows给出;
{
    width = 100;
    height = rows;

    int i, j;
    data = new unsigned char *[height];//动态内存开辟
    for (i = 0; i < height; i++)
    {
        data[i] = new unsigned char[width];
    }

    for (i = 0; i < height; i++)
    {
        for (j = 0; j < width; j++)
        {
            data[i][j] = m[i][j];
        }
    }
}

Image::Image(unsigned char **m, int h, int w)//构造函数重载,从动态数组(二级指针)创建Image对象,图像的行数和列数由后面两个参数给出;
{
    height = h;
    width = w;

    int i, j;
    data = new unsigned char *[height];//动态内存开辟
    for (i = 0; i < height; i++)
    {
        data[i] = new unsigned char[width];
    }

    for (i = 0; i < height; i++)
    {
        for (j = 0; j < width; j++)
        {
            data[i][j] = m[i][j];
        }
    }
}

//拷贝构造函数
Image::Image(const Image &im)//深拷贝
{
    this->height = im.height;
    this->width = im.width;
    this->fileheader=im.fileheader;
    this->infoheader=im.infoheader;
    int i, j;
    data = new unsigned char *[im.infoheader.biHeight];//动态内存开辟
    for (i = 0; i < im.infoheader.biHeight; i++)
    {
        data[i] = new unsigned char[im.infoheader.biWidth];
    }

    for (i = 0; i < im.infoheader.biHeight; i++)
    {
        for (j = 0; j < im.infoheader.biWidth; j++)
        {
            data[i][j] = im.data[i][j];
        }
    }
}

void Image::wfree(unsigned char** data, int h)
{
    int i;
    for (i = 0; i < h; i++)//释放空间
        delete[] data[i];
    delete[] data;
}

//析构函数
Image::~Image()
{
    int i;
    for (i = 0; i < height; i++)//释放空间
        delete[] data[i];
    delete[] data;
}

//从硬盘读入图像文件;
void Image::ReadBMP(const char* filename)
{
    FILE* pfin = NULL; // 保存文件的文件指针
    fopen_s(&pfin, filename, "rb"); // 二进制写入方式打开文件
    fread(&fileheader, sizeof(BMPFILEHEADER), 1, pfin);
    fread(&infoheader, sizeof(BITMAPINFOHEADER), 1, pfin);
    height = infoheader.biHeight;
    width = infoheader.biWidth;

    int i, j;
    data = new unsigned char *[height];//动态内存开辟
    for (i = 0; i < height; i++)
    {
        data[i] = new unsigned char[width];
    }

    unsigned char a, b, c;
    for (i = 0; i < height; i++)
    {
        for (j = 0; j < width; j++)
        {
            fread(&a, sizeof(unsigned char), 1, pfin);
            fread(&b, sizeof(unsigned char), 1, pfin);
            fread(&c, sizeof(unsigned char), 1, pfin);//读出三通道
            data[i][j] = (a + b + c) / 3;//转为灰度图,存入数组
        }
    }
    fclose(pfin); 
}

//保存图像;
void Image::WriteBMP(const char *filename)
{
    FILE* pfout = NULL; // 保存文件的文件指针
    fopen_s(&pfout, filename, "wb"); // 二进制写入方式打开文件
    fwrite(&fileheader, sizeof(fileheader), 1, pfout);
    fwrite(&infoheader, sizeof(infoheader), 1, pfout);

    int i, j, k;
    for (i = 0; i < height; i++)
    {
        for (j = 0; j < width; j++)
        {
            for (k = 0; k < 3; k++)
                fwrite(&data[i][j], sizeof(unsigned char), 1, pfout);
        }
    }
    fclose(pfout);

}

void Image::WriteBMP(const char *filename, unsigned char** pdata, BMPFILEHEADER pfileheader, BITMAPINFOHEADER pinfoheader)
{
    FILE* pfout = NULL; // 保存文件的文件指针
    fopen_s(&pfout, filename, "wb"); // 二进制写入方式打开文件
    // 写入文件头
    fwrite(&pfileheader, sizeof(pfileheader), 1, pfout);
    // 写入信息头
    fwrite(&pinfoheader, sizeof(pinfoheader), 1, pfout);
    // 写入数据
    int i, j, k;
    for (i = 0; i < pinfoheader.biHeight; i++)
    {
        for (j = 0; j < pinfoheader.biWidth; j++)
        {
            for (k = 0; k < 3; k++)
                fwrite(&pdata[i][j], sizeof(unsigned char), 1, pfout);
        }
    }
    fclose(pfout);
}

//从文本文件读取
void Image::ReadText(const char* filename)
{
    ReadBMP(filename);
}

//保存成文本文件
void Image::WriteText(const char *filename)
{
    FILE* pfout = NULL; // 保存文件的文件指针
    fopen_s(&pfout, filename, "wb"); // 二进制写入方式打开文件
    fwrite(&fileheader, sizeof(fileheader), 1, pfout);
    fwrite(&infoheader, sizeof(infoheader), 1, pfout);
    // fwrite(img, sizeof(RGB), size, pfout);
    int height, weight;
    height = infoheader.biHeight;
    width = infoheader.biWidth;
    int i, j, k;
    for (i = 0; i < height; i++)
    {
        for (j = 0; j < width; j++)
        {
            for (k = 0; k < 3; k++)
                fwrite(&data[i][j], sizeof(unsigned char), 1, pfout);
        }
    }
    fclose(pfout);
}

//获取图像中指定点的值
unsigned char& Image::At(int row, int col)
{
    return data[row][col];
}

void Image::Set(int row, int col, unsigned char value) //设置像素(row,col)为某值;
{
    BMPFILEHEADER pfileheader = this->fileheader;
    BITMAPINFOHEADER pinfoheader = this->infoheader;
    int i, j;
    unsigned char **pdata = new unsigned char *[height];
    for (i = 0; i < height; i++)
    {
        pdata[i] = new unsigned char[width];
    }
    for (i = 0; i < height; i++)
    {
        for (j = 0; j < width; j++)
        {
            pdata[i][j] = data[i][j];
        }
    }
    pdata[row][col]=value;

    pinfoheader.biHeight = this->infoheader.biHeight;
    pinfoheader.biWidth = this->infoheader.biWidth;
    this->WriteBMP("SetOne.bmp", pdata, pfileheader, pinfoheader);
    this->wfree(pdata, pinfoheader.biHeight);
}

//设置图像为同一值
void Image::Set(unsigned char value)
{
    BMPFILEHEADER pfileheader = this->fileheader;
    BITMAPINFOHEADER pinfoheader = this->infoheader;
    int i, j;
    unsigned char **pdata = new unsigned char *[height];
    for (i = 0; i < height; i++)
    {
        pdata[i] = new unsigned char[width];
    }

    for (i = 0; i < height; i++)
    {
        for (j = 0; j < width; j++)
        {
            pdata[i][j] = value;
        }
    }
    pinfoheader.biHeight = this->infoheader.biHeight;
    pinfoheader.biWidth = this->infoheader.biHeight;
    this->WriteBMP("SetAll.bmp", pdata, pfileheader, pinfoheader);
    this->wfree(pdata, pinfoheader.biHeight);
}

//false 左右,true 上下;
void Image::Flip(int code)//图像的翻转; 根据code的值:0:左右翻转,1:上下翻转;
{
    BMPFILEHEADER pfileheader = this->fileheader;
    BITMAPINFOHEADER pinfoheader = this->infoheader;
    int i, j;
    unsigned char **pdata = new unsigned char *[height];
    for (i = 0; i < height; i++)
    {
        pdata[i] = new unsigned char[width];
    }

    if (code == 0)
    {
        for (i = 0; i < height; i++)
        {
            for (j = 0; j < width; j++)
            {
                pdata[i][width - j - 1] = data[i][j];
            }
        }
        this->WriteBMP("Flipliftright.bmp", pdata, pfileheader, pinfoheader);
        this->wfree(pdata, pinfoheader.biHeight);
    }
    if (code == 1)
    {
        for (i = 0; i < height; i++)
        {
            for (j = 0; j < width; j++)
            {
                pdata[height - 1 - i][j] = data[i][j];
            }
        }
        this->WriteBMP("Flipupdown.bmp", pdata, pfileheader, pinfoheader);
        this->wfree(pdata, pinfoheader.biHeight);
    }
}

//图像缩小,放大
void Image::Resize(int code)
{
    if (code == 0)
    {
        BMPFILEHEADER pfileheader = this->fileheader;
        BITMAPINFOHEADER pinfoheader = this->infoheader;
        int i, j;
        unsigned char **pdata = new unsigned char *[height / 2];
        for (i = 0; i < height / 2; i++)
        {
            pdata[i] = new unsigned char[width / 2];
        }

        for (i = 0; i * 2 < height; i++)
        {
            for (j = 0; j * 2 < width; j++)
            {
                pdata[i][j] = data[i * 2][j * 2];
            }
        }
        pinfoheader.biHeight = this->infoheader.biHeight / 2;
        pinfoheader.biWidth = this->infoheader.biWidth / 2;
        pinfoheader.biSizeImage = this->infoheader.biSizeImage / 4;
        this->WriteBMP("Resize smaller.bmp", pdata, pfileheader, pinfoheader);
        this->wfree(pdata, pinfoheader.biHeight);
    }

    if (code == 1)
    {
        BMPFILEHEADER pfileheader = this->fileheader;
        BITMAPINFOHEADER pinfoheader = this->infoheader;
        int i, j;

        unsigned char **pdata = new unsigned char *[2 * height];
        for (i = 0; i < 2 * height; i++)
        {
            pdata[i] = new unsigned char[2 * width];
        }

        for (int i = 0; i < height; i++)
        {
            for (int j = 0; j < width; j++)
            {
                pdata[i * 2][j * 2] = data[i][j];
                pdata[i * 2 + 1][j * 2] = data[i][j];
                pdata[i * 2][j * 2 + 1] = data[i][j];
                pdata[i * 2 + 1][j * 2 + 1] = data[i][j];  //原来的一个像素变四个
            }
        }
        //重写信息头
        pinfoheader.biHeight = this->infoheader.biHeight * 2;
        pinfoheader.biWidth = this->infoheader.biWidth * 2;
        pinfoheader.biSizeImage = this->infoheader.biSizeImage * 4;
        //保存图片
        this->WriteBMP("Resize bigger.bmp", pdata, pfileheader, pinfoheader);
        this->wfree(pdata, pinfoheader.biHeight);
    }
}

//图像裁剪的函数
void Image::Cut(int x1, int y1, int x2, int y2)
{
    if (x2 > x1 && y2 > y1)
    {
        int h = y2 - y1 + 1;
        int w = x2 - x1 + 1;
        while (w % 4)
        {
            w++;
        }

        int i, j;
        unsigned char **pdata = new unsigned char *[h];
        for (i = 0; i < h; i++)
        {
            pdata[i] = new unsigned char[w];
        }

        int m,n;
        for(i=y1,m=0; i<=y2; i++,m++)
        {
            for(j=x1,n=0; j<=x2; j++,n++)
            {
                pdata[m][n]=data[i][j];
            }
        }

        BMPFILEHEADER pfileheader = this->fileheader;
        BITMAPINFOHEADER pinfoheader = this->infoheader;
        pinfoheader.biHeight = h;
        pinfoheader.biWidth = w;
        //通过公式重新计算biSize
        pinfoheader.biSizeImage = (((w*pinfoheader.biBitCount) + 31) / 32 * 4)*h;
        //保存数据
        WriteBMP("cutImage.bmp", pdata, pfileheader, pinfoheader);
        //释放数据
        wfree(pdata, h);
    }
    else
    {
        puts("输入坐标有误");
    }
}

//图像旋转的函数
void Image::Rotate(int degree)//图像旋转的函数(简单起见,旋转角度为90度的整数倍)
{
    BMPFILEHEADER pfileheader = this->fileheader;
    BITMAPINFOHEADER pinfoheader = this->infoheader;
    int i, j;
    if(degree%360==0)
    {
        int i, j;
        unsigned char **pdata = new unsigned char *[height];
        for (i = 0; i < height; i++)
        {
            pdata[i] = new unsigned char[width];
        }

        for (i = 0; i < height; i++)
        {
            for (j = 0; j < width; j++)
            {
                pdata[i][j] = data[i][j];
            }
        }
        //保存图片
        this->WriteBMP("rotate0.bmp", pdata, pfileheader, pinfoheader);
        this->wfree(pdata, pinfoheader.biHeight);
    }

    else if(degree<0)
    {
    if ((degree%90==0)&&(degree%180!=0)&&(degree%270!=0))
    {
        unsigned char **pdata = new unsigned char *[width];
        for (i = 0; i < width; i++)
        {
            pdata[i] = new unsigned char[height];
        }

        for (int i = 0; i < infoheader.biWidth; i++)
        {
            for (int j = 0; j < infoheader.biHeight; j++)
            {
                pdata[i][j] = data[infoheader.biHeight - j - 1][i];
            }
        }
        pinfoheader.biHeight = this->infoheader.biWidth;
        pinfoheader.biWidth = this->infoheader.biHeight;
        //保存图片
        this->WriteBMP("rotate-90.bmp", pdata, pfileheader, pinfoheader);
        this->wfree(pdata, pinfoheader.biHeight);
    }

    else if ((degree %180==0)&&(degree%270!=0))
    {
        int i, j;
        unsigned char **pdata = new unsigned char *[height];
        for (i = 0; i < height; i++)
        {
            pdata[i] = new unsigned char[width];
        }

        for (i = 0; i < height; i++)
        {
            for (j = 0; j < width; j++)
            {
                pdata[height-i-1][width - j - 1] = data[i][j];
            }
        }
        //保存图片
        this->WriteBMP("rotate-180.bmp", pdata, pfileheader, pinfoheader);
        this->wfree(pdata, pinfoheader.biHeight);
    }

    else if (degree %270==0)
    {
        unsigned char **pdata = new unsigned char *[width];
        for (i = 0; i < width; i++)
        {
            pdata[i] = new unsigned char[height];
        }

        for (int i = 0; i < infoheader.biWidth; i++)
        {
            for (int j = 0; j < infoheader.biHeight; j++)
            {
                pdata[i][j] = data[j][pinfoheader.biWidth - i - 1];
            }
        }
        //重写信息头
        pinfoheader.biHeight = this->infoheader.biWidth;
        pinfoheader.biWidth = this->infoheader.biHeight;
        //保存图片
        this->WriteBMP("rotate-270.bmp", pdata, pfileheader, pinfoheader);
        this->wfree(pdata, pinfoheader.biHeight);
    }
    }

    else if(degree>0)
    {
    if ((degree%90==0)&&(degree%180!=0)&&(degree%270!=0))
    {
        /*unsigned char **pdata = new unsigned char *[width];
        for (i = 0; i < width; i++)
        {
            pdata[i] = new unsigned char[height];
        }

        for (int i = 0; i < infoheader.biWidth; i++)
        {
            for (int j = 0; j < infoheader.biHeight; j++)
            {
                pdata[i][j] = data[infoheader.biHeight - j - 1][i];
            }
        }
        pinfoheader.biHeight = this->infoheader.biWidth;
        pinfoheader.biWidth = this->infoheader.biHeight;
        //保存图片
        this->WriteBMP("rotate90.bmp", pdata, pfileheader, pinfoheader);
        this->wfree(pdata, pinfoheader.biHeight);*/
        unsigned char **pdata = new unsigned char *[width];
        for (i = 0; i < width; i++)
        {
            pdata[i] = new unsigned char[height];
        }

        for (int i = 0; i < infoheader.biWidth; i++)
        {
            for (int j = 0; j < infoheader.biHeight; j++)
            {
                pdata[i][j] = data[j][pinfoheader.biWidth - i - 1];
            }
        }
        //重写信息头
        pinfoheader.biHeight = this->infoheader.biWidth;
        pinfoheader.biWidth = this->infoheader.biHeight;
        //保存图片
        this->WriteBMP("rotate90.bmp", pdata, pfileheader, pinfoheader);
        this->wfree(pdata, pinfoheader.biHeight);
    }

    else if ((degree %180==0)&&(degree%270!=0))
    {
        int i, j;
        unsigned char **pdata = new unsigned char *[height];
        for (i = 0; i < height; i++)
        {
            pdata[i] = new unsigned char[width];
        }

        for (i = 0; i < height; i++)
        {
            for (j = 0; j < width; j++)
            {
                pdata[height-i-1][width - j - 1] = data[i][j];
            }
        }
        //保存图片
        this->WriteBMP("rotate180.bmp", pdata, pfileheader, pinfoheader);
        this->wfree(pdata, pinfoheader.biHeight);

    }

    else if (degree %270==0)
    {
        /*unsigned char **pdata = new unsigned char *[width];
        for (i = 0; i < width; i++)
        {
            pdata[i] = new unsigned char[height];
        }

        for (int i = 0; i < infoheader.biWidth; i++)
        {
            for (int j = 0; j < infoheader.biHeight; j++)
            {
                pdata[i][j] = data[j][pinfoheader.biWidth - i - 1];
            }
        }
        //重写信息头
        pinfoheader.biHeight = this->infoheader.biWidth;
        pinfoheader.biWidth = this->infoheader.biHeight;
        //保存图片
        this->WriteBMP("rotate270.bmp", pdata, pfileheader, pinfoheader);
        this->wfree(pdata, pinfoheader.biHeight);*/
        unsigned char **pdata = new unsigned char *[width];
        for (i = 0; i < width; i++)
        {
            pdata[i] = new unsigned char[height];
        }

        for (int i = 0; i < infoheader.biWidth; i++)
        {
            for (int j = 0; j < infoheader.biHeight; j++)
            {
                pdata[i][j] = data[infoheader.biHeight - j - 1][i];
            }
        }
        pinfoheader.biHeight = this->infoheader.biWidth;
        pinfoheader.biWidth = this->infoheader.biHeight;
        //保存图片
        this->WriteBMP("rotate270.bmp", pdata, pfileheader, pinfoheader);
        this->wfree(pdata, pinfoheader.biHeight);
    }
    }

    else
    {
        puts("输入的角度不是90的整数倍");
    }
}

void Image::Mean_Variance(float &m, float &var)//求图像的均值和方差,利用参数输出
{
    float sum = 0;
    int i, j;
    for (i = 0; i < height; i++)
    {
        for (j = 0; j < width; j++)
        {
            sum += data[i][j];
        }
    }
    m = sum / (height*width);

    float sum1 = 0;
    for (i = 0; i < height; i++)
    {
        for (j = 0; j < width; j++)
        {
            sum1 += (data[i][j] - m)*(data[i][j] - m);
        }
    }
    var = sum1 / (height*width);
}

//实现友元函数,交换两个Image对象的数据
void Swap(Image &a, Image &b)
{
    unsigned char **pdata;
	int h;
	int w;
	BMPFILEHEADER fh;
	BITMAPINFOHEADER ih;

    h=b.height;
    w=b.width;
    fh=b.fileheader;
    ih=b.infoheader;
    pdata=b.data;

    b.fileheader=a.fileheader;
    b.infoheader=a.infoheader;
    b.height=a.height;
    b.width=a.width;
    b.data=a.data;

    a.fileheader=fh;
    a.infoheader=ih;
    a.height=h;
    a.width=w;
    a.data=pdata;
}
#include <iostream>
#include "Image.h"
#include <cstdlib>
using namespace std;

int main(int argc, char* argv[])
{
	Image img; //创建对象
	//读写BMP文件
	img.ReadBMP("Fruits.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(false);
    printf("图片翻转完成\n");


	//图像的缩放,并保存结果图像文件
	img.Resize(false);//图像缩小
	img.Resize(true);//图像放大
    printf("图片放缩完成\n");


	//获取图像的某点的像素值,并修改, 并保存结果图像文件
	int row = 80;
	int col = 80;
	img.At(row, col);
	img.Set(row, col, 10);
	img.Set(123);
	printf("像素设置完成\n");

	//使用深拷贝构造函数创建新的对象
	Image new_img(img);
	new_img.WriteBMP("new_img.bmp");
    printf("新对象完成\n");

    new_img.Cut(120,120,360,360);

	img.Rotate(0);
	printf("图像翻转90度完成\n");
	img.Rotate(-90);
	printf("图像翻转90度完成\n");
	img.Rotate(-270);
    printf("图像翻转90度完成\n");


	//求图像的均值和方差,并在命令行输出
	float m = 0;
	float var = 0;
	img.Mean_Variance(m, var);
	printf("平均值为:%f\n方差为:%f\n", m, var);


	//交换两个图像的数据
	Image img1("Baboon.bmp");
	Image img2("Lena.bmp");
	Swap(img1, img2);
	//保存交换完的结果图像文件
	img1.WriteBMP("S_img1_baboon.bmp");
	img2.WriteBMP("S_img2_lena.bmp");
	printf("图片交换完成\n");

	return 0;

}

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值