web-dev-qa-db-ja.com

Python:PNGからメタデータを抽出する

Rを使用して必要な情報を抽出できますが、プロジェクト全体で一貫性を保つために、Python(できればPython3)でそれを実行できるようにしたいと思います。 「設定」と呼ばれる単一のタグ。このタグにはXMLが含まれているため、解析する必要があります。

Rでのメタデータの取得は非常に簡単です。

_library(exifr)
library(XML)

path = file.path('path', 'to', 'file')

x = read_exif(file.path(path,'image.png'))
x$Settings
_

Pythonでできるので、心が揺さぶられます。そうするためには、PythonとPNGよりもはるかに多くの知識が必要ですPythonを使用してPNGメタデータを抽出するにはどうすればよいですか?


これが私が試したもののリストです:

PyPngPyPNGは有望なようです。各チャンクの長さを調べると、「設定」タグがzTXtチャンクに存在しているようです。

_import png

filename = "C:\\path\\to\\image.png"

im = png.Reader(filename)

for c in im.chunks():
    print(c[0], len(c[1]))

>>>
IHDR 13
tIME 7
pHYs 9
IDAT 47775
zTXt 714
IEND 0
_

上記は this post からの引用です。ただし、zTXtデータを抽出する方法はまだ不明です。

hachoir3

_hachoir3_ パッケージを使用して、私は以下を試しました:

_from hachoir.parser import createParser
from hachoir.metadata import extractMetadata

filename = "C:\\path\\to\\file\\image.png"
parser = createParser(filename)
metadata = extractMetadata(parser)

for line in metadata.exportPlaintext():
    print(line)
_

これは私に次を与えます:

_Metadata:
- Image width: 1024 pixels
- Image height: 46 pixels
- Bits/pixel: 16
- Pixel format: RGB
- Compression rate: 2.0x
- Image DPI width: 1 DPI
- Image DPI height: 1 DPI
- Creation date: 2016-07-13 19:09:28
- Compression: deflate
- MIME type: image/png
- Endianness: Big endian
_

必要なフィールド、Rコードで参照されている「設定」に到達できないようです。 _metadata.get_のような他の方法ではうまくいきませんでした。私の知る限り、これらはPNGメタデータを解析するための2つのオプションのようです。ドキュメントを読んで、

いくつかの良い(しかし完璧ではない;-))パーサー:

MatroskaビデオMicrosoft RIFF(AVIビデオ、WAVオーディオ、CDAファイル)PNG画像TARおよびZipアーカイブ

多分それは私が必要とする機能を持っていないのですか?

これで与えられたアドバイスに従う post

_from PIL import Image
filename = "C:\\path\\to\\file\\image.png"
im = Image.open(filename)
_

これは画像を読み込みますが、_im.info_は{'aspect': (1, 1)}のみを返します。ドキュメントを読むと、どのメソッドもメタデータを取得するようには見えません。投稿で提供されている PNGの説明 を読みました。正直なところ、私はその情報をどのように利用するか、枕が私をどのように助けてくれるかわかりません。

私が必要としていることを実行できることを示唆する投稿がいくつかありますが、それらは機能しません。たとえば、 this post は、ExifTagsライブラリの使用を提案します。

_from PIL import Image, ExifTags
filename = "C:\\path\\to\\file\\image.png"
im = Image.open(filename)
exif = { ExifTags.TAGS[k]: v for k, v in im._getexif().items() if k in ExifTags.TAGS}
_

問題は、_AttributeError: 'PngImageFile' object has no attribute '_getexif'_です。 documentation によると、_._getexif_機能は実験的なものであり、JPGにのみ適用されます。

全体を読む 枕のドキュメント 、それは本当にJPGとTIFFについてのみ話します。 PNGファイルの処理は、パッケージの一部ではないようです。 hachoirのように、それができないのでしょうか?

[〜#〜] pil [〜#〜]

Pillowの分岐元となった別のパッケージPILがあるようです。 2009年に見捨てられたようです。

6
Lorem Ipsum

これは、洗練されていなくて不器用ですが、実用的なソリューションです。

ここから改作: https://motherboard.vice.com/en_us/article/aekn58/hack-this-extra-image-metadata-using-python

python=内からコマンドラインexiftoolsアプリを呼び出して、結果を解析できます。

以下は、Ubuntu 16.04でPython 3.6.3で動作するコードです。

import subprocess

result = subprocess.run(['exiftool', '-h', '/home/jason/Pictures/kitty_mask.png'], stdout=subprocess.PIPE)
print (type(result))
print ("\n\n",result.stdout)
normal_string = result.stdout.decode("utf-8")
print("\n\n", normal_string)

テストイメージに対して次の結果が生成されます。

> <class 'subprocess.CompletedProcess'>
> 
> 
>  b'<!-- /home/jason/Pictures/kitty_mask.png
> -->\n<table>\n<tr><td>ExifTool Version Number</td><td>10.80</td></tr>\n<tr><td>File
> Name</td><td>kitty_mask.png</td></tr>\n<tr><td>Directory</td><td>/home/jason/Pictures</td></tr>\n<tr><td>File
> Size</td><td>25 kB</td></tr>\n<tr><td>File Modification
> Date/Time</td><td>2018:07:02 09:35:00+01:00</td></tr>\n<tr><td>File
> Access Date/Time</td><td>2018:07:09
> 16:23:24+01:00</td></tr>\n<tr><td>File Inode Change
> Date/Time</td><td>2018:07:02 09:35:00+01:00</td></tr>\n<tr><td>File
> Permissions</td><td>rw-r--r--</td></tr>\n<tr><td>File
> Type</td><td>PNG</td></tr>\n<tr><td>File Type
> Extension</td><td>png</td></tr>\n<tr><td>MIME
> Type</td><td>image/png</td></tr>\n<tr><td>Image
> Width</td><td>2448</td></tr>\n<tr><td>Image
> Height</td><td>3264</td></tr>\n<tr><td>Bit
> Depth</td><td>8</td></tr>\n<tr><td>Color
> Type</td><td>RGB</td></tr>\n<tr><td>Compression</td><td>Deflate/Inflate</td></tr>\n<tr><td>Filter</td><td>Adaptive</td></tr>\n<tr><td>Interlace</td><td>Noninterlaced</td></tr>\n<tr><td>Image
> Size</td><td>2448x3264</td></tr>\n<tr><td>Megapixels</td><td>8.0</td></tr>\n</table>\n'
> 
> 
>  <!-- /home/jason/Pictures/kitty_mask.png --> <table> <tr><td>ExifTool
> Version Number</td><td>10.80</td></tr> <tr><td>File
> Name</td><td>kitty_mask.png</td></tr>
> <tr><td>Directory</td><td>/home/jason/Pictures</td></tr> <tr><td>File
> Size</td><td>25 kB</td></tr> <tr><td>File Modification
> Date/Time</td><td>2018:07:02 09:35:00+01:00</td></tr> <tr><td>File
> Access Date/Time</td><td>2018:07:09 16:23:24+01:00</td></tr>
> <tr><td>File Inode Change Date/Time</td><td>2018:07:02
> 09:35:00+01:00</td></tr> <tr><td>File
> Permissions</td><td>rw-r--r--</td></tr> <tr><td>File
> Type</td><td>PNG</td></tr> <tr><td>File Type
> Extension</td><td>png</td></tr> <tr><td>MIME
> Type</td><td>image/png</td></tr> <tr><td>Image
> Width</td><td>2448</td></tr> <tr><td>Image
> Height</td><td>3264</td></tr> <tr><td>Bit Depth</td><td>8</td></tr>
> <tr><td>Color Type</td><td>RGB</td></tr>
> <tr><td>Compression</td><td>Deflate/Inflate</td></tr>
> <tr><td>Filter</td><td>Adaptive</td></tr>
> <tr><td>Interlace</td><td>Noninterlaced</td></tr> <tr><td>Image
> Size</td><td>2448x3264</td></tr>
> <tr><td>Megapixels</td><td>8.0</td></tr> </table>
1
Spoonless