TensorboardのProjectorで、各要素に対応する画像をはっつけるためのsprite画像(metadata)を作ろうと思ったが、
それをurlから作る時に参考になるいいサイトがなく苦労したので、ここで紹介する。
使用言語はPython3である。
#必要なモジュールをimport
import urllib.error
import urllib.request
import time
import os
import pickle
#urlをdownloadする関数を定義
def download_image(url, dst_path):
try:
data=urllib.request.urlopen(url).read()
with open(dst_path, mode='wb') as f:
f.write(data)
except urllib.error.URLError as e:
print(e)
#このディレクトリはあらかじめ作っておく。
download_dir='images'
#urlデータを持ってくる
with open('urls', 'rb') as f:
urls=pickle.load(f)
list=[]
for (i, url) in enumerate(urls):
#ファイル名はurlの配列順の番号にする(ここは任意)
dst_path=os.path.join(download_dir, str(i))
#urlをダウンロード
download_image(url, dst_path)
#ダウンロードしたurlの順番を覚えておく。
list.append(i)
#画像をarrayに変換
image_array=xp.array([xp.array(Image.open('images/'+str(i))) for i in list])
image_array_c=copy.deepcopy(image_array)
#画像の修正
#下は(200,200)のサイズにしたいときの例
import cv2
for i in range(image_array_c.shape[0]):
image_array_c[i]=cv2.resize(image_array_c[i], (200,200))
#修正した画像を保存
#urlの配列順をsprite画像まで失わないためにファイル名のlistをurlの配列順に作成。ここではその順番をファイル名に使っている。
list=[]
for i in range(image_array_c.shape[0]):
im=Image.fromarray((image_array_c[i]))
list.append(str(i)+'.jpg')
im.save('images/'+str(i)+'.jpg')
#sprite画像生成
#ちなみにlistを特定の配列にすれば好きな順番でsprite画像を作ることができる
from PIL import Image
import os, math, time
max_frames=int(xp.ceil(xp.sqrt(image_array_c.shape[0])))
frames = []
tile_width = 0
tile_height = 0
spritesheet_width = 200
spritesheet_height = 200
files = list
for current_file in files :
try:
with Image.open("images/" + current_file) as im :
frames.append(im.getdata())
except:
print(current_file + " is not a valid image")
tile_width = frames[0].size[0]
tile_height = frames[0].size[1]
if len(frames) > max_frames :
spritesheet_width = tile_width * max_frames
spritesheet_height = tile_height * max_frames
else:
spritesheet_width = tile_width*len(frames)
spritesheet_height = tile_height
print(spritesheet_height)
print(spritesheet_width)
#真っ白なシート作成
spritesheet = Image.new("RGB",(int(spritesheet_width), int(spritesheet_height)))
#順番に画像をはめ込んでいく
for current_frame in frames :
top = tile_height * math.floor((frames.index(current_frame))/max_frames)
left = tile_width * (frames.index(current_frame) % max_frames)
bottom = top + tile_height
right = left + tile_width
box = (left,top,right,bottom)
box = [int(i) for i in box]
cut_frame = current_frame.crop((0,0,tile_width,tile_height))
spritesheet.paste(cut_frame, box)
spritesheet.save("spritesheet" + time.strftime("%Y-%m-%dT%H-%M-%S") + ".png", "PNG")