续实验四:源码

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<Windows.h>
#include<cstdio>
#include<cstdlib>
using namespace std;
unsigned char **  ReadBMP(const char* filename, BITMAPFILEHEADER *filehead , BITMAPINFOHEADER *infohead)
{//读取已知文件中的信息存入到二级指针**d中
    unsigned char** d;
    FILE* fp = fopen(filename, "rb");
    if (!fp)
    {
        printf("文件打开错误");
        exit(0);
    }
    long width, height;
    fread(filehead, sizeof(BITMAPFILEHEADER), 1, fp);//读取文件头
    fread(infohead, sizeof(BITMAPINFOHEADER), 1, fp);//读取信息头
    height = infohead->biHeight ;//读取像素高度
    width = infohead->biWidth;//读取像素宽度
    // 当读入的图像是"Fruits_480x511.jpg"时,这个图像每行字节数不是4的整数倍,文件里每行都有补零
    // 你的这个函数应该能够正确处理这种情况
    //补0
    if (height % 4 != 0)
    {
        height = (height * (infohead->biBitCount) / 8 + 3) / 4 * 4;
        height = height / 3;
    }
    if (width % 4 != 0)
    {
        width = (width* (infohead->biWidth)/ 8 + 3) / 4 * 4;
        width = width / 3;
    }
    //动态开辟内存空间,二维数组
    d = new unsigned char* [height];
    int i, j;
    unsigned char a, b, c;//像素点信息
    for (i = 0; i < height; i++)
    {
        d[i] = new unsigned char[width];
    }
    for (i = 0; i < height; i++)
    {
        for (j = 0; j < width; j++)
        {
            fread(&a, sizeof(unsigned char), 1, fp);
            fread(&b, sizeof(unsigned char), 1, fp);
            fread(&c, sizeof(unsigned char), 1, fp);
            d[i][j] = (a + b + c) / 3;
        }
    }
    fclose(fp);
    return d;
}
void WriteBMP(char *filename,BITMAPFILEHEADER filehead, BITMAPINFOHEADER infohead, unsigned char** p)
{

    FILE* fp= fopen(filename, "wb");
    if (fp == NULL)
    {
        printf("文件打开失败");
        exit(0);
    }
    fwrite(&filehead, sizeof(BITMAPFILEHEADER), 1, fp);
    fwrite(&infohead, sizeof(BITMAPINFOHEADER), 1, fp);
    // fwrite(img, sizeof(RGB), size, pfout);
    int height, weight;
    height = infohead.biHeight;
    weight = infohead.biWidth;
    int i, j, k;
    for (i = 0; i < height; i++)
    {
        for (j = 0; j < weight; j++)
        {
            for (k = 0; k < 3; k++)
                fwrite(&p[i][j], sizeof(unsigned char), 1, fp);
        }
    }
    fclose(fp);
    /* for (i = 0; i < height; i++)//释放空间
         delete[] p[i];
     delete p;*/
}
void FlipImageUpDown(unsigned char** d, int rows, int cols) 
{ 

    int i, j;
    unsigned char **d1=new unsigned char *[rows];
    for (i = 0; i < rows; i++)
    {
        d1[i] = new unsigned char[cols];
    }
    for (i = 0; i < rows; i++)
    {
        for (j = 0; j < cols; j++)
        {
            d1[i][j] = d[i][j];
        }
    }
    for (i = 0; i < rows; i++)
    {
        for (j = 0; j < cols; j++)
        {
            d[i][j] = d1[rows - i - 1][j];
        }
    }//释放动态分配的
    for (i = 0; i < rows; i++)
    {
        delete[]d1[i];
    }
    delete []d1;
}

void FlipImageLeftRight(unsigned char** d, int rows, int cols)
{
    int i, j;
    unsigned char** d1 = new unsigned char* [rows];
    for (i = 0; i < rows; i++)
    {
        d1[i] = new unsigned char[cols];
    }
    for (i = 0; i < rows; i++)
    {
        for (j = 0; j < cols; j++)
        {
            d1[i][j] = d[i][j];
        }
    }
    for (i = 0; i < rows; i++)
    {
        for (j = 0; j < cols; j++)
        {
            d[i][j] = d1[i][cols-j-1];
        }
    }//释放动态分配
    for (i = 0; i < rows; i++)
    {
        delete[]d1[i];
    }
    delete []d1;
}
void ResizeImage(unsigned char** d, int rows, int cols)
{
    unsigned char **d1 = new unsigned char* [rows / 2];
    int i, j;
    for (i = 0; i < rows / 2; i++)
    {
        d1[i] = new unsigned char[cols / 2];
    }
   for (i = 0; 2 * i < rows; i++)
    {
        for (j = 0; 2 * j < cols; j++)
        {
            d1[i][j] = d[i*2][j*2];
        }
    }
    for (i = 0; i < rows / 2; i++)
    {
        for (j = 0; j < cols / 2; j++)
        {
            d[i][j] = d1[i][j];
        }
    }
}
void WriteBMP2(char* filename, BITMAPFILEHEADER filehead, BITMAPINFOHEADER infohead, unsigned char** p)
{

    FILE* fp = fopen(filename, "wb");
    if (fp == NULL)
    {
        printf("文件打开失败");
        exit(0);
    }  
    infohead.biHeight /= 2;//长宽各变成1/2
    infohead.biWidth /= 2;
    fwrite(&filehead, sizeof(BITMAPFILEHEADER), 1, fp);
    fwrite(&infohead, sizeof(BITMAPINFOHEADER), 1, fp);
    // fwrite(img, sizeof(RGB), size, pfout);
    int height, weight;
    height = infohead.biHeight;
    weight = infohead.biWidth;
    int i, j, k;
    for (i = 0; i < height; i++)
    {
        for (j = 0; j < weight; j++)
        {                
            for (k = 0; k < 3; k++)
            fwrite(&p[i][j], sizeof(unsigned char), 1,fp);
        }
    }
    fclose(fp);
    /* for (i = 0; i < height; i++)//释放空间
         delete[] p[i];
     delete p;*/
}
int main(int argc, char* argv[])
{
    // 调用你写的读取BMP图像的函数,读取数据到二维数组
    // write your code here
    BITMAPFILEHEADER filehead;//文件头
    BITMAPINFOHEADER infohead;//信息头
    char filename[100];//文件名
    cout << "请输入你想要操作的文件名"<<endl;
    cin >> filename;
    char filename2[100];
    cout << "1:上下翻转"<<endl;
    cout << "2:左右翻转" << endl;
    cout << "3:缩小图片为2分之一" << endl;
    cout << "请输入你想要的操作" << endl;
    int e;
    cin >> e;
    unsigned char **a= ReadBMP(filename, &filehead, &infohead);//定义存储信息的数组指针
   //ReadBMP(filename,a, &filehead, &infohead);//读取图片中的信息存入到二维数组a中
    long height = infohead.biHeight;
    long  width = infohead.biWidth;
    long i, j;
    switch (e)
    {
    case 0:
        cin >> filename2;
        WriteBMP( filename2,filehead, infohead,a);
        cout << "灰度化图片保存完整存入:" << filename2 ;
        break;
    case 1:
        FlipImageUpDown(a, height, width);
        cin >> filename2;
        WriteBMP(filename2, filehead, infohead, a);
        cout << "上下翻转的灰度化图片完整存入::" << filename2 ;
        break;
    case 2:
        FlipImageLeftRight(a, height, width);
        cin >> filename2;
        WriteBMP(filename2, filehead, infohead, a);
        cout << "左右翻转的灰度化图片完整存入::" << filename2;
        break;
    case 3:
        ResizeImage(a, height, width);
        cin >> filename2;
        WriteBMP2(filename2, filehead, infohead, a);
        cout << "缩小为1/2灰度化图片完整存入::" << filename2;
        break;
    default :
        cout << "退出" << endl;
        break;
    }
    return 0;
}

程序结果图片

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值