How to Convert Canvas Content to an Image

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:

  1. 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



Leave a reply



Submit