程序设计基础课程设计—位图图像文件缩放

本文介绍了一个命令行工具,用于处理BMP图像文件的缩放,包括位图文件结构理解、缩放算法设计、测试实例与源代码。重点讲解了如何通过BMP文件头和位图信息头进行操作,以实现不同比例的位图压缩并保存为新文件。
摘要由CSDN通过智能技术生成

个人博客地址:https://travis1024.github.io/

位图图像文件缩放

1. 问题描述

编写一个程序,可以在命令行输入参数,完成指定文件的缩放,并存储到新文件,命令行参数如下: zoom file1.bmp 200 file2.bmp

第一个参数为可执行程序名称,第二个参数为原始图像文件名,第三个参数为缩放比例(百分比),第四个参数为新文件名

2. 问题分析

  1. 提前查阅资料,熟悉BMP位图文件结构,知道怎么通过命令行参数读取相应的BMP文件;
    2) 明确解决BMP位图文件的按比例压缩问题的步骤;
    3) 明确解决存储压缩后生成的BMP文件的问题的步骤;

3. 处理方法设计(算法步骤)

  • 整个bmp文件的内容可以分为3到4块,第一块是bmp的文件头用于描述整个bmp文件的情况。结构如下:

    ​ 第一个bfType用于表示文件类型,如果它是bmp文件,那么它这个位置的值一定是”BM” 也就是0x4D42。第二个bfSize表示整个文件的字节数。第三第四个 则保留,目前无意义,最后一个相当重要,表示,位图的数据信息离文件头的偏移量,以字节为单位。

  • 第二块是位图信息头,即BITMAPINFOHEADER,用于描述整个位图文件的情况,结构如下:

  • 第三块就是调色板信息或者掩码部分,如果是8位位图 则存放调色板 ;16 与32位位图则存放RGB颜色的掩码,这些掩码以DWORD大小来存放。

  • 为了进行放缩操作,我们根据放缩的比例把后来对应的图片的位置的像素,映射到原先的像素位置,用原先的像素进行填充。

  • 位图快速缩放公式:

4.测试数据设计

原文件为travis.bmp,通过以下两个命令生成两张新的bmp文件:
Third travis.bmp 200 Large_travis.bmp
Third travis.bmp 20 Small_travis.bmp

5.测试结果分析

6.程序结构

7.源代码

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#pragma pack(1)
using namespace std;
typedef struct   ClBitMapFileHeader {	//文件信息
	unsigned short    bfType;			//文件信息类型
	unsigned long    bfSize;			//文件大小
	unsigned short    bfReserved1;
	unsigned short    bfReserved2;
	unsigned long    bfOffBits;			//文件头到真正的数据之间的数据量
} tagBITMAPFILEHEADER;
typedef struct   ClBitMapInfoHeader {	//BMP信息
	unsigned long  biSize;				//此结构默认字节数40
	long   biWidth;
	long   biHeight;
	unsigned short   biPlanes;			//颜色平面,总是1
	unsigned short   biBitCount;		//比特数/像素 ,一般是24,(真彩色)
	unsigned long  biCompression;		//压缩方式,这里一般是0,真彩色图像
	unsigned long  biSizeImage;			//图像大小
	long   biXPelsPerMeter;				//水平分辨率
	long   biYPelsPerMeter;				//垂直分辨率
	unsigned long   biClrUsed;			//颜色索引
	unsigned long   biClrImportant;		//重要颜色信息,一般是0
}tagBITMAPINFOHEADER;

void Transtition(char source[],char target[],double times) {

	FILE* f1 = fopen(source,"rb");
	FILE* f2 = fopen(target,"wb");
	if(f1 == NULL || f2 == NULL){
		cout << "File read/write error!" << endl;
	}
	tagBITMAPFILEHEADER filehead;		 //文件头
	tagBITMAPINFOHEADER BMPhead;		 //BMP头
	fread(&filehead,sizeof(filehead),1,f1);
	fread(&BMPhead,sizeof(BMPhead),1,f1);

	long width = BMPhead.biWidth;		 //获取宽度和高度
	long height = BMPhead.biHeight;

	unsigned char *data = (unsigned char*)malloc(sizeof(unsigned char)*width*3*height);//获取真正的数据信息
    fseek(f1,54,SEEK_SET);
	fread(data,width*3*height,1,f1);

	long new_width = (long)1.0*times*width;			//新的图片的宽度
	long new_height = (long)1.0*times*height;		//新的图片的高度
    filehead.bfSize = new_width*new_height*3+54;	//更改文件的信息头和BMP信息头
    BMPhead.biHeight = new_height;
	BMPhead.biWidth = new_width;
	fwrite(&filehead,sizeof(filehead),1,f2);
	fwrite(&BMPhead,sizeof(BMPhead),1,f2);

	unsigned char *new_data = (unsigned char*)malloc(sizeof(unsigned char)*new_width*3*new_height);//分配新的数据空间
	long src_x,src_y;//代表原x和y;

	for(long i=0;i<new_height;i++){
		src_y = (long)1.0*i/times;
		unsigned char *src_row_begin = data + src_y*3*width;//换算成原先行的起始处;
		for(long j=0;j<new_width;j++){
			src_x = (long)1.0*j/times;
			memcpy(new_data + i*new_width*3+j*3,src_row_begin + src_x * 3,3);
		}
	}
	fseek(f2,54,SEEK_SET);
	fwrite(new_data,new_width*3*new_height,1,f2);
	cout << "New BMP image generated successfully!" << endl;
	free(data);
	free(new_data);
	fclose(f1);
	fclose(f2);
}
int main(int argc,char** argv){
	double times= atof(argv[2])/100.0;
	Transtition(argv[1],argv[3],times);
	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值