2016年9月14日水曜日

Python | 画像ファイルのExif情報を取り出す

普段デジカメで写真を撮ることが多いので、遠くない将来、撮りためた画像のExif情報から自分の傾向分析なんかをすることになる気がしています。

その時のために、画像ファイルのExif情報をPythonで書いたスクリプトを使って取得する方法を調べてみました。

ネットで検索すると、PIL(Python Image Library)というモジュールを使っている例が多いようなのですが、使い方がいまいちピンとこなかったので、別の方法として、ExifReadを使ってみることにしました。

ExifReadをDLする

ExifReadはこちらからDLできます。


モジュールを適切な場所に置く

解凍したモジュール一式を僕は"C:\Python27\Lib"の中に置きました。

スクリプトを書く

下を参考にしてみてください。
僕はこのサイトに教えてもらいました。

---
#!/usr/bin/env python
#-*- coding:utf-8 -*-

# 目的
# 画像ファイルからExif情報を取り出す

# 使い方
# 1.このスクリプトファイルを画像データのあるフォルダに置く
# 2.必要に応じて拡張子の指定部分を書き換える
# 3.実行する

from exif_py_develop import exifread
import glob

photos = glob.glob('*.JPG')

for f in photos:
    fname = open(f,'rb')
    tags = exifread.process_file(fname)

    for tag in tags:
        if tag not in ('JPEGThumbnail', 'TIFFThumbnail', 'Filename', 'EXIF MakerNote'):
            print "Key: %s, value %s" % (tag, tags[tag])
---

実行結果

スクリプトファイルは画像ファイルと同じフォルダに置いて実行します。
Exifにはたくさんの情報が入っていますが、例えば撮影日時であれば

Key: EXIF DateTimeDigitized, value 2016:08:24 16:44:22

2016年8月24日16時44分22秒に撮影された、と出力されます。

注意点やメモ

  • DL,解凍したモジュールを最初にインポートしています。
  • フォルダ内の全画像ファイル(拡張子JPG)を取得するのにglob関数を使いましたので、globモジュールもインポートしています。このとき、拡張子の指定は文字列で、大文字小文字も区別されます。

2016年7月7日木曜日

Python | for文での繰り返しを降順(逆順)で回す

for文では通常、指定範囲の中でインデックスの値の小さい方から大きい方へ向かって処理が進みますが、この方法で問題となるのが、スプレッドシートなどで条件に合う行を削除する場合です。

スプレッドシートで1行削除すると行の位置が1つ上にずれてしまい、本来削除したい行とはずれが生じてしまいます。

それを解決するのが、スプレッドシートの下のほうの行から上に向かって行の削除を実行していく方法になります。この方法のスクリプトはこちらを参考にしてください。PythonではなくGoogle Apps Scriptで書いたものですが、イメージは伝わるかと思います。

ここで問題となるのが、Google Apps Script(JavaScript)のfor文で"--i"、つまり i = i -1 で表現している、降順でのループの回し方を、Pythonの文法でどう表現するのか、ということです。

結論としては、

for i in range(1, 10):

のような書き方のforループを逆順で回す場合、

for i in reversed(range(1, 10)):

とします。

2016年6月10日金曜日

Python | 複数の画像ファイルをWordの表に貼りつける方法

Microsoft Wordの表の1セルに1コマずつ、複数(多数)の画像ファイルを貼りつける場面があり、手動ではかなりの時間がかかったため、効率化をのためのメモを残しておきます。

前提として、全画像ファイルが同一フォルダに置かれているものとします。また、画像ファイルの入っているフォルダには、画像ファイル以外にはPythonスクリプトファイルのみ置かれているものとします。

#---
#!/usr/bin/env python
# -*- coding: UTF-8 -*-

import os
import win32com.client as win32

def insertImagesIntoWord(arg):

    wordApp = win32.gencache.EnsureDispatch('Word.Application') #create a word application object
    wordApp.Visible = 1 # Wordを表示します
    doc = wordApp.Documents.Add() # create a new application

    doc.PageSetup.RightMargin = 15 # Wordのページの右側余白を指定します
    doc.PageSetup.LeftMargin = 15 # Wordのページの左側余白を指定します
    doc.PageSetup.Orientation = win32.constants.wdOrientLandscape
    # A4 サイズ: 595x842
    doc.PageSetup.PageWidth = 595
    doc.PageSetup.PageHeight = 842

    total_column = 3 # Wordの表の列数を指定します
    total_row = 17 # Wordの表の行数を指定します
    rng = doc.Range(0,0)
    rng.ParagraphFormat.Alignment = win32.constants.wdAlignParagraphCenter
    table = doc.Tables.Add(rng,total_row, total_column)
    table.Borders.Enable = False
    if total_column > 1:
   table.Columns.DistributeWidth()

    frame_max_width= 167 # the maximum width of a picture
    frame_max_height= 125 # the maximum height of a picture

    for index, filename in enumerate(filenames):

        if filename[len(filename)-4: len(filename)].upper() == 'JPEG':

# 各画像を貼りつける位置を計算します
cell_column= index % total_column + 1
cell_row = index / total_column + 1

# セルの形式を整えます
cell_range= table.Cell(cell_row, cell_column).Range
cell_range.ParagraphFormat.LineSpacingRule = win32.constants.wdLineSpaceSingle
cell_range.ParagraphFormat.SpaceBefore = 0
cell_range.ParagraphFormat.SpaceAfter = 3

# ここで画像を貼りつけています
current_pic = cell_range.InlineShapes.AddPicture(os.path.join(os.path.abspath("."), filename))
width, height = (frame_max_height*frame_max_width/frame_max_height, frame_max_height)

# 画像の大きさを表のセルサイズに合わせる場合はこちらも追加します
#current_pic.Height= height
#current_pic.Width= width

# 各セルに対応する画像のファイル名を入力します
table.Cell(cell_row, cell_column).Range.InsertAfter("\n"+filename)


if __name__ == "__main__":

    currentDir = os.getcwd() # スクリプト実行時のカレントディレクトリのパスを取得します
    filenames = os.listdir(currentDir)
    insertImagesIntoWord(filenames)
#---

こちらがベースです。
ファイルがJPG形式かどうかを確認する部分の書き方がくどく感じますが、これで当初の目的はほぼ果たせました。


2016/07/15追記
対象のフォルダ内に画像ファイルとスクリプトファイル以外のファイルが存在すると、画像の貼り付けが表の左上からではなく、ずれてしまいます。

SyntaxHighlighter