TIFF基于特定tiff图像的读写(C++)

       图像处理, 首先,需要在网上下载一个查看文件十六进制的软件(FlexHEX),根据软件打开对应的图文件,如下图所示为打开tiff深度图的结果。针对本文章tiff图为波纹板的深度图,它的图文件结构首先是文件头、图像数据、DE个数(占4字节),每个DE的类型(每个DE是12个字节)。然后是其他信息,可以不用读取,主要是图像数据和DE目录里面的图像的宽和图像的高。如下图。需要根据软件查看的图文件数据对着TIFF文件格式详解对照着码代码。TIFF文件格式详解在我另一个文章中。

 代码区:只针对于我的tiff图像实现读写(波纹板深度图)因为tiff图像类型太多了,文件信息比bmp位图更灵活。(bmp是固定的位图文件格式)。

tiffFile.cpp

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <algorithm>
#include <Windows.h>
#include <stdio.h>
#include "tiffFile.h"
using namespace std;

/***********定义文件头结构体************/
typedef struct
{
	uint16_t endian;                // (2个字节)字节顺序标志位,值为II或者MM。II表示小字节在前, 又称为littleendian。MM表示大字节在前,又成为bigendian。
	uint16_t magic;                 //(2个字节)TIFF的标志位,一般都是42
	uint32_t ifdOffset;             //(4个字节)第一个IFD的偏移量
}IFH;                                   //文件头变量

uint16_t DE_count;                        //DE的个数
/***************定义DE成员的结构体***********************/
typedef struct
{
	uint16_t tag;                      // (2bit)TAG的唯一标识,每一种tagID代表了它所对应的图像信息,例如长,宽等。
	uint16_t type;                     // (2bit)数据类型,integer类型,long类型,还有RATIONAL类型属于分数类型两个long组成。
	uint32_t size;                     // (4bit)数量,类型和数量可以确定存储此TAG的数据需要占据的字节数
	uint32_t valOffset;                //(4bit)代表数值,对于tag对应图像信息的数值
}DE;
/***************定义IFD目录结构体***********************/
typedef struct
{
	DE ImageWidth;                     //图像的宽
	DE ImageHeight;                    //图像的高
	DE BitsPerSample;                  //位深
	DE Compression;                    //判断是否压缩
	DE PhotometricInterpretation;      //判断是什么图像(灰度?RGB?)
	DE Make;                           //生产商的描述 x0F01
	DE StripOffsets;                   //每个Strip的偏移量
	DE Orientation;                    //方向
	DE SamplesPerPixel;               //每个像素通道个数
	DE RowsPerStrip;                   //行
	DE StripByteCounts;                //长度
	DE XResolution;                     //水平分辨率
	DE YResolution;                    //垂直分辨率
	DE PlanarConfiguration;            //计划配置
	DE ResolutionUnit;                 //解析度
	DE Software;                       //软件啥的
	DE DateTime;                       //图像创键日期
	DE ExtraSamples;                   //其他

}IFD;

IFH filehead;                           //定义文件头
IFD infohead;                           //文件信息头
uint16_t othersize[4100];                       //之后的数就没用了,找个空间写入

bool readtiff(char* fileName, int& tiffsize, int& width, int& height, float*& tiffImg)
{
	FILE* fp = fopen(fileName, "rb");    //以二进制读方式打开  
	if (NULL == fp) {
		cout << "File is opened failure!" << endl;
		return FALSE;
	}
	fread(&filehead, sizeof(IFH), 1, fp);
	
	tiffsize = (filehead.ifdOffset - sizeof(filehead));

	tiffImg = new float[tiffsize];
	fread(tiffImg, 1, tiffsize, fp);
	//fseek(fp, filehead.ifdOffset,0);
	//cout << "第一个IFD偏移量" << filehead.ifdOffset << endl; 
	fread(&DE_count, sizeof(DE_count), 1, fp);
	fread(&infohead, sizeof(IFD), 1, fp);
	width = infohead.ImageWidth.valOffset;
	height = infohead.ImageHeight.valOffset;
	fread(&othersize, sizeof(othersize), 1, fp);
	fclose(fp);//关闭文件
	return 1;
}

bool writetiff(char* fileName, int tiffsize, int width, int height, float* tiffimf)
{
	if (!tiffimf)
		return false;
	//以二进制写的方式打开指定图像文件
	FILE* fp = fopen(fileName, "w+b");
	if (fp == 0) return false;
	fwrite(&filehead, sizeof(IFH), 1, fp);//向文件中写入位图文件头
	fwrite(tiffimf, 1, tiffsize, fp);
	fwrite(&DE_count, sizeof(DE_count), 1, fp);
	fwrite(&infohead, sizeof(IFD), 1, fp);//向文件中写入位图信息头
	fwrite(&othersize, sizeof(othersize), 1, fp);
	return 1;
}

tiffFile.h

#pragma once
#include <iostream>
using namespace std;
bool readtiff(char* fileName, int& tiffsize, int& width, int& height, float*& tiffImg);
bool writetiff(char* fileName, int tiffsize, int width, int height, float* tiffimf);

main.cpp

#define _CRT_SECURE_NO_WARNINGS
#include <string>
#include <cstdint>
#include <cstring>
#include <math.h>
#include <fstream>
#include <algorithm>
#include <stdio.h>
#include <Windows.h>
#include "tiffFile.h"
#include "data_collation.h"





int main()
{
	int width, tiffsize, height;
	float* tiffImg;       //定义读入的图像数据

	clock_t startTime, endTime;
	startTime = clock();       //计时开始

	char readPath[]= "D:\\机器视觉学习工程\\波纹板深度检测\\111.tif";
	readtiff(readPath,tiffsize, width,  height, tiffImg);
	cout << "宽" << width << endl;
	cout << "高" << height << endl;

	float* tiffout = new float[tiffsize];
	memset(tiffout, 0, tiffsize);

	data_collation(tiffImg, tiffout, height, width);   //图像处理函数单纯读写需要去掉
	
	
	char writePath[] = "D:\\机器视觉学习工程\\波纹板深度检测\\111write.tif";
	writetiff(writePath,tiffsize,width, height, tiffout);
	cout << width << endl;
	ShellExecuteA(nullptr, "open", writePath, "", "", SW_SHOW);     //打开写入的位图结果
	endTime = clock();    //计时结束
	cout << "The run time is: " << (float)(endTime - startTime) / CLOCKS_PER_SEC << "s" << endl;
	delete[] tiffImg;
	delete[] tiffout;
}

完事!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值