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