Skip to content

Instantly share code, notes, and snippets.

@melMass
Forked from korakot/draw.py
Last active July 27, 2023 10:32
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save melMass/d59bd9c13ba9cf10790ef8a8c5962de7 to your computer and use it in GitHub Desktop.
Save melMass/d59bd9c13ba9cf10790ef8a8c5962de7 to your computer and use it in GitHub Desktop.
Drawing on Google Colab

Drawing in Colab

Features

  • Controls for colors and stroke width draw_colab

Examples

draw(bg_color="white")

image

draw(bg_color="black",color="red")

image

Use in a loop

This is useful if you want to feed the image to a model periodically:

from PIL import Image
from IPython.display import Image as IImage
filename = "draw.png"
while True:
  img = draw(filename=filename,bg_color="white",color="red",line_width=8, w=512,h=512,loop=True)
  
  if not img:
    break
  filename = process_with_model(input=filename)
from google.colab import output
from base64 import b64decode
import os
import shutil
import uuid
COLAB_HTML_ROOT = "/usr/local/share/jupyter/nbextensions/google.colab/"
def moveToExt(filename:str) -> str:
if not os.path.exists(filename):
print("Image file not found")
return None
target = os.path.basename(filename)
target = os.path.join(COLAB_HTML_ROOT, str(uuid.uuid4()) + target)
shutil.copyfile(filename,target)
print("moved to ext")
return target
def draw(filename='drawing.png', color="black", bg_color="transparent",w=256, h=256, line_width=1,loop=False):
real_filename = os.path.realpath(filename)
html_filename = real_filename
html_real_filename = html_filename
if os.path.exists(real_filename):
html_real_filename = moveToExt(real_filename)
html_filename = html_real_filename.replace("/usr/local/share/jupyter","")
canvas_html = f"""
<canvas width={w} height={h}></canvas>
<div>
<label for="strokeColor">Stroke</label>
<input type="color" value="{color}" id="strokeColor">
<label for="bgColor">Background</label>
<input type="color" value="{bg_color}" id="bgColor">
</div>
<div class="slidecontainer">
<label for="lineWidth" id="lineWidthLabel">{line_width}px</label>
<input type="range" min="1" max="35" value="1" class="slider" id="lineWidth">
</div>
<div>
<button id="loadImage">Reload from disk</button>
<button id="reset">Reset</button>
<button id="save">Save</button>
<button id="exit">Exit</button>
</div>
<script>
function loadImage(url) {{
return new Promise(r => {{ let i = new Image(); i.onload = (() => r(i)); i.src = url; }});
}}
var canvas = document.querySelector('canvas')
var ctx = canvas.getContext('2d')
ctx.lineWidth = {line_width}
ctx.fillStyle = "{bg_color}";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.strokeStyle = "{color}";
var strokeColor = document.querySelector('#strokeColor')
var bgColor = document.querySelector('#bgColor')
var slider = document.getElementById("lineWidth");
slider.oninput = function() {{
ctx.lineWidth = this.value;
lineWidthLabel.innerHTML = `${{this.value}}px`
}}
function updateStroke(event){{
ctx.strokeStyle = event.target.value
}}
function updateBG(event){{
ctx.fillStyle = event.target.value
}}
bgColor.addEventListener("change", updateBG, false);
strokeColor.addEventListener("change", updateStroke, false);
var clear_button = document.querySelector('#reset')
var reload_img_button = document.querySelector('#loadImage')
var button = document.querySelector('#save')
var exit_button = document.querySelector('#exit')
var mouse = {{x: 0, y: 0}}
canvas.addEventListener('mousemove', function(e) {{
mouse.x = e.pageX - this.offsetLeft
mouse.y = e.pageY - this.offsetTop
}})
canvas.onmousedown = ()=>{{
ctx.beginPath()
ctx.moveTo(mouse.x, mouse.y)
canvas.addEventListener('mousemove', onPaint)
}}
canvas.onmouseup = ()=>{{
canvas.removeEventListener('mousemove', onPaint)
}}
var onPaint = ()=>{{
ctx.lineTo(mouse.x, mouse.y)
ctx.stroke()
}}
reload_img_button.onclick = async ()=>{{
console.log("Reloading Image {html_filename}")
let img = await loadImage('{html_filename}');
console.log("Loaded image")
ctx.drawImage(img, 0, 0);
}}
clear_button.onclick = ()=>{{
console.log('Clearing Screen')
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillRect(0, 0, canvas.width, canvas.height);
}}
canvas.addEventListener('load', function() {{
console.log('All assets are loaded')
}})
var data = new Promise(resolve=>{{
button.onclick = ()=>{{
resolve(canvas.toDataURL('image/png'))
}}
exit_button.onclick = ()=>{{
resolve()
}}
}})
// window.onload = async ()=>{{
// console.log("loaded")
// let img = await loadImage('{html_filename}');
// ctx.drawImage(img, 0, 0);
// }}
</script>
"""
display(HTML(canvas_html))
print("Evaluating JS")
data = output.eval_js("data")
if data:
print("Saving Sketch")
binary = b64decode(data.split(',')[1])
# filename = html_real_filename if loop else filename
with open(filename, 'wb') as f:
f.write(binary)
#return len(binary)
if loop:
output.clear()
return True
return False
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment