Implementation of tiff to bmp

tiff file format, see the article content before
this experiment, they used to do ps uncompressed image, a preview 160 * 90 follows
Insert picture description here
due rgb itself is stored upside down, hoping to get a reverse image
black and white facilitate Finding errors in binary files, the implementation is as follows:

header.h

The file declares the file header and information header to be used for conversion to bmp

#ifndef HEADER_H
#define HEADER_H
#include"stdafx.h"
#include<iostream>
#include<fstream>
#include<cmath>

#pragma pack(2)
class bmpHeader {
public:
	short type=0 ;
	unsigned int size=0 ;
	unsigned int reserved=0 ;
	unsigned int offbit=0 ;
};//文件头
class bmpInfo {
public:
	unsigned int size=40 ;
	unsigned int width=160 ;
	unsigned int height=90;
	short planes=1 ;
	unsigned int bitcount=24 ;
	unsigned int compression=0;
	unsigned int sizeimage=0;
	unsigned int XP=0 ;
	unsigned int YP=0 ;
	unsigned int clr=0 ;
	unsigned int clrsig=0 ;
};//信息头
int rgb2bmp(bmpHeader*, bmpInfo*);

#endif // !HEADER_H

#pragma pack (2) is used to prevent the structure from automatically aligning. I did n’t pay attention to this before and made my bmp file header wrong. The picture ca n’t be opened.
In addition , I ’m lazy here. I did n’t read the length and width and color format from the corresponding tiff directory item. , Defined at the time of declaration, the implementation of reading is similar to the process of reading image data below

Preparation before processing

#include"header.h"
using namespace std;
const char*pathin = "pic.tif";
const char*pathout = "pic.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 = 160 * 90 * 3 + 54;
	head.offbit = 54;
	info.size = 40;

The data in the bmp file header is manually defined, and the class definition of the directory item is also completed, and then the data can be processed

data processing

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)
			{
				for (int j = 0; j < 3; j++)
				{
					data[i + j] = data[i + 2 - j];
				}
			}
			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;

After reading the data from the buffer, the judgment is made. Here, all the directory items are not read. Only the required 0111 and 0117 items are read. Here, they are hexadecimal, and the code is decimal. The above is just the tiff image. The data is read out, and the current file is still in the state of rgb. The preview is as follows
Insert picture description here
. The image is exactly the reverse of the original image, and it is
converted to bmp as expected.

rgb2bmp

#include"stdafx.h"
#include"header.h"
using namespace std;

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

There is no palette information because of the true color image of the image used this time.
Let's take a look at the bmp image
Insert picture description here
as expected

Published 5 original articles · Likes0 · Visits 203

Guess you like

Origin blog.csdn.net/m0_46340275/article/details/105476139