Class written using qt resolution tiff file

This system configuration: ThinkPadT570, Windows10, QT5.12.2 (QtCreater4.8.2 )
requirements are as follows: we need to import 16-bit grayscale tiff with deep qt, but only with the introduction QImage eight deep grayscale tiff, if QImage qt introduction of 16-bit grayscale depth, image data will be cast to the image argb format, the data is changed, so I need to write a parse function tiff file, I read a lot of blog, which the following link to help my biggest:
https://blog.csdn.net/chenlu5201314/article/details/56276903
above blog as documentation for detailed analysis tiff file structure and write very detailed, I am also in accordance with the above, himself I wrote a tiff file parsing classes (of course features small, can only be resolved tiff files that meet specific criteria), as follows:
header:

#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或0x4949
    qint16          nVersion;//版本号,其值恒为0x2A
    qint32          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 Head
    MY_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

Source File:

#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;
}

Usage:
First, the header file that contains the class
#include ""
and then add the following code where needed:
MyTifLib m_MyTifLib; // define a class object
MY_TIFF myTIFF; // define a data structure tiff
m_MyTifLib.ParseTIFF ( "to parse QString type of tiff file path string ", myTIFF); // parse tiff file
at this time, the image data tiff file you want in just myTIFF.vShortData or myTIFF.vUcharData inside.
Note: If you need to resolve the image depth is 8 bits, the data stored in myTIFF.vUcharData which
if desired resolved image depth is 16 bits, the data stored in the inside myTIFF.vShortData

Source Address: https://download.csdn.net/download/weixin_43935474/11188206

Guess you like

Origin blog.csdn.net/weixin_43935474/article/details/90298671