一个tif转bmp的示例

本文受了https://blog.csdn.net/m0_46340275/article/details/105476139 的启发。

bmp的格式是RGBRGB.....排列下来的,每个像素的三个分量靠在一起,描述完一个像素,接着描述下一个像素。

tif的格式更多样。通常的格式也是BGRBGR.....(次序与bmp相反)排列下来的,但偶尔有一些tif文件采用RRRRRR.......GGGGG.........BBBBB.....的安排。还有的tif文件内容是压缩过的。。。。这里我们只考虑三个颜色分量靠在一起的情况。

下面的例子是一个tif文件,宽896,高608,三个分量。这里先把其内容取出,并交换RB的位置,然后保存为.rgb文件。再给这个rgb文件加上头,形成bmp。

#include<iostream>
#include<fstream>
#include<cmath>


const int cnst_iWidth = 896;//图宽
const int cnst_iHeight = 608;
const int cnst_iChan = 3;//RGB三通道
#pragma pack(2)
struct bmpHeader {
	short type;
	unsigned int size;
	unsigned int reserved ;
	unsigned int offbit;
public:
	bmpHeader()
	{
		type=0 ;
		size=0 ;
		reserved=0 ;
		offbit=0 ;
	}
};//文件头
struct bmpInfo {
	unsigned int size ;
	unsigned int width ;
	unsigned int height;
	short planes;
	unsigned int bitcount;
	unsigned int compression;
	unsigned int sizeimage;
	unsigned int XP;
	unsigned int YP;
	unsigned int clr ;
	unsigned int clrsig ;
public:
	bmpInfo()
	{
	size=40 ;
	width=cnst_iWidth ;
	height= cnst_iHeight;
	planes=1 ;
	bitcount=24 ;
	compression=0;
	sizeimage=0;
	 XP=0 ;
	YP=0 ;
	clr=0 ;
	clrsig=0 ;
	}
};//信息头
int rgb2bmp(bmpHeader*, bmpInfo*);



using namespace std;
const char*pathin = "earthRGBRGB.tif";
const char*pathout = "earth.rgb";
unsigned char*buffer = new unsigned char[12];
int main()
{
	int off_img=0;//图像数据偏移量
	ifstream in(pathin, ios::binary);
	ofstream out(pathout, ios::binary);
	bmpHeader head;
	bmpInfo info;
	in.read((char*)buffer, 8);
	if (!in.is_open()) { cout << "open failed" << endl; }
	int offset = 0;//文件目录的偏移量
	offset = (buffer[7] << 24) + (buffer[6] << 16) + (buffer[5] << 8) + buffer[4];
	in.seekg(offset);
	in.read((char*)buffer, 2);
	unsigned int package_num = buffer[0] + (buffer[1] << 8);
	class package
	{
	public:
		unsigned char tag_ID[2];
		unsigned char type[2];
		unsigned char num[4];
		unsigned int data[4];
	};//定义了目录项
	
	package*a= new package[package_num];
	head.type = 0x4d42;
	head.size = cnst_iWidth * cnst_iHeight * cnst_iChan + 54;
	head.offbit = 54;
	info.size = 40;

	for (int i = 0; i < package_num; i++)
	{
		in.read((char*)buffer, 12);
		for (int j = 0; j < 2; j++) { a[i].tag_ID[j] = buffer[j]; }
		for (int j = 0; j < 2; j++) { a[i].type [j]= buffer[j + 2]; }
		for (int j = 0; j < 4; j++) { a[i].data[j] = buffer[j + 8];  }
		if (a[i].tag_ID[0]== 17&&a[i].tag_ID[1]==01) {
			 off_img = (a[i].data[3] << 24) + (a[i].data[2] << 16) + (a[i].data[1] << 8) + a[i].data[0];
			cout << off_img << endl;
		}
		if (a[i].tag_ID[0] ==23&&a[i].tag_ID[1]==01) 
		{
			for (int j = 0; j < 4; j++) { cout << a[i].data[j] << endl; }
			unsigned int length = (a[i].data[3] << 24) + (a[i].data[2] << 16) + (a[i].data[1] << 8) + a[i].data[0];
			unsigned char*data = new unsigned char[length];
			in.seekg(off_img);
			in.read((char*)data, length);
			for (int i = 0; i < length; i = i + 3)
			{
				unsigned char ucTmp = data[i];
				data[i] = data[i + 2];
				data[i + 2] = ucTmp;
			}
			out.write((char*)data, length);
			out.close();
			in.seekg((i+1)*12+2+offset, ios::beg);
		}
	}
	in.close();
	rgb2bmp(&head, &info);
	system("pause");
    return 0;
}


const char*pathbmp = "earthRGBRGB.bmp";
unsigned char*bufferrgb = new unsigned char[cnst_iWidth * cnst_iHeight * cnst_iChan ];
int rgb2bmp(bmpHeader*A,bmpInfo*B)
{
	ifstream rgb(pathout, ios::binary);
	ofstream bmp(pathbmp, ios::binary);
	rgb.read((char*)bufferrgb, cnst_iWidth * cnst_iHeight * cnst_iChan);
	bmp.write((char*)A, 14);
	bmp.write((char*)B, 40);
	bmp.write((char*)bufferrgb, cnst_iWidth * cnst_iHeight * cnst_iChan);
	bmp.close();
	rgb.close();
	system("pause");
	return 0;
}

原tif文件

新的bmp文件:

两图上下翻转,这是因为bmp把图片最底部一行的像素放在文件的前面,而图片最顶部的一行放在文件后面。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值