<jupyter_start><jupyter_text>ImagesYou can draw images on canvases in two steps.First you must load the image and identify it with a name,and afterward you can draw the image any number of timesby providing x, y corner coordinates with width and height.You may also specify a rectangle inside the image to draw.<jupyter_code>from jp_doodle import dual_canvas
from IPython.display import display
# In this demonstration we do most of the work in Javascript.

demo = dual_canvas.SnapshotCanvas("Image0.png", width=320, height=220)
demo.display_all()

demo.js_init("""

// Mandrill from a remote image
var mandrill_url = "http://sipi.usc.edu/database/preview/misc/4.2.03.png";
// This local image reference works in "classic" notebook, but not in Jupyter Lab.
var mandrill_url = "../mandrill.png"
element.name_image_url("mandrill", mandrill_url);

// just the eyes, not the whole image
var eyes = element.named_image({
    name: "<NAME>",
    image_name: "mandrill", x:0, y:-40, w:80, h:30,
    sx:30, sy:15, sWidth:140, sHeight:20
    });
    
var mandrill = element.named_image({
    name: "<NAME>",
    image_name: "mandrill", x:0, y:0, w:200, h:200
    });
    
var square = element.named_image({
    name: "<NAME>",
    image_name: "mandrill", x:210, y:0, w:200, h:200,
    sx:40, sy:14, sWidth:30, sHeight:30
    });
    
var highlight = element.rect({name:"highlight", x:40, y:200-14, w:30, h:-30,
    color:"rgba(200,200,100,0.7)"});
    
// events to drag the square and adjust the detail.
// Attach a mousedown event which picks the highlight.
var moving = false;
var on_mouse_down = function(event) {
    moving = true;
};
element.on_canvas_event("mousedown", on_mouse_down);
square.on("mousedown", on_mouse_down)

// Attach a mousemove event which moves the highlight.
var on_mouse_move = function(event) {
    if (moving) {
        var loc = element.event_model_location(event);
        var x = loc.x;
        var y = loc.y;
        if ((x > 0) && (y > 30) && (x < 170) && (y < 200)) {
            highlight.change({x:loc.x, y:loc.y});
            square.change({sx:loc.x, sy:200-loc.y})
        }
    } 
};
element.on_canvas_event("mousemove", on_mouse_move);

// Attach a mouseup event which "drops" the current picked up object.
var on_mouse_up = function(event) {
    moving = false;
};
element.on_canvas_event("mouseup", on_mouse_up);

// Fit the figure into the available space
element.fit(null, 10);

$("<div>Drag the yellow square to adjust the detail view</div>").appendTo(element);
""")
#demo.save_pixels_to_png_async("Images.png")<jupyter_output><empty_output><jupyter_text>You can also load images from numpy arrays<jupyter_code># reading an image from python
import matplotlib.image as mpimg
img = mpimg.imread('../mandrill.png')
img.shape, img.max(), img.min()
demo2 = dual_canvas.SnapshotCanvas("Image1.png", width=320, height=220)
demo2.display_all()
# Scaled the image to byte values.
inverted = (1 - img) * 255
# Load the image to the canvas and name it.
demo2.name_image_array("inverted mandrill", inverted)
# Draw the image by name.
demo2.named_image("inverted mandrill", 50, 50, 210, 130)
# You can also use images with alpha channels
import matplotlib.image as mpimg
img2 = mpimg.imread('Transitions.png')
img2.shape, img2.max(), img2.min()
demo3 = dual_canvas.SnapshotCanvas("Image3.png", width=320, height=220)
demo3.display_all()
# Load the image, scaled to byte values, and name it.
inverted = img * 255
demo3.name_image_array("mandrill", inverted)
# Draw the image by name.
demo3.named_image("mandrill", 50, 50, 210, 130)

# draw a partially transparent image on top
demo3.name_image_array("alpha", img2 * 255)
demo3.named_image("alpha", 50, 50, 210, 130)
# Use a numpy array with transparency as a focus over another image.
import numpy as np

# focus_array has an opaque border and a clear center for a lens effect.
focus_array = np.zeros((100,100,4), dtype=np.float)
for i in range(50):
    f = 1.0 - i/50.0
    hi = 99-i
    focus_array[i:hi,i:hi,:] = f
focus_array[:,:,2] = 1 - focus_array[:,:,2] # invert blue band
    
demo4 = dual_canvas.SnapshotCanvas("Image4.png", width=520, height=420)
demo4.display_all()

demo4.name_image_array("focus", focus_array * 255)

demo4.js_init("""

// Mandrill from a remote image
var mandrill_url = "http://sipi.usc.edu/database/preview/misc/4.2.03.png";
// This local image reference works in "classic" notebook, but not in Jupyter Lab.
var mandrill_url = "../mandrill.png"
element.name_image_url("mandrill", mandrill_url);

// just the eyes, not the whole image
element.named_image({
    name: "mandrill eyes",
    image_name: "mandrill", x:0, y:-40, w:80, h:30,
    sx:30, sy:15, sWidth:140, sHeight:20
    });
    
var mandrill = element.named_image({
    name: "whole mandrill",
    image_name: "mandrill", x:0, y:0, w:200, h:200
    });
    
var square = element.named_image({
    name: "mandrill square",
    image_name: "mandrill", x:210, y:0, w:200, h:200,
    sx:40, sy:14, sWidth:30, sHeight:30
    });
    
var highlight = element.named_image({name:"highlight", x:40, y:200-14, w:30, h:-30,
    image_name: "focus"});
    
// events to drag the square and adjust the detail.
// Attach a mousedown event which picks the highlight.
var moving = false;
var on_mouse_down = function(event) {
    moving = true;
};
highlight.on("mousedown", on_mouse_down);

// Attach a mousemove event which moves the highlight.
var on_mouse_move = function(event) {
    if (moving) {
        var loc = element.event_model_location(event);
        var x = loc.x;
        var y = loc.y;
        if ((x > 0) && (y > 30) && (x < 170) && (y < 200)) {
            highlight.change({x:loc.x, y:loc.y});
            square.change({sx:loc.x, sy:200-loc.y})
        }
    } 
};
element.on_canvas_event("mousemove", on_mouse_move);

// Attach a mouseup event which "drops" the current picked up object and re-fits the canvas.
var on_mouse_up = function(event) {
    moving = false;
};
element.on_canvas_event("mouseup", on_mouse_up);

// Fit the figure into the available space
element.fit(null, 10);

$("<div>Drag the yellow square to adjust the detail view</div>").appendTo(element);
""")<jupyter_output><empty_output><jupyter_text>Loading canvas contents to numpy arraysIt is also possible to asynchronously load the contents of a canvas to a numpy array.The following example draws some objects on a canvas, loads the canvas image as a numpyarray and then runs a convolution over the image contents.  The resulting modified arrayis then displayed in another canvas.<jupyter_code>from scipy.ndimage import convolve

kernel = np.zeros((3,3), dtype=np.float)
kernel[1,:] = 1
kernel[:,1] = 1
image = np.zeros([7,7], dtype=np.float)
image[4,:] = 255
image[2,2] = 100

def convolve_and_scale255(image2d, kernel=kernel):
    cv = convolve(image2d, kernel)
    return (cv * (255.0/cv.max())).astype(np.int)

convolve_and_scale255(image)
big_kernel = np.eye(10) * 2.0 + 1
big_kernel[4,4] = 19
big_kernel[8,2] = 6
#big_kernel[4,:] = 4
#big_kernel[:,5] = 7

class ConvolveCanvas:
    
    def __init__(self):
        """
        Draw stuff on a canvas and call get_array_async when done.
        """
        # Display both the source and dest canvases
        self.source_canvas = dual_canvas.SnapshotCanvas("Image_source.png", width=320, height=220)
        self.source_canvas.display_all()
        self.dest_canvas = dual_canvas.SnapshotCanvas("Image_processed.png", width=320, height=220)
        self.dest_canvas.display_all()
        
        # put some stuff in the source canvas, and call get_array_async when done.
        self.source_canvas.js_init("""
            // A filled yellow circle (disk) named "<NAME>
            element.circle({name: "<NAME>", x:100, y:150, r:90, color:"yellow"});
            // A filled red rectangle named "<NAME>"
            element.rect({name: "<NAME>", x:100, y:130, w:100, h:20, color: "red"});
            // An unfilled white circle named "<NAME>"
            element.circle({
                name: "<NAME>", x:100, y:150, r:58, fill:false, 
                color:"white", lineWidth: 14});
            // An unfilled blue rectangle named <NAME>
            element.rect({
                name: "<NAME>", x:40, y:110, w:100, h:20,
                color: "blue", lineWidth: 10, degrees:70, fill:false});
            // A line segment named "<NAME>".
            element.line({
                name: "<NAME>", x1:190, y1:100, x2:10, y2:200,
                color:"purple", lineWidth: 20});
            element.fit();
            ready()
        """, ready = self.get_array_async)
        
    def get_array_async(self):
        """
        Get the array from the source_canvas and deliver it to the process_array callback
        """
        self.source_canvas.element["print"]("Now getting array async.")
        self.source_canvas.pixels_array_async(self.process_array)
        
    def process_array(self, image_array):
        """
        Process the canvas array and display it in the destination canvas.
        """
        processed_array = image_array.astype(np.float)
        # make background partially opaque
        processed_array[:,:,3] = np.maximum(processed_array[:,:,1], 100)
        # convolve all bands
        for i in range(3):
            processed_array[:,:,i] = convolve_and_scale255(processed_array[:,:,i], big_kernel)
        self.dest_canvas.name_image_array("processed", processed_array)
        # Draw the image by name.
        self.dest_canvas.named_image("processed", 0, 0, 320, 220)
        self.dest_canvas.element["print"]("Processed image loaded.")
        
C = ConvolveCanvas()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1342045218834267, 'fraction_numerical': 0.04107031736154325, 'mean_word_length': 3.3991788321167884, 'pattern_counts': {'":': 0, '<': 34, '<?xml version=': 0, '>': 34, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '3', 'dir': 'jupyter-structured-clean-dedup', 'id': '483005', 'license': 'BSD-2-Clause', 'n_tokens_mistral': 3481, 'n_tokens_neox': 3161, 'n_words': 913, 'path': 'notebooks/Feature demonstrations/Images.ipynb', 'repo_name': 'lingruiluo/jp_doodle', 'size': '9734'}