Revision 42 canvas.py
| canvas.py (revision 42) | ||
|---|---|---|
| 1 | 1 |
from __future__ import with_statement |
| 2 | 2 |
from pymt import * |
| 3 | 3 |
from pyglet.gl import * |
| 4 |
from numpy import * |
|
| 5 |
import string |
|
| 4 |
from layermanager import * |
|
| 6 | 5 |
|
| 7 | 6 |
class Canvas(MTScatterWidget): |
| 8 | 7 |
def __init__(self, **kwargs): |
| 9 | 8 |
super(Canvas, self).__init__(**kwargs) |
| 10 |
self.width = 500 |
|
| 11 |
self.height = 400 |
|
| 9 |
self.canvas_area = MTStencilContainer(pos=(20,20),size=(self.width-40,self.height-40)) |
|
| 10 |
self.add_widget(self.canvas_area) |
|
| 11 |
self.layer_manager = LayerManager(pos=(20,20),canvas=self,size=(self.width-40,self.height-40)) |
|
| 12 |
self.canvas_area.add_widget(self.layer_manager) |
|
| 12 | 13 |
self.fbo = Fbo(size=(self.width, self.height), with_depthbuffer=False) |
| 13 |
self.color = (0,1,0,1.0) |
|
| 14 |
set_brush('brushes/brush_particle.png')
|
|
| 15 |
self.layer_clear() |
|
| 16 |
self.touch_positions = {}
|
|
| 17 |
self.mode = "zoom" |
|
| 18 |
set_brush_size(25) |
|
| 19 |
self.brush_color=(0,0,0,1) |
|
| 20 |
|
|
| 21 |
def layer_clear(self): |
|
| 22 |
self.fbo.bind() |
|
| 23 |
glClearColor(0,0,0,0) |
|
| 24 |
glClear(GL_COLOR_BUFFER_BIT) |
|
| 25 |
self.fbo.release() |
|
| 26 |
|
|
| 27 |
def on_touch_down(self, touches, touchID, x, y): |
|
| 28 |
if self.collide_point(x,y): |
|
| 29 |
self.touch_positions[touchID] = self.to_local(x,y) |
|
| 30 |
if self.mode == "draw": |
|
| 31 |
self.fbo.bind() |
|
| 32 |
set_color(*self.brush_color) |
|
| 33 |
set_brush('brushes/brush_particle.png')
|
|
| 34 |
set_brush_size(25) |
|
| 35 |
drawCircle(pos=self.to_local(x,y), radius=1) |
|
| 36 |
self.fbo.release() |
|
| 37 |
elif self.mode == "zoom": |
|
| 38 |
super(Canvas, self).on_touch_down(touches, touchID, x, y) |
|
| 39 |
elif self.mode == "smudge": |
|
| 40 |
self.do_smudge(self.touch_positions[touchID][0],self.touch_positions[touchID][1]) |
|
| 41 |
|
|
| 42 |
return True |
|
| 43 |
|
|
| 44 |
def on_touch_move(self, touches, touchID, x, y): |
|
| 45 |
if self.touch_positions.has_key(touchID): |
|
| 46 |
if self.mode == "zoom": |
|
| 47 |
super(Canvas, self).on_touch_move(touches, touchID, x, y) |
|
| 48 |
elif self.mode == "draw": |
|
| 49 |
cur_pos = self.to_local(x,y) |
|
| 50 |
ox,oy = self.touch_positions[touchID] |
|
| 51 |
self.fbo.bind() |
|
| 52 |
set_color(*self.brush_color) |
|
| 53 |
set_brush('brushes/brush_particle.png')
|
|
| 54 |
set_brush_size(25) |
|
| 55 |
paintLine((ox,oy,cur_pos[0],cur_pos[1])) |
|
| 56 |
self.fbo.release() |
|
| 57 |
self.touch_positions[touchID] = self.to_local(x,y) |
|
| 58 |
return True |
|
| 59 |
|
|
| 14 |
|
|
| 60 | 15 |
def draw(self): |
| 61 | 16 |
with gx_matrix: |
| 62 |
glColor4f(1,1,1,1) |
|
| 63 |
drawRectangle((-6,-6),(self.width+12,self.height+12)) |
|
| 64 |
glScaled(float(self.width)/500, float(self.height)/400, 2.0) |
|
| 65 |
with gx_blending: |
|
| 66 |
drawTexturedRectangle(self.fbo.texture, (-6,-6),(self.width+12,self.height+12)) |
|
| 67 |
|
|
| 17 |
glColor4f(0,0,0,1) |
|
| 18 |
drawRectangle((0,0),(self.width,self.height)) |
|
| 19 |
|
|
| 68 | 20 |
def set_mode(self,mode): |
| 69 |
self.mode = mode |
|
| 21 |
self.layer_manager.set_mode(mode) |
|
| 22 |
|
|
| 23 |
def create_layer(self,pos=(0,0),size=(200,200),color=(0,0,0,0.5)): |
|
| 24 |
self.layer_manager.create_layer(pos=pos,size=size,color=color) |
|
| 70 | 25 |
|
| 26 |
def save_image(self): |
|
| 27 |
with self.fbo: |
|
| 28 |
self.layer_manager.background.dispatch_event('on_draw')
|
|
| 29 |
for layer in self.layer_manager.layer_list : |
|
| 30 |
layer.dispatch_event('on_draw')
|
|
| 31 |
data = (self.fbo.texture).get_image_data() |
|
| 32 |
data.save(file='test.png') |
|
| 33 |
|
|
| 71 | 34 |
def set_brush_color(self,color): |
| 72 |
self.brush_color = color |
|
| 35 |
self.layer_manager.set_brush_color(color) |
|
| 36 |
|
|
| 37 |
def set_brush(self,sprite,size): |
|
| 38 |
self.layer_manager.set_brush(sprite,size) |
|
| 73 | 39 |
|
| 74 |
|
|
| 75 |
def do_smudge(self, x, y): |
|
| 76 |
# First, extract region from texture |
|
| 77 |
region = self.fbo.texture.get_region(int(x) - 16, int(y) - 16, 32, 32) |
|
| 78 |
data = region.get_image_data() |
|
| 79 |
# Extract pixels |
|
| 80 |
format = 'RGB' |
|
| 81 |
pitch = 32 * len(format) |
|
| 82 |
pixel_data = data.get_data(format, pitch) |
|
| 83 |
pixels_list = map(ord, list(pixel_data)) |
|
| 40 |
def collide_point(self, x,y): |
|
| 41 |
local_coords = self.to_local(x,y) |
|
| 42 |
if local_coords[0] > 0 and local_coords[0] < self.width \ |
|
| 43 |
and local_coords[1] > 0 and local_coords[1] < self.height: |
|
| 44 |
return True |
|
| 45 |
else: |
|
| 46 |
return False |
|
| 84 | 47 |
|
| 85 |
pixels = zeros((32,32,3), float) |
|
| 86 |
z = 0 |
|
| 87 |
for i in range(0,31): |
|
| 88 |
for j in range(0,31): |
|
| 89 |
for k in range(0,2): |
|
| 90 |
pixels[i,j,k] = pixels_list[z] |
|
| 91 |
z += 1 |
|
| 92 |
#work |
|
| 93 |
state=zeros((32,32,3), float) |
|
| 94 |
rate = 0.5 |
|
| 95 |
|
|
| 96 |
#i = 32 * 32; |
|
| 97 |
for i in range (32*32,0,-1) : |
|
| 98 |
iy = i >> 5 |
|
| 99 |
ix = i & 0x1f |
|
| 100 |
# is it not on the circle of radius sqrt(120) at location 16,16? |
|
| 101 |
if (ix - 16) * (ix - 16) + (iy - 16) * (iy - 16) > 120 : |
|
| 102 |
continue |
|
| 103 |
# it is on the circle, so grab it |
|
| 104 |
|
|
| 105 |
# Get color |
|
| 106 |
r = float(pixels[ix,iy,0])/float(255) |
|
| 107 |
g = float(pixels[ix,iy,1])/float(255) |
|
| 108 |
b = float(pixels[ix,iy,02])/float(255) |
|
| 109 |
#print r,g,b |
|
| 110 |
|
|
| 111 |
state[ix,iy,0] = rate * state[ix,iy,0] + (1.0 - rate) * r |
|
| 112 |
state[ix,iy,1] = rate * state[ix,iy,1] + (1.0 - rate) * g |
|
| 113 |
state[ix,iy,2] = rate * state[ix,iy,2] + (1.0 - rate) * b |
|
| 114 |
|
|
| 115 |
#put back pixel |
|
| 116 |
z = 0 |
|
| 117 |
for i in range(0,31): |
|
| 118 |
for j in range(0,31): |
|
| 119 |
for k in range(0,2): |
|
| 120 |
pixels_list[z] = pixels[i,j,k] |
|
| 121 |
z += 1 |
|
| 122 |
|
|
| 123 |
data.set_data(format, pitch, ''.join(map(chr, pixels_list))) |
|
| 124 |
texture = data.get_texture() |
|
| 125 |
|
|
| 126 |
# Draw texture on Fbo |
|
| 127 |
with self.fbo: |
|
| 128 |
drawTexturedRectangle(texture, pos=(x - 16, y - 16), size=(32, 32)) |
|
| 48 |
if __name__ == '__main__': |
|
| 49 |
w = MTWindow() |
|
| 50 |
canvas = Canvas(size=(540,440),pos=(w.width/2-260,w.height/2-120)) |
|
| 51 |
w.add_widget(canvas) |
|
| 52 |
draw_but = MTButton(label="Painting") |
|
| 53 |
w.add_widget(draw_but) |
|
| 54 |
@draw_but.event |
|
| 55 |
def on_press(touchID, x, y): |
|
| 56 |
canvas.set_mode(mode='draw') |
|
| 57 |
zoom_but = MTButton(label="Layering",pos=(draw_but.width+5,0)) |
|
| 58 |
w.add_widget(zoom_but) |
|
| 59 |
@zoom_but.event |
|
| 60 |
def on_press(touchID, x, y): |
|
| 61 |
canvas.set_mode(mode='zoom') |
|
| 129 | 62 |
|
| 63 |
add_but = MTButton(label="Save",pos=(draw_but.width+zoom_but.width+10,0)) |
|
| 64 |
@add_but.event |
|
| 65 |
def on_press(touchID, x, y): |
|
| 66 |
canvas.save_image() |
|
| 67 |
w.add_widget(add_but) |
|
| 130 | 68 |
|
| 131 |
|
|
| 69 |
canvas.create_layer(pos=(100,100),size=(200,200),color=(1,0,0,0.8)) |
|
| 70 |
canvas.create_layer(size=(300,200),color=(0,1,0,0.8)) |
|
| 71 |
canvas.create_layer(size=(250,150),color=(0,0,1,0.8)) |
|
| 72 |
runTouchApp() |
|
| 73 |
|
|
| 74 |
|
|
| 75 |
|
|
Also available in: Unified diff
