Canvas Coordinate Transforms

Stuff To Do:


Load image data


In [1]:
from __future__ import print_function, unicode_literals, division, absolute_import

from widget_canvas import CanvasImage
from widget_canvas import image

import toyplot as tp
import IPython
from ipywidgets import widgets



In [2]:
# Load two images.
data_A = image.read('images/Whippet.jpg')
data_B = image.read('images/Doberman.jpg')

Canvas 2D Image Transformations

The Canvas Element does not do a good job of keeping track of its own transformation matrix. Or at least the API does not make it easily retrievable once it's been set. I wrote a Python helper class based on an earlier JavaScript implementation by Simon Sarris: transform.js.

transform.py


In [3]:
from widget_canvas import transform


---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
<ipython-input-3-fe0ba9c897c0> in <module>()
----> 1 from widget_canvas import transform

ImportError: cannot import name 'transform'

In [ ]:
T = transform.Transform()

In [ ]:
T.reset()

In [ ]:
G = T.translate((4,4)).rotate(45/180.*np.pi)

In [ ]:


In [ ]:
G.invert()

In [ ]:
palette = tp.color.brewer('Set1', 3)

In [ ]:
points = [[0.0, 0.0],
          [1.0, 0.1],
          [2.0, 3.0],
          [1.5, 2.0],
          [1.0, 3.5]]

points = np.asarray(points)

In [ ]:
IPython.display.display(palette)

canvas = tp.Canvas(width=500, height=400)
axes = canvas.axes()

m = 'o'

x = points[:, 0].tolist()
y = points[:, 1].tolist()

c = palette.color(0)
mark = axes.scatterplot(x, y, marker=m, color=c, size=50)

In [ ]:


In [ ]:


In [ ]:
1/0

In [ ]:
import display_mouse_events

wid_image = display_mouse_events.display(data_A)

# Build a few helper widgets.
wid_butt = IPython.html.widgets.ButtonWidget(description='Reset Transform')
IPython.display.display(wid_butt)

In [ ]:
# Build event handler for the button I just added in the cell above.
def handle_reset(widget_butt):
    wid_image.transform.reset()

# Attach event handler to the button.
wid_butt.on_click(handle_reset)

In [ ]:
IPython.display.display(wid_image.transform)

In [ ]:
print(0)
wid_image.transform.scale(1.2).scale(5).rotate(15)
print(1)

In [ ]:
IPython.display.display(wid_image.transform)

In [ ]:
1/0

In [ ]:
import time

T = canvas.transform.Transform() 

def update_transform(T):
    wid_image._transform = T.values
#     IPython.display.clear_output(True)
#     IPython.display.display(T)
    

def handle_slide_scale(name_trait, value_old, value_new):
    X, Y = wid_image.mouse_xy
    
    T.translate(-X, -Y)
    T.scale(value_new/value_old)
    T.translate(X, Y)

    update_transform(T)
    
# def handle_A(wid):
#     T.scale(1./1.1)
#     update_transform(T)
# def handle_B(wid):
#     T.scale(1.1)
#     update_transform(T)

def handle_scroll(widget, ev):
    tick = ev['deltaY']

    factor = 1.1
    
    if tick == 0:
#         raise Exception()
#         print('tick == 0, do nothing')
        return

    if tick > 0:
        scl = factor
    else:
        scl = 1./factor

    px, py = ev['canvas_xy']

    Q = T.copy()
    Q.invert()
    
    px, py = Q.transform_point(px, py)
    T.translate(px, py).scale(scl).translate(-px, -py)
  
    update_transform(T)

    
def handle_drag(widget, ev):
    dx, dy = ev['drag_delta_xy']
    
#     D = T.copy()
#     qx, qy = Q.invert().transform_point(dx, dy)
#     qx, qy = T.transform_point(dx, dy)
#     T.translate(dx, dy, update=True)  #.scale(scl).translate(px, py)

    
    Q = T.copy()
    Q.invert()
    
    p0x, p0y = Q.m13, Q.m23  # Q.transform_point(0, 0)
    pdx, pdy = Q.transform_point(dx, dy)
#     print(dx, dy, px, py)
    T.translate(pdx-p0x, pdy-p0y)

    update_transform(T)
    
      
# wid_slide.on_trait_change(handle_slide_scale, name=str('value'))
# wid_butt_A.on_click(handle_A)

wid_butt_C.on_click(handle_C)

wid_image.on_mouse_wheel(handle_scroll)
wid_image.on_mouse_drag(handle_drag)

In [ ]: