Operation KiWi

一生使える言語はPythonだと信じてる

Python3.6.1で任意のフォルダにある画像のmd5値を取得、yamlに保存する方法

複雑なのかと思ったら、簡単だったのでメモ代わりに残します。同一画像の検出とか、保存したくない画像の判別に使えるかもしれない…

事前準備

pip install PyYAML

ソースコード

import os
import hashlib
import yaml


class GenMd5(object):
    """ グロ画像のmd5をとるためだけに存在しているクラスなのである """

    @staticmethod
    def check_dir_exists():
        if not os.path.exists('グロ'):
            print("グロ画像フォルダを作成しました。以後、グロ画像はこのフォルダにぶち込んでください。")
            os.mkdir('グロ')
            exit()

    @staticmethod
    def get_dir_list():
        """ ディレクトリ内のファイルを全て返す関数 """
        file_list = []
        for (root, dirs, files) in os.walk('グロ'):
            for f in files:
                file_list.append(os.path.join(root, f).replace("\\", "/").split('/')[-1])
        return file_list

    @staticmethod
    def run():
        GenMd5.check_dir_exists()
        os.chdir('グロ')
        md5 = set()

        for i in os.listdir('.'):
            with open(i, 'rb') as f:
                md5.add(hashlib.md5(f.read()).hexdigest())

        with open(os.path.join(os.path.dirname(__file__), 'grotesque_filter.yaml') , 'wt') as f:
            f.write(yaml.safe_dump(md5, default_flow_style=False))

        print("グロ画像フォルダ内のmd5値を保存しました...")
        os.chdir(os.path.dirname(__file__))

if __name__ == '__main__':
    GenMd5.run()

やっていること

  1. グロフォルダが存在しているかどうか。なければ作成して終了
  2. グロフォルダにカレントディレクトリを移動
  3. ディレクトリ内の全てのファイルパスを返す関数を実行する
  4. 画像を一つ一つ開いて、md5を取得、yamlに保存する
  5. 最後にカレントディレクトリを元に戻して終了(重要)

Tips

  • os.walk関数でディレクトリ以下のフォルダ、ファイルのパスを再帰的に取得することができます。
  • md5があるかどうかを判別できればいいので、set型もしくは辞書型で作成するといいかもしれないっす。
    • 単純にリストで保存してもいいけれども、リストは線形探索になるため、md5が増えると計算量が膨大になります。
    • ハッシュなら一発で検索が終わる(基本情報試験で習いましたね)
  • 画像を開くときはバイナリモードで開きましょう。
with open('File_name', mode="rb", encoding="utf-8") as f:
  • md5はhashlib.md5().hexdigest()で簡単に作り出せます。
md5 = set()
md5.add(hashlib.md5(f.read()).hexdigest())

でstr型のハッシュ値を取得出来ます。set型に追加するときはappend()じゃなくてadd()なので注意。

  • 移動したカレントディレクトリはちゃんと元に戻しておきましょう。自動的にカレントディレクトリを戻してくれないので、エラーのもとになります。自動で戻せよファック

終わり

今回はグロ画像用のフィルターを作成するためにmd5を取得、yamlで保存するようにしました。jsonでもいいのかな。なんとなくyamlの方が高機能なイメージがあります…w

退屈なことはPythonにやらせよう ―ノンプログラマーにもできる自動化処理プログラミング

退屈なことはPythonにやらせよう ―ノンプログラマーにもできる自動化処理プログラミング

入門 Python 3

入門 Python 3