GAEで外部の画像(Amazonの商品など)を保存してロードする方法

=前置き=

 無念番付で使うために、Amazonから引っ張ってきた画像の「一番多い色」を求めてゲームに反映したい。のだが、CanvasAmazon画像を描画してピクセルごとに参照しようにも「Canvasに外部画像を描くとピクセルデータを取得できない(外部画像でdrawImageするとgetImageDataでエラーが出る)」という問題があり、計算することができない。Flash側に画像をそのまま渡してなんとかする方向もあるのだがそれはそれで別の問題があり、どうせならAmazonの画像をGAE側に保存しておくことで毎回Amazonに参照に行かなくて済むようにしたい。(ついでに色計算までGAE側で済ませたい)

 というわけで、外部の画像を引っ張ってきてGAE側で保存〜参照するところまでのメモ。(色計算はまた別エントリで)

=概要=

 基本的にはImages API の例  |  Python の App Engine スタンダード環境  |  Google Cloudに書かれていることそのまま。ここでは必要最低限の流れだけ書くので、疑問点が出た場合はこのURLを見ればわかるかも。


 概要は以下のとおり。

  • 保存パート(画像のURLからロードしてGAEに保存する)
    • Model側に「picture = db.BlobProperty(default=None)」という感じで画像を保存する部分を作成
    • ここに「hoge.picture = db.Blob(urlfetch.Fetch(img_url).content)」という感じでデータをセットして保存する
  • 参照パート(それを「〜/image?title=xxx」という感じでアクセスできるようにする)
    • スクリプトで「〜/image.*」からGetImageを呼ぶようにする
    • GetImageではDBの検索をし、「self.response.headers['Content-Type'] = 'image/jpg'」と「self.response.out.write(〜.img)」で画像を返す
    • app.yamlにてそのスクリプトを呼ぶようにする


 画像のURLからロードしてGAEに保存するところまでは以下のような感じ。とてもシンプル。(参照しやすいようにKeyNameで設定しているが、普通の登録でもOK)

imgURL = "......" #Amazonなどから持ってきたものを使う
result = urlfetch.Fetch(imgURL)
if result.status_code == 200:
	key_name = "hogehoge" #実際にはUniqueなものを自前で作って使っている
	info = UpdateModel.get_or_insert(key_name)
	info.picture = db.Blob(result.content)
	info.put()


 参照の方も設定自体は簡単だが、設定箇所が多い。
 まず、app.yamlにて「URL→呼ぶスクリプト」の対応付けを行う。

- url: /image.*
  script: munen_index.py

 次に、そのmunen_index.pyにて「URL→呼ぶ関数」の対応付けを行う。

application = webapp.WSGIApplication(
	[
		('/image.*', GetImage),
		('/index.*', MainPage)
	],
	debug=True
)

 そして対応付けた関数にて保存したデータを返すようにする。(ここではKeyNameを使って返しているが、GQLで検索しても良い)

class GetImage(webapp.RequestHandler):
	def get(self):
		key_name = self.request.get('key_name') #「〜/image?key_name=hogehoge」で渡ってきたhogehogeを取得

		info = UpdateModel.get_by_key_name(key_name)

		if (info and info.picture):
			self.response.headers['Content-Type'] = 'image/jpg' #Amazonの書影はjpgでありそのまま保存しているのでjpgとして返す
			self.response.out.write(info.picture)
		else:
			self.redirect('/noimage.png') #データがない場合はこちらを表示

 あとは「http://〜/image?key_name=hogehoge」という風にアクセスすれば保存した画像が返ってくる。(imgのsrcとかに設定すれば表示される)