Skip to content

Instantly share code, notes, and snippets.

@mieki256
Last active August 29, 2015 14:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mieki256/cf04af8b72ddd29fa95b to your computer and use it in GitHub Desktop.
Save mieki256/cf04af8b72ddd29fa95b to your computer and use it in GitHub Desktop.
Python 2.7.9 + Tkinter + Pillow 2.8.1 で夜景のビルのテクスチャっぽい画像を生成するスクリプト
#!/usr/bin/env python
# -*- mode: python; Encoding: utf-8; coding: utf-8 -*-
# Last updated: <2015/06/02 20:20:33 +0900>
"""
m256 building texture maker
by mieki256
License: CC0
use Python 2.7.9 + Tkinter + Pillow 2.8.1
"""
from tkFileDialog import *
import Tkinter as Tk
import random
from PIL import Image, ImageTk
from PIL import ImageFilter
class Frame(Tk.Frame):
def __init__(self, master=None):
Tk.Frame.__init__(self, master)
self.master.title('m256 Building Texture Maker')
self.pack()
self.grid_count_x = Tk.IntVar()
self.grid_count_y = Tk.IntVar()
self.grid_size_x = Tk.IntVar()
self.grid_size_y = Tk.IntVar()
self.ratio = Tk.DoubleVar()
self.line_enable = Tk.BooleanVar()
self.smooth_enable = Tk.BooleanVar()
self.grid_count_x.set(64)
self.grid_count_y.set(64)
self.grid_size_x.set(8)
self.grid_size_y.set(8)
self.ratio.set(0.20)
self.line_enable.set(False)
self.smooth_enable.set(False)
self.f1 = Tk.Frame(self)
self.la1 = Tk.Label(self.f1, text='Grid Count')
self.la2 = Tk.Label(self.f1, text='x')
self.la3 = Tk.Label(self.f1, text='Grid Size')
self.la4 = Tk.Label(self.f1, text='x')
self.eb1 = Tk.Entry(self.f1, width=6,
textvariable=self.grid_count_x)
self.eb2 = Tk.Entry(self.f1, width=6,
textvariable=self.grid_count_y)
self.eb3 = Tk.Entry(self.f1, width=6,
textvariable=self.grid_size_x)
self.eb4 = Tk.Entry(self.f1, width=6,
textvariable=self.grid_size_y)
self.sc1 = Tk.Scale(self.f1, label='Ratio',
from_=0.005, to=1.0, variable=self.ratio,
orient=Tk.HORIZONTAL, resolution=0.01)
self.ck1 = Tk.Checkbutton(self.f1, text='Line',
variable=self.line_enable)
self.ck2 = Tk.Checkbutton(self.f1, text='Smooth',
variable=self.smooth_enable)
self.bt1 = Tk.Button(self.f1, text='Make',
command=self.make_image)
self.bt2 = Tk.Button(self.f1, text='Save',
command=self.save_image)
self.bt3 = Tk.Button(self.f1, text='Preview',
command=self.preview_image)
self.canvas = Tk.Canvas(self, width=512, height=512)
self.la1.grid(column=0, row=0)
self.eb1.grid(column=1, row=0)
self.la2.grid(column=2, row=0)
self.eb2.grid(column=3, row=0)
self.la3.grid(column=0, row=1)
self.eb3.grid(column=1, row=1)
self.la4.grid(column=2, row=1)
self.eb4.grid(column=3, row=1)
self.sc1.grid(column=0, row=2, columnspan=4,
sticky=Tk.W + Tk.E)
self.ck1.grid(column=0, row=3, sticky=Tk.W)
self.ck2.grid(column=1, row=3, sticky=Tk.W)
self.bt1.grid(column=1, row=4, padx=8)
self.bt2.grid(column=2, row=4, padx=8)
# self.bt3.grid(column = 3, row = 4, padx = 8)
self.f1.pack(side=Tk.LEFT, anchor=Tk.NW, padx=4, pady=4)
self.canvas.pack(side=Tk.LEFT, padx=4, pady=4)
self.make_image()
def make_image(self):
gw = self.grid_count_x.get()
gh = self.grid_count_y.get()
sw = self.grid_size_x.get()
sh = self.grid_size_y.get()
rt = self.ratio.get()
line = self.line_enable.get()
smooth = self.smooth_enable.get()
img_w = gw * sw
img_h = gh * sh
self.pilimage = self.get_image((gw, gh), (sw, sh), rt, line, smooth)
self.photo = ImageTk.PhotoImage(self.pilimage)
self.canvas.create_image(0, 0, anchor=Tk.NW, image=self.photo)
self.canvas.configure(width=img_w, height=img_h)
def get_image(self, grid_count, grid_size, ratio, line, smooth):
gw, gh = grid_count
sw, sh = grid_size
img_w = gw * sw
img_h = gh * sh
self.im = Image.new('RGB', (img_w, img_h), (0, 0, 0))
lights = self.get_light_seq(gw, gh, ratio, line)
for i, v in enumerate(lights):
gx = (i % gw) * sw
gy = int(i / gw) * sh
block_im = self.get_one_block(sw - 2, sh - 2, v, smooth)
self.im.paste(block_im, (gx + 1, gy + 1))
return self.im
def get_light_seq(self, w, h, ratio, line_enable):
n = w * h
cbuf = [0] * n
vlist = [0, 32, 64, 96, 192, 255]
if line_enable:
for y in range(h):
v = random.random()
xbuf = [0] * w
if v < ratio:
for i, x in enumerate(range(w / 2)):
xbuf[i] = vlist[random.randint(0, len(vlist) - 1)]
random.shuffle(xbuf)
else:
xbuf = [0] * w
for x, v in enumerate(xbuf):
cbuf[y * w + x] = v
else:
cnt = int(n * ratio) / len(vlist)
for v in vlist:
for i in range(cnt):
x = random.randint(0, w - 1)
y = random.randint(0, h - 1)
cbuf[y * w + x] = v
return cbuf
def get_one_block(self, w, h, v, smooth):
tim = Image.new('RGB', (w, h), (0, 0, 0))
if v <= 128:
for py in range(h):
cw = random.randint(0, 96 * py / h)
for px in range(w):
r = v + random.randint(0, cw)
if r < 0:
r = 0
tim.putpixel((px, py), (r, r, r))
else:
for py in range(h):
cw = v * py / h
for px in range(w):
vv = v - random.randint(0, cw)
r = vv - random.randint(0, vv / 4)
g = vv - random.randint(0, vv / 4)
b = vv - random.randint(0, vv / 4)
tim.putpixel((px, py), (r, g, b))
if smooth:
f = ImageFilter.Kernel((3, 3), [0, 2, 0, 1, 3, 1, 0, 2, 0], 9)
return tim.filter(f)
# return tim.filter(ImageFilter.SMOOTH)
else:
return tim
def save_image(self):
fname = asksaveasfilename(filetypes=[('PNG', '*.png')])
if fname != "":
self.im.save(fname)
# print "save %s" % (fname)
def preview_image(self):
self.im.show()
if __name__ == '__main__':
f = Frame()
f.mainloop()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment