Last active
August 29, 2015 14:22
-
-
Save mieki256/cf04af8b72ddd29fa95b to your computer and use it in GitHub Desktop.
Python 2.7.9 + Tkinter + Pillow 2.8.1 で夜景のビルのテクスチャっぽい画像を生成するスクリプト
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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