FC2ブログ

myara CG blog

CG Design Blog. Thoughts, experiments and experiences.

Python で TGAの情報(header)を読み込む方法

今回の案件でテクスチャはTGA 24bit RLE圧縮という指定がありまして、それをチェックが出来るツールを書こうとしていました。

まずは既に書いてある物をネットで探して、使えそうなモジュールはこれでした:

pyTGA
https://github.com/MircoT/pyTGA

TGAを読み込んだり、書き出したり出来るモジュールです。
そして、全てデフォルトのPythonで動くモジュールです!

全てPythonだから好きに編集が出来るけど、処理が重いのかなという心配もあります。
とりあえず試してみます。

使い方を読んで、以下のコマンドで欲しかった情報を取得ができました。
image = pyTGA.Image()
image.load( texture_filePath )
print image._header.pixel_depht


しかし、重い。
1枚数十秒だったので、4K テクスチャを数十枚を確認するには向いていませんね・・・。

どうやら load でテクスチャのデータを全て読み込んでいるようで、かなり時間が掛かってしまいます。

でも、欲しいのはヘッダーの部分だけ。
テクスチャのデータとかはいらないので、色々弄ってみて以下のコードに変わりました。
あっちこちの調整も必要があったけど、主にヘッダーの読み込みに役に立ちそうな部分だけを残して、あとは削除する作業でなんとかなりました:

from struct import unpack
def dec_byte(data, size=1, littleEndian=True):
"""Decode some data from bytes.

Args:
data (bytes): data to decode
size (int): number of bites of the data
littleEndian (bool): little endian or big endian

Returns:
int: the decoded data
"""
order = str('<' if littleEndian else '>')
format_ = str((None, 'B', 'H', None, 'I')[size])

return unpack(order + format_, data)[0]

class TGAHeader(object):
"""
#- Field(1)
# ID LENGTH (1 byte):
# Number of bites of field 6, max 255.
# Is 0 if no image id is present.
#
#- Field(2)
# COLOR MAP TYPE (1 byte):
# - 0 : no color map included with the image
# - 1 : color map included with the image
#
#- Field(3)
# IMAGE TYPE (1 byte):
# - 0 : no data included
# - 1 : uncompressed color map image
# - 2 : uncompressed true color image
# - 3 : uncompressed black and white image
# - 9 : run-length encoded color map image
# - 10 : run-length encoded true color image
# - 11 : run-length encoded black and white image
#
#- Field(4)
# COLOR MAP SPECIFICATION (5 bytes):
# - first_entry_index (2 bytes) : index of first color map entry
# - color_map_length (2 bytes)
# - color_map_entry_size (1 byte)
#
#- Field(5)
# IMAGE SPECIFICATION (10 bytes):
# - x_origin (2 bytes)
# - y_origin (2 bytes)
# - image_width (2 bytes)
# - image_height (2 bytes)
# - pixel_depth (1 byte):
# - 8 bit : grayscale
# - 16 bit : RGB (5-5-5-1) bit per color
# Last one is alpha (visible or not)
# - 24 bit : RGB (8-8-8) bit per color
# - 32 bit : RGBA (8-8-8-8) bit per color
# - image_descriptor (1 byte):
# - bit 3-0 : number of attribute bit per pixel
# - bit 5-4 : order in which pixel data is transferred
# from the file to the screen
"""

def __init__(self, file_name):
with open(file_name, "rb") as image_file:

# Read Header
image_file.seek(0)
# ID LENGTH
self.id_length = dec_byte(image_file.read(1))
# COLOR MAP TYPE
self.color_map_type = dec_byte(image_file.read(1))
# IMAGE TYPE
self.image_type = dec_byte(image_file.read(1))
# COLOR MAP SPECIFICATION
self.first_entry_index = dec_byte(image_file.read(2), 2)
self.color_map_length = dec_byte(image_file.read(2), 2)
self.color_map_entry_size = dec_byte(image_file.read(1))
# IMAGE SPECIFICATION
self.x_origin = dec_byte(image_file.read(2), 2)
self.y_origin = dec_byte(image_file.read(2), 2)
self.image_width = dec_byte(image_file.read(2), 2)
self.image_height = dec_byte(image_file.read(2), 2)
self.pixel_depth = dec_byte(image_file.read(1))
self.image_descriptor = dec_byte(image_file.read(1))


これで欲しかった情報を一瞬で読み込むことが出来ました。
テクスチャの作り方にミスがあったかどうかはすぐに分かる。

tga = TGAHeader( texture_filePath )
print tga.image_type #3以下の場合は圧縮なし
print tga.image_height #高さ
print tga.image_width #横幅
print tga.pixel_depth #24bit か 32bit


そして何もインストールする必要がない!
チェックツール1つだけで済むというのも嬉しいですね。
スポンサーサイト



コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://myara.blog.fc2.com/tb.php/232-114450cf
この記事にトラックバックする(FC2ブログユーザー)