How to convert dataurl back to image and display on canvas
The reason your solution did not work is because you did not wait for the onload
event. Before the onload
event the image will not render.
To convert a canvas to a data URL is simple, use the .toDataURL();
method of the canvas element.
Then to convert the data URL back to an canvas image, you would first have to create an Image element and set its source as the dataURL. After getting the image onload
event you can draw the image onto the canvas. This could be accomplished as shown:
Assuming the data URL is in a variable called dataURL, the canvas context is in a variable called ctx.
var img = new Image;
img.onload = () => { ctx.drawImage(img, 0, 0); };
img.src = dataURL;
The final solution would go like this:
var cdata2 = c2.toDataURL();
var cimg2 = new Image;
cimg2.onload = () => { ctx4.drawImage(cimg2, 0, 0, c4.width, c4.height); };
PS: You don't have to scale the image object by specifying the width and height, the canvas will do that when you specify the destination width and height.
How I put the canvas content as a file in a input type file
The best is still to send files through a FormData and AJAX.
But since it seems it's for personal use, and that you already have something working with a <form>, you can probably use what is still an hack exposed in this answer of mine. Beware this still works only in latest Chromium and Geckos browsers (no Webkit support, which means no iOS support).
So the step by step is,
- draw on your canvas.
- export it to a Blob using the
HTMLCanvasElement.toBlob()
method. - build a File from this Blob
- build a DataTransfer object
- append the File to the DataTransfer's
items
list - set the
.files
property of your <input type="file"> to the DataTransfer's.files
// draw on the canvas
const canvas = document.createElement( "canvas" );
const ctx = canvas.getContext( "2d" );
ctx.fillStyle = "red";
ctx.fillRect( 20, 20, 260, 110 );
// convert to Blob (async)
canvas.toBlob( (blob) => {
const file = new File( [ blob ], "mycanvas.png" );
const dT = new DataTransfer();
dT.items.add( file );
document.querySelector( "input" ).files = dT.files;
} );
// to prove the image is there
document.querySelector( "#test" ).onclick = (evt) => {
const file = document.querySelector( "input" ).files[ 0 ];
document.body.appendChild( new Image() )
.src = URL.createObjectURL( file );
};
<form method="POST">
<input type="file" name="file"><br>
<button>submit</button> (check your dev tools network panel to see the File is sent)
</form>
<br>
<button id="test">
load input's content as image
</button>
Convert HTML5 canvas to image link
Assuming that data = canvas.toDataURL("image/jpeg")
, you can specify a base64 link with the correct headers :
const canvas = document.querySelector('canvas')const button = document.querySelector('button')const ctx = canvas.getContext('2d')
canvas.width = window.innerWidthcanvas.height = window.innerHeight
ctx.fillStyle = 'red'ctx.fillRect(50, 50, 100, 100)
button.addEventListener('click', () => { let data = canvas.toDataURL("image/jpeg"); data = data.replace('data:image/jpeg;base64,', '') console.log(data) downloadImage(data);})
function downloadImage(data, filename = 'untitled.jpeg') { const a = document.createElement('a'); a.href = 'data:application/octet-stream;headers=Content-Disposition%3A%20attachment%3B%20filename=' + filename + ';base64,' + data; a.download = filename; document.body.appendChild(a); a.click();}
<button>Save</button><canvas></canvas>
How to save an HTML5 Canvas as an image on a server?
Here is an example of how to achieve what you need:
- Draw something (taken from canvas tutorial)
<canvas id="myCanvas" width="578" height="200"></canvas>
<script>
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
// begin custom shape
context.beginPath();
context.moveTo(170, 80);
context.bezierCurveTo(130, 100, 130, 150, 230, 150);
context.bezierCurveTo(250, 180, 320, 180, 340, 150);
context.bezierCurveTo(420, 150, 420, 120, 390, 100);
context.bezierCurveTo(430, 40, 370, 30, 340, 50);
context.bezierCurveTo(320, 5, 250, 20, 250, 50);
context.bezierCurveTo(200, 5, 150, 20, 170, 80);
// complete custom shape
context.closePath();
context.lineWidth = 5;
context.fillStyle = '#8ED6FF';
context.fill();
context.strokeStyle = 'blue';
context.stroke();
</script>
Capture HTML Canvas as gif/jpg/png/pdf?
Original answer was specific to a similar question. This has been revised:
const canvas = document.getElementById('mycanvas')
const img = canvas.toDataURL('image/png')
with the value in IMG you can write it out as a new Image like so:
document.getElementById('existing-image-id').src = img
or
document.write('<img src="'+img+'"/>');
How can I convert canvas content to an image?
You can either generate a postscript document (to feed into some other tool: ImageMagick, Ghostscript, etc):
from Tkinter import *
root = Tk()
cv = Canvas(root)
cv.create_rectangle(10,10,50,50)
cv.pack()
root.mainloop()
cv.update()
cv.postscript(file="file_name.ps", colormode='color')
root.mainloop()
or draw the same image in parallel on PIL and on Tkinter's canvas (see: Saving a Tkinter Canvas Drawing (Python)). For example (inspired by the same article):
from Tkinter import *
import Image, ImageDraw
width = 400
height = 300
center = height//2
white = (255, 255, 255)
green = (0,128,0)
root = Tk()
# Tkinter create a canvas to draw on
cv = Canvas(root, width=width, height=height, bg='white')
cv.pack()
# PIL create an empty image and draw object to draw on
# memory only, not visible
image1 = Image.new("RGB", (width, height), white)
draw = ImageDraw.Draw(image1)
# do the Tkinter canvas drawings (visible)
cv.create_line([0, center, width, center], fill='green')
# do the PIL image/draw (in memory) drawings
draw.line([0, center, width, center], green)
# PIL image can be saved as .png .jpg .gif or .bmp file (among others)
filename = "my_drawing.jpg"
image1.save(filename)
root.mainloop()
Related Topics
Hexadecimal String to Byte Array in Python
How to Select Rows in a Dataframe Between Two Values, in Python Pandas
Replace Console Output in Python
Numpy Array Is Not JSON Serializable
How to Time a Code Segment for Testing Performance with Pythons Timeit
How to Fix Overlapping Annotations/Text
Dictionary Creation with Fromkeys and Mutable Objects. a Surprise
Create Nice Column Output in Python
How to Set Sys.Stdout Encoding in Python 3
Getting "Permission Denied" When Running Pip as Root on My MAC
String Concatenation of Two Pandas Columns
String Replace Doesn't Appear to Be Working
Pandas: Multiple Conditions While Indexing Data Frame - Unexpected Behavior