#やりたかったこと
WEB上の画像をローカルに保存することなく、OpenCV用の形式(ndarray)に変換する関数が欲しかったので作った。
#開発環境
- Windows 10 Home 21H1 64bit
- Python 3.9.4
#コード
import cv2
import requests
import tempfile
import os
def imread_web(url):
# 画像をリクエストする
res = requests.get(url)
img = None
# Tempfileを作成して即読み込む
fp = tempfile.NamedTemporaryFile(dir='./', delete=False)
fp.write(res.content)
fp.close()
img = cv2.imread(fp.name)
os.remove(fp.name)
return img
# 使用イメージ
img = imread_web('https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png')
cv2.imshow('Googleロゴ', img)
#メモ
tempfile.NamedTemporaryFile()
は閉じたら自動で削除される一時的な空FileObjectを生成してくれる。
これを利用しカレントフォルダに一時ファイルを生成、WEBから取得した画像を書き込んで即座に読み込んだあと削除している(結局一瞬ローカルにファイルは生成される)。
本来with句を使ってファイルを閉じる処理と削除する処理は省略出来るのだが、Windows環境のみ書き込んだあと手動で閉じない限り読み込めない(=cv2.imread()
の返り値がNoneになる)仕様が存在するために冗長な記述となっている。
tempfile --- 一時ファイルやディレクトリの作成 — Python 3.9.4 ドキュメント
tempfile.NamedTemporaryFile(mode='w+b', buffering=None, encoding=None, newline=None, suffix=None, prefix=None, dir=None, delete=True)
この関数は、ファイルシステム上でファイルが可視の名前を持つことが保証される (Unix においてはディレクトリエントリが unlink されない) 点以外は TemporaryFile() と正確に同じことを行います。 その名前は、返されたファイル様オブジェクトの name 属性から取得することができます。 名前付き一時ファイルがまだ開かれている間にこの名前を使って再度ファイルを開くことができるかどうかは、プラットフォームによって異なります (Unix 上では可能ですが、 Windows NT 以降ではできません)。
#参考
Webから引っ張ってきた画像をOpenCVで処理して表示する話 - EnsekiTT Blog
Windows10でのPythonの一時ファイルtempfile.NamedTemporaryFileへのアクセス ~ Windowsではいったん閉じないと駄目 - 日常メモ