メモリ上で画像を弄りたくなる時もたまにある。
そう、たまにあるんです。
大体は速くなるからね、やりたくなるよね。
なので簡単に使えるように作ってみた。
arrayimage.py
from PIL import Image, ImageTk
class ArrayImage:
def __init__(self, size=(10, 10)):
self.sizeW = int(size[0])
self.sizeH = int(size[1])
self.size = (self.sizeW, self.sizeH)
self.byteData = bytearray(self.sizeW * self.sizeH * 3)
def image(self):
return ImageTk.PhotoImage(Image.frombytes("RGB", self.size, bytes(self.byteData)))
def index(self, pos):
return (pos[1] * self.sizeW + pos[0]) * 3
def set(self, pos, rgb):
index = self.index(pos)
self.byteData[index:index+3] = rgb
def get(self, pos):
index = self.index(pos)
return tuple(self.byteData[index:index+3])
使うにはこう。
import tkinter as tk
import random
from arrayimage import *
class MyApp:
def __init__(self, cnf={}, **kw):
self.root = root = tk.Tk()
self.ai = ArrayImage(size=(128, 128))
self.canvas = c0 = tk.Canvas(root, width=self.ai.sizeW*3, height=self.ai.sizeH*3)
c0.pack()
def mainloop(self):
self.root.after(100, self.dispImage)
self.root.mainloop()
def dispImage(self, e=None):
for y in range(self.ai.sizeH):
for x in range(self.ai.sizeW):
self.ai.set((x, y),
(random.randint(0,255),
random.randint(0,255),
random.randint(0,255))
)
self.dispimg = self.ai.image()
self.dst = self.dispimg._PhotoImage__photo.zoom(3)
self.canvas.create_image(0, 0, anchor="nw", image=self.dst)
self.root.after(33, self.dispImage) # 1 / 30 * 1000
if __name__ == "__main__":
app = MyApp()
app.mainloop()
動作イメージ
こんなかんじで砂嵐が表示されます。
それなりに速く動くけどCPU利用率はなかなか。
あとは大きな画像を作るとそれなりにヘヴィーです。
使いどころが難しそうだけどpico8的なものを作ったりするときにひょっとしたら役にたつかもしれないですね。