本机系统配置:ThinkPadT570、Windows10、QT5.12.2(QtCreater4.8.2)
需求如下:我们需要用qt导入16位深的tiff灰度图,但用QImage只能导入8位深的tiff灰度图,如果用qt的QImage导入16位深的灰度图,图像数据会被强制转换成argb格式的图像,数据就被更改了,所以我需要自己编写一个解析tiff文件的功能,我翻阅了很多博客,其中如下链接给我的帮助最大:
https://blog.csdn.net/chenlu5201314/article/details/56276903
上述博客作为详细解析tiff文件结构的说明文档,写的非常详细,我也是根据上面的内容,自己编写了一个解析tiff文件的类(当然功能很少,只能解析符合特定条件的tiff文件),具体如下:
头文件:

#ifndef MYTIFLIB_H
#define MYTIFLIB_H
//************************************************************
//by Bruce Xu
//注:该类只解析特定的tiff文件!
//1.解析的tiff文件中只存在一幅图,如果文件中存在多幅图,本类不支持解析!
//2.图像数据为8位或16位深度的灰度图,如果是其他类型的图片,本类不支持解析!
//3.图片没有被压缩过!
//************************************************************
#include <QObject>
#include <QVector>
#include <QString>
#include <QFile>
struct MY_IFH//Image File Head
{qint16          nByteOrder;//TIF标记,其值为0x4D4D或0x4949qint16          nVersion;//版本号,其值恒为0x2Aqint32          nOffset2FirstIFD;//第一个IFD的偏移量
};
struct MY_DE//Directory Entry
{qint16          nTagID;//本属性的标签编号qint16          nType;//本属性值的数据类型qint32          nLength;//该种类型的数据的个数,而不是某个数据的长度qint32          nValueOffset;//tagID代表的变量值相对文件开始处的偏移量,但如果变量值占用的空间不多于4个字节(例如只有1个Integer类型的值),那么该值就直接存放在valueOffset中,没必要再另外指向一个地方了。
};
struct MY_IFD//image file directory
{qint16          nIDNum;//本IFD中DE的数量QVector<MY_DE>  vMyDE;//本IFD中的DE
};struct MY_ImgInfo//图片属性信息
{qint32          nHeight;//图像的宽度qint32          nWidth;//图像的高度qint16          nDepth;//图像的深度bool            bCompressed;//图像是否被压缩qint32          nDataOffset;//图像第一个像素数据距离的偏移多少字节qint32          nDataSize;//图像数据字节总数
};struct MY_TIFF//Image File Struct
{MY_IFH                  tMyIFH;//Image File HeadMY_IFD                  tMyIFD;//放image file directory的容器QVector<unsigned char>  vUcharData;//如果是8位深的灰度图用unsigned char 放数据QVector<unsigned short> vShortData;//如果是16位深的灰度图用short* 放数据MY_ImgInfo              tImgInfo;//图片属性信息
};class MyTifLib
{
public:MyTifLib();~MyTifLib();bool            ParseTIFF(QString sFilePath, MY_TIFF &myTIFF);
};#endif // MYTIFLIB_H

源文件:

#include "mytiflib.h"
MyTifLib::MyTifLib()
{
}
MyTifLib::~MyTifLib()
{
}
bool MyTifLib::ParseTIFF(QString sFilePath, MY_TIFF &myTIFF)
{QFile file(sFilePath);if(!file.open(QIODevice::ReadOnly)){return false;}QByteArray t = file.readAll();file.close();memcpy((char*)&myTIFF.tMyIFH.nByteOrder,t.data(),2*sizeof(char));memcpy((char*)&myTIFF.tMyIFH.nVersion,t.data()+2,2*sizeof(char));memcpy((char*)&myTIFF.tMyIFH.nOffset2FirstIFD,t.data()+4,4*sizeof(char));memcpy((char*)&myTIFF.tMyIFD.nIDNum,t.data()+myTIFF.tMyIFH.nOffset2FirstIFD,2*sizeof(char));myTIFF.tMyIFD.vMyDE.resize(myTIFF.tMyIFD.nIDNum);for (int i=0;i<myTIFF.tMyIFD.nIDNum;i++){memcpy((char*)&myTIFF.tMyIFD.vMyDE[i].nTagID,t.data()+myTIFF.tMyIFH.nOffset2FirstIFD+2+12*i,2*sizeof(char));memcpy((char*)&myTIFF.tMyIFD.vMyDE[i].nType,t.data()+myTIFF.tMyIFH.nOffset2FirstIFD+2+12*i+2,2*sizeof(char));memcpy((char*)&myTIFF.tMyIFD.vMyDE[i].nLength,t.data()+myTIFF.tMyIFH.nOffset2FirstIFD+2+12*i+4,4*sizeof(char));memcpy((char*)&myTIFF.tMyIFD.vMyDE[i].nValueOffset,t.data()+myTIFF.tMyIFH.nOffset2FirstIFD+2+12*i+8,4*sizeof(char));if(myTIFF.tMyIFD.vMyDE[i].nTagID == 0x0100)//表示图像宽度{myTIFF.tImgInfo.nWidth = myTIFF.tMyIFD.vMyDE[i].nValueOffset;}if(myTIFF.tMyIFD.vMyDE[i].nTagID == 0x0101)//表示图像高{myTIFF.tImgInfo.nHeight = myTIFF.tMyIFD.vMyDE[i].nValueOffset;}if(myTIFF.tMyIFD.vMyDE[i].nTagID == 0x0102)//表示图像每个像素深度,即占多少位宽{myTIFF.tImgInfo.nDepth = myTIFF.tMyIFD.vMyDE[i].nValueOffset;}if(myTIFF.tMyIFD.vMyDE[i].nTagID == 0x0103)//表示图像数据是否压缩{if(myTIFF.tMyIFD.vMyDE[i].nValueOffset == 5){myTIFF.tImgInfo.bCompressed = true;}else{myTIFF.tImgInfo.bCompressed = false;}}if(myTIFF.tMyIFD.vMyDE[i].nTagID == 0x0111)//图像数据起始字节相对于文件开始处的偏移量{myTIFF.tImgInfo.nDataOffset = myTIFF.tMyIFD.vMyDE[i].nValueOffset;}if(myTIFF.tMyIFD.vMyDE[i].nTagID == 0x0117)//图像数据字节总数{myTIFF.tImgInfo.nDataSize = myTIFF.tMyIFD.vMyDE[i].nValueOffset;}}if(myTIFF.tImgInfo.bCompressed){return false;}if(myTIFF.tImgInfo.nDepth == 16){//TODO:myTIFF.vShortData.resize(myTIFF.tImgInfo.nWidth*myTIFF.tImgInfo.nHeight);if(myTIFF.vShortData.size()<1){return false;}memcpy((char*)&myTIFF.vShortData[0],t.data()+myTIFF.tImgInfo.nDataOffset,myTIFF.tImgInfo.nDataSize*sizeof(char));}else if(myTIFF.tImgInfo.nDepth == 12){//TODO:myTIFF.vShortData.resize(myTIFF.tImgInfo.nWidth*myTIFF.tImgInfo.nHeight);if(myTIFF.vShortData.size()<1){return false;}memcpy((char*)&myTIFF.vShortData[0],t.data()+myTIFF.tImgInfo.nDataOffset,myTIFF.tImgInfo.nDataSize*sizeof(char));}else if(myTIFF.tImgInfo.nDepth == 8){//TODO:myTIFF.vUcharData.resize(myTIFF.tImgInfo.nWidth*myTIFF.tImgInfo.nHeight);if(myTIFF.vUcharData.size()<1){return false;}memcpy((char*)&myTIFF.vUcharData[0],t.data()+myTIFF.tImgInfo.nDataOffset,myTIFF.tImgInfo.nDataSize*sizeof(char));}else{return false;}return true;
}

用法:
首先包含该类头文件
#include “”
然后在需要用的地方添加如下代码:
MyTifLib m_MyTifLib;//定义一个类对象
MY_TIFF myTIFF;//定义一个tiff数据结构体
m_MyTifLib.ParseTIFF(“需要解析的tiff文件路径的QString类型的字符串”,myTIFF);//解析tiff文件
这时候,你要的tiff文件中的图像数据就在myTIFF.vShortData或者myTIFF.vUcharData里面了。
注:如果需要解析的图像是8位深的,则数据存放在myTIFF.vUcharData里面
如果需要解析的图像是16位深的,则数据存放在myTIFF.vShortData里面

源码地址:https://download.csdn.net/download/weixin_43935474/11188206

用qt编写的解析tiff文件的类相关推荐

  1. [转载]VC轻松解析XML文件 - CMarkup类的使用方法

    VC轻松解析XML文件 - CMarkup类的使用方法 VC解析XML文件的工具有很多,CMarkup, tinyXML,还有IBM的,MS的等等. 据说tinyXML很好,可能字符集问题,我编译不了 ...

  2. 自己编写一个读取TGA文件的类

    自己编写一个读取TGA文件的类 TGA文件,也就是Targa文件,是一种图片的格式,在游戏和绘图领域中用得比较广泛.TGA文件是位图文件,存储着各个像素的颜色信息.本来想直接使用<OpenGL超 ...

  3. Qt/C++ + opengl 解析stl文件(二进制和Ascii两种格式)

    前言: 3D 的stl 模型文件分为两种 二进制和Ascii 明码的Ascii 内容清晰可以打开看,但是文件比较大 二进制的文件 看不到内容 但是占用空间小 我是用 qt + opengl 加载 st ...

  4. Java解析eml文件工具类

    依赖 <!-- https://mvnrepository.com/artifact/javax.mail/mail --><dependency><groupId> ...

  5. POI解析Excel文件工具类

    /*** 读取excel数据*/public static List<Map<String, Object>> exportListFromExcel(File file, i ...

  6. java解析csv文件工具类,java操作CSV文件工具类

    离线路灯 UID:3 注册时间2011-08-21 最后登录2021-03-15 在线时间5398小时 发帖659 精华44 金币3650 威望1881 股份280 发帖659 金币3650威望188 ...

  7. 基于QT编写的周立功CAN,可进行uds、bootloder的上位机开发

    基于QT编写的解析周立功CAN 1.介绍 应用场景:需要将CAN数据传输到上位机. 可以进行界面显示,做一些基于can的演示系统等 2.封装的模块 1.CanComm.c 中间层 封装通信函数 封装了 ...

  8. 第六章、epub文件处理 -- 解析container文件与.opf文件

    2019独角兽企业重金招聘Python工程师标准>>> 第六章.epub文件处理 -- 解析container文件与.opf文件 这一章我们会接着第三章结尾介绍的FBReaderAp ...

  9. Android中使用SAX方式解析XML文件

    转载http://blog.csdn.net/cjjky/article/details/6666834 在Android中解析XML文主要有三种方式,分别为Simple API for XML(SA ...

  10. Qt Creator使用Clang代码模型解析C ++文件

    Qt Creator使用Clang代码模型解析C ++文件 使用Clang代码模型解析C ++文件 关于Clang代码模型 配置C语代码模型 lang检查 在项目级别指定Clang代码模型设置 使用编 ...

最新文章

  1. python爬取岗位数据并分析_区块链岗位薪资高,Python爬取300个区块链岗位分析,龙虎榜出炉...
  2. leetcode练习
  3. 【OS】经典调度算法
  4. REVERSE-PRACTICE-BUUCTF-7
  5. 1.3 编程基础之算术表达式与顺序执行 04 带余除法
  6. JVM专题之类加载机制
  7. qml 不刷新 放大还原_【显示器选择详解】你的电脑能否带动高分辨率,高刷新率显示器?...
  8. 力扣——最后一个单词的长度
  9. bzoj 3514: Codechef MARCH14 GERALD07加强版
  10. 硬盘根目录里的Msdia80.dll文件是干什么用的
  11. JavaMail 邮件附件名乱码问题
  12. Linux 调用openoffice报错 disconnected unexpectedly
  13. 低版本ie浏览器禁用提示
  14. stm32f103移植到stm32f105的时钟问题
  15. 手把手教你搭APM之Skywalking搭建指南(支持Java/C#/Node.js)
  16. 【一句日历】2019年5月
  17. 第十三章 失业、通货膨胀和经济周期
  18. 帝国,又是帝国... ...
  19. 1.虚拟机克隆后的处理步骤
  20. LintCode 764. 计算圆周长和面积 Java算法

热门文章

  1. php怎么做一个音乐播放器,音乐播放器的制作实例(html5)
  2. 坚守,一个烂俗的词,驱动人生带它走过了15年
  3. mysql外键设置sql语句_数据库sql语句如何设置外键
  4. CANoe软件打不开了怎么办?
  5. Unreal 凹多边形三角化
  6. 使用ASP.NET快速开发平台,获得表单源码,用珍藏资料换来的代码生成器!
  7. 项目经理和产品经理之区别
  8. python 设备ArtNetToDMX512的协议测试
  9. 稳定kms服务器,kms服务器
  10. 点餐推荐系统_类似美团外卖点餐系统APP开发平台模式