【VBA】TIF、TIFFファイルのページ数を取得

 大量にあるマルチTIFFファイルのページ数を取得しようとした場合、意外とページ数取得に苦労します。PowerShellで取得しようにもPDFファイルの様にオブジェクト情報の中にページ数が無く、簡単に取得することができない様です。
 そこで、VBAのバイナリデータ読込みからTIFFファイルのヘッダ情報を確認して、ページ数を取得する方法をご紹介したいと思います。

目次

マクロブックの作成

 新たにマクロブックを作成し、Sheet1のA列、2行目以降に調べたいTIFFファイルのフルパスを入力していきます。マクロ実行した時にB列にページ数が入力されます。

VBA構文

 まず最初にVBAの構文を載せます。解説は抜きにして、とりあえずVBAコードでページ数を取得したい方はこちらのコードをコピペして利用ください。Get_TiffPageの実行でページ数の入力が開始されます。

Option Explicit

Private fn

Type FileHeader
    ByteOrder As String * 2
    VersionNum(1) As Byte
End Type
 
Type Entry_IFD
    TagType(0 To 1) As Byte
    DataType(0 To 1) As Byte
    DataCount(0 To 3) As Byte
    Data(0 To 3) As Byte
End Type

Sub Get_TiffPage()
    Dim TargetRow As Long, maxrow As Long
    maxrow = Sheet1.Cells(Rows.Count, 1).End(xlUp).Row
    For TargetRow = 2 To maxrow
        Sheet1.Cells(TargetRow, 2) = GetPageNumber(Sheet1.Cells(TargetRow, 1))
    Next TargetRow
End Sub

Function GetPageNumber(TiffFileName As String)
    Dim header As FileHeader
    fn = FreeFile
    Open TiffFileName For Binary As fn
    Get fn, , header
    
    Select Case header.ByteOrder
    Case "II"
        Close fn
        GetPageNumber = GetPageNumber_Intel(TiffFileName)
    Case "MM"
        Close fn
        GetPageNumber = GetPageNumber_Motorola(TiffFileName)
    Case Else
        Close fn
        Err.Raise 9999, , "Exception ByteOrder"
    End Select
End Function
 
Function GetPageNumber_Intel(TiffFileName As String)
    Dim header As FileHeader
    Dim TagSize As Integer, Tag() As Entry_IFD, NextIFD As Long
    Dim pagecount As Long
    Dim j As Long
    
    fn = FreeFile
    Open TiffFileName For Binary As fn
    Get fn, , header
    
    If header.VersionNum(0) <> 42 Then
        Close fn
        Err.Raise 9999, , "This is not TiffFile"
        Exit Function
    End If
    
    pagecount = 0
    Do Until EOF(fn)
        Get fn, , NextIFD
        If NextIFD = 0 Then Exit Do
        Seek #fn, NextIFD + 1
        pagecount = pagecount + 1
        Get fn, , TagSize
        If TagSize > 0 Then
            ReDim Tag(1 To TagSize)
            Get fn, , Tag
        End If
    Loop
    Close fn
    GetPageNumber_Intel = pagecount
End Function

Function GetPageNumber_Motorola(TiffFileName As String)
    Dim EntryCount_Byte(1) As Byte, EntryCount_10 As Long, EntryCount_16 As String, Tag() As Entry_IFD
    Dim NextIFD_10 As Long, NextIFD_16 As String
    Dim IFDByte(3) As Byte
    Dim header As FileHeader
    Dim j As Long
    Dim pagecount As Long
    
    fn = FreeFile
    Open TiffFileName For Binary As fn
    Get fn, , header
    
    If header.VersionNum(1) <> 42 Then
        Close fn
        Err.Raise 9999, , "This is not TiffFile"
        Exit Function
    End If
        
    pagecount = 0
    Do Until EOF(fn)
        Get fn, , IFDByte
        NextIFD_16 = Hex(Format(IFDByte(0), "00")) & Hex(Format(IFDByte(1), "00")) & _
                     Hex(Format(IFDByte(2), "00")) & Hex(Format(IFDByte(3), "00"))
        NextIFD_10 = Abs("&H" & NextIFD_16)
        
        If NextIFD_10 = 0 Then Exit Do
        Seek #fn, NextIFD_10 + 1
        pagecount = pagecount + 1
        Get fn, , EntryCount_Byte
        EntryCount_16 = Hex(Format(EntryCount_Byte(0), "00")) & Hex(Format(EntryCount_Byte(1), "00"))
        EntryCount_10 = Abs("&H" & EntryCount_16)
        If EntryCount_10 > 0 Then
            ReDim Tag(1 To EntryCount_10)
            Get fn, , Tag
        End If
    Loop
    Close fn
    GetPageNumber_Motorola = pagecount
End Function

TIFFファイル仕様

 コードを解説する前にTIFFファイルの仕様をある程度理解しておかなければ、VBAコードを読み取り、理解することができません。TIFFファイルの仕様については本も出ていますが、以下のサイトに日本語で網羅されております。わざわざ英語のTIFF仕様を読まずとも日本語で詳しく丁寧に解説されており、TIFFファイル仕様を知るには非常に役立つサイトだと思います。本当にこのサイトが存在してくれていたお陰でTIFF仕様を学ぶ機会を得ることができました。

 以下で備忘記録のため、TIFFファイル仕様について解説していますが、参照元はほぼ我楽多頓陳館さんのホームページから自分なりに読み解き、TIFFの枚数をカウントするために解説している仕様解説内容となっております。なるべく誤解がない状態で解説しているつもりですが、私の解説で矛盾点があったり、よく分からない内容があれば、上記サイトでTIFF仕様を確認していただいても良いと思います。

バイナリエディタ

 バイナリデータを閲覧するには、バイナリエディタが役立ちます。世の中、色々なバイナリエディタがある様ですが、私はBinary Editor BZを利用しています。Vector窓の杜で入手することができます。バイナリエディタでTIFFファイルを開くと以下のイメージになります。1コマに各々16進法でデータが表示されています。1コマ毎にAsciiに変換した文字列が右側に表示されており、バイトオーダ(後述)位でしたら、バイナリエディタで確認することができます。

TIFF仕様概要

TIFFのデータはバイナリデータに属しており、データは複数のブロックに役割が分かれています。

ファイルヘッダ
IFD
画像関連データ
カラーマップ
イメージデータ

 TIFFファイルのブロック構成を左記に載せておきます。
 ファイルヘッダは必ずTIFFファイルの先頭に位置しています。それ以外のブロックは基本的にどこに位置しても良い仕様となっています。
 TIFFファイルの枚数をカウントするためには、ヘッダ情報とIFD(Image File Directory)の情報取得する必要があります。

ファイルヘッダ

 前述のとおり、ファイルヘッダは必ずTIFFファイルの先頭に位置しています。バイナリエディタでTIFFファイルを開くと、先頭8Byteの範囲でファイルヘッダの情報を確認することができます。1ファイルに複数ページをまとめることができるマルチTIFFでもファイルヘッダは一つしかありません。

スクロールできます
ファイルヘッダ
IFD
画像関連データ
カラーマップ
イメージデータ

内容バイト数取得値
バイトオーダー2"MM"(4D4DH)または"II"(4949H)
バージョン番号2固定値42
IFDポインタ4先頭IFDへのバイト単位のオフセット値
バイトオーダー

TIFFファイルがMotorola型(リトルエンディアン)かIntel型(ビックエンディアン)かを示します。
・Motorola型 ⇒ "MM"(4D4DH)を表示
・Intel型 ⇒ "II"(4949H)を表示

バージョン番号

TIFFファイル固有の値が表示されます。2AH(42)が固定値となっています。したがって、この数値が42以外の場合、そのファイルはTIFFファイルではない、ということになります。

IFDポインタ

先頭IFDへのバイト単位のオフセット値が表示されます。表示されているByte位置に変遷し、IFD情報を取得していきます。

IFD(Image File Directory)

 IFDの情報を取得することで、TIFFファイルのプロパティ情報(縦幅、横幅、圧縮方式等)を取得することができます。また、IFDポインタを読み取ることで、複数ページのマルチTIFFの情報を読み込むことができます。

スクロールできます
ファイルヘッダ
IFD
画像関連データ
カラーマップ
イメージデータ

内容バイト数取得値
エントリーカウント21-65535(取得値 = n
IFDエントリー(1番)121番目のIFDエントリ(プロパティ情報)
IFDエントリー(2番)122番目のIFDエントリ(プロパティ情報)
~中略~
IFDエントリー(n-1番)12n-1番目のIFDエントリ(プロパティ情報)
IFDエントリー(n番12n番目のIFDエントリ(プロパティ情報)
IFDポインタ4次のIFDへのバイト単位のオフセット値
エントリーカウント

IFDに含まれるエントリー(プロパティ)数が表示されています。例えば、エントリー数を20で取得した場合、バイナリーエディタでエントリーカウントの次に表示されるIFDエントリー情報(12Byte)が20種類表示されます。エントリー数はそのままプロパティ数と読み替えても良いと思います。エントリー数の範囲は、1-65535(n番)となっています。いくつか試しにエントリー数を見てみたところ、20個以内に収まる程度のエントリー数が大半でした。

IFDエントリー

TIFFに記録されているエントリー(プロパティ)情報を表示します。

内容バイト数取得値
タグコード2254以上の必須タグと選択タグのコード
データ型21~12のデータ型コード
カウントフィールド4データフィールドに含まれる値の数
データフィールドまたはデータポインタ4データの値または、データオフセット値
IFDポインタ

次のIFDへのバイト単位のオフセット値が表示されます。マルチTIFFで複数ページが1ファイルに存在する場合、1ページ目のIFD情報を取得後、このIFDポインタの情報で2ページ目のIFD情報へ変遷することができます。このポインタがあるお陰でページ数をカウントすることが可能になります。
次のIFDがない場合は0が表示されます。つまり、ページ数はこれ以上カウントできないため、ページ数のカウントを終了することができます。

バイナリデータ例(Motorola型)

Motorola型のバイナリデータ例を紹介します。Intel型は、Byteの並びが逆になりますのでご注意ください。

ファイルヘッダ

バイトオーダーバージョン番号IFDポインタ
4D4D002A00000008
MM4208

IFD

エントリーカウント
カウント数
000F
15
IFDエントリー
タグ番号データ型カウントフィールドデータフィールド
IFDエントリー100FE00040000000100000000
NewSubfileType254040100
IFDエントリー2010000040000000100000280
ImageWidth2560401640
IFDエントリー30101000400000001000001E0
ImageLength2570401480
IFDエントリー4010200040000000100080000
BitsPerSample2580401524288
IFDエントリー5010000030000000100050000
Compression2590301327680
IFDエントリー6010600030000000100030000
PhotometricInterpretation2620301196608
IFDエントリー70111000400000014000000D2
StripOffsets2730420210
IFDエントリー8011500030000000100010000
SamplesPerPixel277030165536
IFDエントリー9011600040000000100000019
RowsPerStrip278040125
IFDエントリー10011700040000001400000122
StripByteCounts2790420290
IFDエントリー11011A000400000001000000C2
Xresolusion2820401194
IFDエントリー12011B000500000001000000CA
Yresolusion2830501202
IFDエントリー13011C00050000000100010000
PlanarConfiguration284050165536
IFDエントリー14012800050000000100020000
ResolutionUnit2960501131072
IFDエントリー15014000050000030000000172
ColorMap32005768370
IFDポインタ
オフセット値
00000000
00

コード解説

 TIFFの仕様を踏まえて、VBA構文のコード解説をしていきます。

宣言文

 宣言セクションで変数をいくつか設定します。特にユーザ定義型変数の設定は今回のコード実行の味噌になるキーワードになります。

Private fn

Type FileHeader
    ByteOrder As String * 2
    VersionNum(1) As Byte
End Type
 
Type Entry_IFD
    TagType(0 To 1) As Byte
    DataType(0 To 1) As Byte
    DataCount(0 To 3) As Byte
    Data(0 To 3) As Byte
End Type
fn

freefileのファイルナンバーとして、各プロシージャでそのまま使うため宣言(引数で渡すのが面倒だった。。)

FileHeader

TIFFのファイルヘッダ情報(計4Byte)をユーザ定義型で宣言
ByteOrder As String * 2 ⇐ * 2 で2文字(2Byte)を宣言
VersionNum(1) As Byte ⇐ 配列設定で2Byteを宣言

ファイルヘッダ内容宣言文Byte数
バイトオーダー"MM" or "II"が設定ByteOrder As String * 22
バージョン番号TIFFファイルは、固定値42VersionNum(1) As Byte2
IFDポインタ(別箇所で宣言)IFDへのオフセット値4
Entry_IFD

IFDエントリで使用されているByte数(計12Byte)をユーザ定義型で宣言

IFDエントリ内訳内容宣言文Byte数
タグTIFFファイルのプロパティ情報を示すタグコードTagType(0 To 1) As Byte2
データの型1~12のデータ型コードDataType(0 To 1) As Byte2
カウントフィールドデータフィールドに含まれる値の数DataCount(0 To 3) As Byte4
データフィールドまたはデータポインタ各種データまたは
バイト単位のオフセット値
Data(0 To 3) As Byte4

Get_TiffPage

マクロ実行用のプロシージャです。シートA列に入力されたフルパスをGetPageNumber関数に引き渡します。

Sub Get_TiffPage()
    Dim TargetRow As Long, maxrow As Long
    maxrow = Sheet1.Cells(Rows.Count, 1).End(xlUp).Row
    For TargetRow = 2 To maxrow
        Sheet1.Cells(TargetRow, 2) = GetPageNumber(Sheet1.Cells(TargetRow, 1))
    Next TargetRow
End Sub

GetPageNumber

 対象のTIFFファイルがMotorola型(リトルエンディアン)かIntel型(ビックエンディアン)か判別し、型に応じて異なる計算実行用関数に引き渡します。

Function GetPageNumber(TiffFileName As String)
    Dim header As FileHeader
    fn = FreeFile
    Open TiffFileName For Binary As fn
    Get fn, , header
    
    Select Case header.ByteOrder
    Case "II"
        Close fn
        GetPageNumber = GetPageNumber_Intel(TiffFileName)
    Case "MM"
        Close fn
        GetPageNumber = GetPageNumber_Motorola(TiffFileName)
    Case Else
        Close fn
        Err.Raise 9999, , "Exception ByteOrder"
    End Select
End Function
2行目

FileHeader型を宣言。4ByteをFileHeader型で取得できる様になります。

3行目

ファイルナンバー(fn)をFreeFile関数で取得。重複で開くことはしないので、1が入力される。

4行目

バイナリモードでTIFFファイルを開く

5行目

header変数にてTIFFファイル先頭の4Byte(ファイルヘッダ)を取得。
最初の2Byteは、バイトオーダ("MM" or "II")を取得。
次の2Byteは、TIFFバージョン番号(42)を取得。

7~17行目

取得したバイトオーダによって処理を条件分岐します。何れの処理でも一度ファイルを閉じます。バイトオーダがMotorola型かIntel型で計算実行用の関数の種類を分けます。(GetPageNumber_Intel or GetPageNumber_Motorola)
TIFFファイル以外のファイルが該当する場合はエラーを出し、一度処理をストップします。

GetPageNumber_Intel

 GetPageNumber関数の条件分岐でバイトオーダが"II"(Intel型)だった場合、こちらの関数でページ数を計算実行します。ビックエンディアンの方が値取得をLong型でそのまま取得ができるので、計算は楽です。

Function GetPageNumber_Intel(TiffFileName As String)
    Dim header As FileHeader
    Dim EntryCount As Integer, Tag() As Entry_IFD, NextIFD As Long
    Dim pagecount As Long
    Dim j As Long
    
    fn = FreeFile
    Open TiffFileName For Binary As fn
    Get fn, , header
    
    If header.VersionNum(0) <> 42 Then
        Close fn
        Err.Raise 9999, , "This is not TiffFile"
        Exit Function
    End If
    
    pagecount = 0
    Do Until EOF(fn)
        Get fn, , NextIFD
        If NextIFD = 0 Then Exit Do
        Seek #fn, NextIFD + 1
        pagecount = pagecount + 1
        Get fn, , EntryCount
        If EntryCount > 0 Then
            ReDim Tag(1 To EntryCount)
            Get fn, , Tag
        End If
    Loop
    Close fn
    GetPageNumber_Intel = pagecount
End Function
2~4行目

この構文で重要な変数を宣言。詳細は以下テーブル参照

項目宣言文バイト数宣言内容
ファイルヘッダheader As FileHeader4FileHeader型を宣言。4Byteを割当。
エントリーカウントEntryCount As Integer2IFDエントリーカウント用の変数宣言。Integer型のByte数である2Byteを割当。
IFDエントリーTag() As Entry_IFD12Entry_IFD型の宣言。ユーザ定義しているIFDエントリ変数を宣言。計12Byteを割当。
IFDポインタNextIFD As Long4最初の取得:ファイルヘッダのIFDポインタ
2回目以降:IFD情報内の最後にあるIFDポインタ
Long型のByte数である4Byteを割当。
ページ数pagecount As Longページカウント用の変数。バイナリデータ参照用ではないため、Byte数は特に意識する必要なし。
7~9行目

fn変数にfreefile関数でファイルナンバーを入力(=1)
TIFFファイルをバイナリモードで開く。
ファイルヘッダ情報(先頭4Byte分)を取得。

11~15行目

TIFFファイルのバージョン番号(=42)を確認。TIFFファイルを示す固有値42以外の場合は、TIFFファイルではないので、エラー発生させ処理終了。

17~29行目

ページカウントの実行。IFDポインタを取得する度にページ数を1カウントしている。IFDポインタが0を取得すれば、これ以上ページ数がないため、処理終了。

(19行目)

・ループ処理初回
 既に9行目の処理で先頭4Byteは取得しているため、続いてIFDポインタ4Byte分を取得。バイナリデータを直前で取得した所からデータ取得ができるため、Seek関数を利用する必要はない。
・ループ処理2回目以降
 IFDエントリーを全て取得後、最後に残っているIFDポインタ4Byte分を取得。ここで、0を取得した時にページカウントが終了する。(20行目処理)

(21行目)

Seek関数でIFDポインタで取得した「オフセット値+1」分のByte数をバイナリデータ上で移動する。この位置からIFD情報が取得できる。

(23行目)

Seek関数で移動した先の先頭にあるエントリーカウント2Byte分を取得。

(25行目)

取得したエントリーカウントでTag変数(動的配列)を再度宣言。

(26行目)

IFDエントリーを「12Byte × エントリーカウント」分取得。

 言葉だけでは説明が分かりにくい方は、以下のアコーディオンブロックでTIFF仕様まとめを載せておきますので、必要に応じでクリックで開いてByte数を比較しながら確認ください。

TIFF仕様まとめ
ファイルヘッダ
スクロールできます
ファイルヘッダ
IFD
画像関連データ
カラーマップ
イメージデータ

内容バイト数取得値
バイトオーダー2"MM"(4D4DH)または"II"(4949H)
バージョン番号2固定値42
IFDポインタ4先頭IFDへのバイト単位のオフセット値
IFD
スクロールできます
ファイルヘッダ
IFD
画像関連データ
カラーマップ
イメージデータ

内容バイト数取得値
エントリーカウント21-65535(取得値 = n
IFDエントリー(1番)121番目のIFDエントリ(プロパティ情報)
IFDエントリー(2番)122番目のIFDエントリ(プロパティ情報)
~中略~
IFDエントリー(n-1番)12n-1番目のIFDエントリ(プロパティ情報)
IFDエントリー(n番12n番目のIFDエントリ(プロパティ情報)
IFDポインタ4次のIFDへのバイト単位のオフセット値
IFDエントリー
内容バイト数取得値
タグコード2254以上の必須タグと選択タグのコード
データ型21~12のデータ型コード
カウントフィールド4データフィールドに含まれる値の数
データフィールドまたはデータポインタ4データの値または、データオフセット値

GetPageNumber_Motorola

 GetPageNumber関数の条件分岐でバイトオーダが"MM"(Motorola型)だった場合、こちらの関数でページ数を計算実行します。リトルエンディアンの場合、値取得を一度Byte毎で取得後、配列を並び直しする必要があります。

Function GetPageNumber_Motorola(TiffFileName As String)
    Dim EntryCount_Byte(1) As Byte, EntryCount_10 As Long, EntryCount_16 As String, Tag() As Entry_IFD
    Dim NextIFD_10 As Long, NextIFD_16 As String
    Dim IFDByte(3) As Byte
    Dim header As FileHeader
    Dim j As Long
    Dim pagecount As Long
    
    fn = FreeFile
    Open TiffFileName For Binary As fn
    Get fn, , header
    
    If header.VersionNum(1) <> 42 Then
        Close fn
        Err.Raise 9999, , "This is not TiffFile"
        Exit Function
    End If
        
    pagecount = 0
    Do Until EOF(fn)
        Get fn, , IFDByte
        NextIFD_16 = Hex(Format(IFDByte(0), "00")) & Hex(Format(IFDByte(1), "00")) & _
                     Hex(Format(IFDByte(2), "00")) & Hex(Format(IFDByte(3), "00"))
        NextIFD_10 = Abs("&H" & NextIFD_16)
        
        If NextIFD_10 = 0 Then Exit Do
        Seek #fn, NextIFD_10 + 1
        pagecount = pagecount + 1
        Get fn, , EntryCount_Byte
        EntryCount_16 = Hex(Format(EntryCount_Byte(0), "00")) & Hex(Format(EntryCount_Byte(1), "00"))
        EntryCount_10 = Abs("&H" & EntryCount_16)
        If EntryCount_10 > 0 Then
            ReDim Tag(1 To EntryCount_10)
            Get fn, , Tag
        End If
    Loop
    Close fn
    GetPageNumber_Motorola = pagecount
End Function
2~7行目

この構文で重要な変数を宣言。詳細は以下テーブル参照

項目宣言文バイト数宣言内容
ファイルヘッダheader As FileHeader4FileHeader型を宣言。4Byteを割当。
エントリーカウント(Byte)EntryCount_Byte(1) As Byte2IFDエントリーカウント用の変数宣言。1Byteずつ配列に代入できる様にして2Byteを割当。
EntryCount_Byte⇒EntryCount_16(16進法)⇒EntryCount_10(10進法)の順に値を変換
エントリーカウント(10進法)EntryCount_10 As LongEntryCount_16で表示した16進法の取得値を10進法に表示させるための変数。バイナリデータからの値取得は、EntryCount_Byteで取得するため、バイト数は意識する必要なし。
エントリーカウント(16進法)EntryCount_16 As StringEntryCount_Byteで取得したByteデータをつなぎ合わせ、16進法表示させるための変数。バイナリデータからの値取得は、EntryCount_Byteで取得するため、バイト数は意識する必要なし。
IFDエントリーTag() As Entry_IFD12Entry_IFD型の宣言。ユーザ定義しているIFDエントリ変数を宣言。計12Byteを割当。
IFDポインタ(Byte)IFDByte(3) As Byte4最初の取得:ファイルヘッダのIFDポインタ
2回目以降:IFD情報内の最後にあるIFDポインタ
配列で4要素分を確保して、4Byteを割当。
IFDポインタ(16進法)NextIFD_16 As StringIFDByteで取得したByteデータをつなぎ合わせ、16進法表示させるための変数。バイナリデータからの値取得は、IFDByteで取得するため、バイト数は意識する必要なし。
IFDポインタ(10進法)NextIFD_10 As LongNextIFD_16で表示した16進法の取得値を10進法に表示させるための変数。バイナリデータからの値取得は、IFDByteで取得するため、バイト数は意識する必要なし。
ページ数pagecount As Longページカウント用の変数。バイナリデータ参照用ではないため、Byte数は特に意識する必要なし。
9~11行目

fn変数にfreefile関数でファイルナンバーを入力(=1)
TIFFファイルをバイナリモードで開く。
ファイルヘッダ情報(先頭4Byte分)を取得。

13~17行目

TIFFファイルのバージョン番号(=42)を確認。TIFFファイルを示す固有値42以外の場合は、TIFFファイルではないので、エラー発生させ処理終了。

19~36行目

ページカウントの実行。IFDポインタを取得する度にページ数を1カウントしている。IFDポインタが0を取得すれば、これ以上ページ数がないため、処理終了。

(21行目)

・ループ処理初回
 既に9行目の処理で先頭4Byteは取得しているため、続いてIFDポインタ4Byte分を取得。バイナリデータを直前で取得した所からデータ取得ができるため、Seek関数を利用する必要はない。
・ループ処理2回目以降
 IFDエントリーを全て取得後、最後に残っているIFDポインタ4Byte分を取得。ここで、0を取得した時にページカウントが終了する。(20行目処理)

(22~24行目)

IFDをByte単位で取得⇒16進法の値に変換⇒10進法の値に変換する。
Seek関数にて10進法表示のIFDポインタで取得した「オフセット値+1」分のByte数をバイナリデータ上で移動する。この位置からIFD情報が取得できる。

(29行目)

Seek関数で移動した先の先頭にあるエントリーカウント2Byte分を取得。

(33行目)

取得したエントリーカウントでTag変数(動的配列)を再度宣言。

(34行目)

IFDエントリーを「12Byte × エントリーカウント」分取得。

 言葉だけでは説明が分かりにくい方は、以下のアコーディオンブロックでTIFF仕様まとめを載せておきますので、必要に応じでクリックで開いてByte数を比較しながら確認ください。

TIFF仕様まとめ
ファイルヘッダ
スクロールできます
ファイルヘッダ
IFD
画像関連データ
カラーマップ
イメージデータ

内容バイト数取得値
バイトオーダー2"MM"(4D4DH)または"II"(4949H)
バージョン番号2固定値42
IFDポインタ4先頭IFDへのバイト単位のオフセット値
IFD
スクロールできます
ファイルヘッダ
IFD
画像関連データ
カラーマップ
イメージデータ

内容バイト数取得値
エントリーカウント21-65535(取得値 = n
IFDエントリー(1番)121番目のIFDエントリ(プロパティ情報)
IFDエントリー(2番)122番目のIFDエントリ(プロパティ情報)
~中略~
IFDエントリー(n-1番)12n-1番目のIFDエントリ(プロパティ情報)
IFDエントリー(n番12n番目のIFDエントリ(プロパティ情報)
IFDポインタ4次のIFDへのバイト単位のオフセット値
IFDエントリー
内容バイト数取得値
タグコード2254以上の必須タグと選択タグのコード
データ型21~12のデータ型コード
カウントフィールド4データフィールドに含まれる値の数
データフィールドまたはデータポインタ4データの値または、データオフセット値
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

VBAを中心とした自動化、効率化の手法を紹介しています。現在は、SeleniumBasicのexamplesを紹介しています。その内、SeleniumBasic以外の手法も掲載したいと思っております。

目次