How can I download the image and canvas? - javascript

I am trying to draw canvas and also want to download, it working fine with download and text but I want to add image also how to do it? The code given bellow draws canvas and downloads it as a png also but how to add image in canvas heading and paragraph in it?
Here is html:
<canvas width="500" height="300" id="canvas">Sorry, no canvas available</canvas>
<a id="download">Download as image</a>
Here is jQuery:
<script type="text/javascript">
var canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d');
function doCanvas() {
/* draw something */
ctx.fillStyle = '#B00000';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = '#fff';
ctx.font = '60px sans-serif';
ctx.fillText('Some heading', 10, canvas.height / 2 + 10);
ctx.fillText('Some Paragraph', 15, canvas.height / 2 + 50);
}
function downloadCanvas(link, canvasId, filename) {
link.href = document.getElementById(canvasId).toDataURL();
link.download = filename;
}
document.getElementById('download').addEventListener('click', function() {
downloadCanvas(this, 'canvas', 'test.png');
}, false);
doCanvas();
</script>

var canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d');
**var background = new Image();
background.src = "your image path";**
you have to create a variable and then if you want background image of canvas than use it as
function doCanvas() {
ctx.fillRect(0, 0, canvas.width, canvas.height);
**ctx.drawImage(background,400,100,60,90);**
ctx.fillStyle = '#fff';
ctx.font = '60px sans-serif';
ctx.fillText('Some heading', 10, canvas.height / 2 + 10);
ctx.fillText('Some Paragraph', 15, canvas.height / 2 + 50);
}
function downloadCanvas(link, canvasId, filename) {
link.href = document.getElementById(canvasId).toDataURL();
link.download = filename;
}
document.getElementById('download').addEventListener('click', function() {
downloadCanvas(this, 'canvas', 'test.png');
}, false);
doCanvas();
</script>

Related

Merge webcam video and canvas drawing together in JS

I'm trying to merge webcam video and canvas drawing and save to an image file. It works but video image covers canvas draving. I tried to swap places context.drawImage but still same. Any ideas? :)
canvas.addEventListener("click", async function () {
var context = canvas.getContext("2d");
context.drawImage(video, 0, 0, canvas.width / 1.5, canvas.height / 1.5);
context.drawImage(canvas, 0, 0, canvas.width, canvas.height);
var dataURL = canvas.toDataURL("image/png");
$.ajax({
type: "POST",
url: "./upload.php",
data: {
dataURL: dataURL
}
});
});
Currently what you code does is to draw the canvas over itself, with the video already painted on it.
You can draw behind the existing content by using the globalCompositeOperation = "destination-over".
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
ctx.font = "16px sans-serif";
ctx.textAlign = "center";
const img = new Image(); // a video is the same
img.src = "https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png";
img.decode().then(() => {
canvas.onclick = (evt) => {
ctx.globalCompositeOperation = "destination-over";
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
// reset to default
ctx.globalCompositeOperation = "source-over";
};
ctx.fillText("click on the canvas", canvas.width / 2, canvas.height / 3);
ctx.fillText("to draw the image", canvas.width / 2, canvas.height / 3 + 20);
ctx.fillText("behind this text", canvas.width / 2, canvas.height / 3 + 40);
});
canvas { outline: 1px solid }
<canvas></canvas>

dataURL not working when the context of the canvas is an image

i was trying to download the context of the canvas as an image using dataURL() through the following code but it's not working for some reason. However, when i replace the context of the canvas to be something else besides the image it actually works, so can you tell how can i fix this
<a href="#" id="downloader" >Download!</a>
<canvas id="canvas"></canvas>
<script>
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var image = new Image(60, 45);
image.onload = function () {
ctx.clearRect(0, 0, canvas.width, canvas.height);
canvas.width = image.naturalWidth;
canvas.height = image.naturalHeight;
ctx.drawImage(image, 0, -60);
}
image.src = 'image.png';
$('#downloader').click(function(){
$(this).attr('href', document.getElementById('canvas').toDataURL("image/png").replace("image/png", "image/octet-stream"));
$(this).attr('download', "Picture.png");
});
</script>
Your JS should be:
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var image = new Image(60, 45);
//First add src, then set the height and width
image.src = 'image.png';
image.onload = function() {
canvas.width = image.width;
canvas.height = image.height;
// Draw image from start and not from behind the axis
ctx.drawImage(image, 0, 0);
}
$('#downloader').click(function() {
$(this).attr('href', document.getElementById('canvas').toDataURL("image/png"))
$(this).attr('download', "Picture.png");
});

Write on a canvas with background-image

So I am trying to build a Meme-Creator. You already can upload the pics as the background-img from the canvas. Now I am trying to do the Meme font but it isnt really working. However it is creating a big gap in the picture. Thanks for your help and attention! :D
var canvas = document.getElementById("meme-canvas");
var ctx = canvas.getContext("2d");
var width = canvas.width;
var height = canvas.height;
function readImage() {
if (this.files && this.files[0]) {
var FR = new FileReader();
FR.onload = function(e) {
var img = new Image();
img.addEventListener("load", function() {
ctx.clearRect(0, 0, width, height);
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0);
});
img.src = e.target.result;
};
FR.readAsDataURL(this.files[0]);
}
}
function Text() {
ctx.clearRect(0, 0, width, height);
var textT = document.getElementById("top-text").value;
var textB = document.getElementById("bottom-text").value;
ctx.font = "60px Impact";
ctx.lineWidth = 3;
ctx.strokeText(textT, 10, 65);
ctx.strokeText(textB, 10, 400);
}
document.getElementById("image-input").addEventListener("change", readImage, false);
<input type="file" id="image-input" accept="image/*">
<input type="text" id="top-text" oninput="Text()">
<input type="text" id="bottom-text" oninput="Text()">
<canvas style="position: absolute; width: 400px; top: 100px; left: 10px;" id="meme-canvas"></canvas>
I've made a few changes to your script. because you need to draw the image several times I've written a function that draws the image. The canvas is cleared every time one of the 2 text input changes it's value, and every time you have to redraw everything.
Also textT and textB can be declared only once. You don't need to declare them in the Text function.
I need to use the font size (60) more than once, so I've made a variable fontSize = 60
Since you don't know the size of your canvas ( depends on the size of the uploaded image ) you need to calculate the position for the bottom text textB = height - fontSize/2 where height is the height of the canvas: height = canvas.height = img.height;
I hope it's useful.
var canvas = document.getElementById("meme-canvas");
var ctx = canvas.getContext("2d");
var width = (canvas.width = 400);
var height = (canvas.height = 400);
var fontSize = 60;
var img = new Image();
var textT = document.getElementById("top-text");
var textB = document.getElementById("bottom-text");
function readImage() {
if (this.files && this.files[0]) {
var FR = new FileReader();
FR.onload = function(e) {
img.addEventListener("load", function() {
width = canvas.width = img.width;
height = canvas.height = img.height;
drawImage();
});
img.src = e.target.result;
};
FR.readAsDataURL(this.files[0]);
}
}
function drawImage() {
ctx.drawImage(img, 0, 0);
}
function Text() {
ctx.font = fontSize + "px Impact";
ctx.textAlign = "center";
ctx.lineWidth = 3;
ctx.clearRect(0, 0, width, height);
drawImage();
ctx.strokeText(textT.value, width / 2, 65);
ctx.strokeText(textB.value, width / 2, height - fontSize/2);
}
document
.getElementById("image-input")
.addEventListener("change", readImage, false);
textT.addEventListener("input", Text);
textB.addEventListener("input", Text);
canvas{position: absolute; left: 10px; top:60px;border:1px solid #d9d9d9;}
<input type="file" id="image-input" accept="image/*">
<input type="text" id="top-text" />
<input type="text" id="bottom-text" />
<canvas style="" id="meme-canvas"></canvas>
A few of the issues I encountered:
If you change the size of the canvas you should not use the variables, because those wont be correct, or you will need to keep track of them
If you do clearRect you have to be aware what are you clearing and re-draw it.
The font did not look too clear so I added a white shadow for better contrast
The bottom text needed to be relative to the canvas height
Here is the code:
var canvas = document.getElementById("meme-canvas");
var ctx = canvas.getContext("2d");
var img = new Image();
function readImage() {
if (this.files && this.files[0]) {
var FR = new FileReader();
FR.onload = function(e) {
img.addEventListener("load", function() {
canvas.width = img.width;
canvas.height = img.height;
draw();
});
img.src = e.target.result;
};
FR.readAsDataURL(this.files[0]);
}
}
function draw() {
var textT = document.getElementById("top-text").value;
var textB = document.getElementById("bottom-text").value;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.font = "60px Impact";
ctx.shadowColor = "white"
ctx.shadowOffsetX = ctx.shadowOffsetY = 2
ctx.lineWidth = 3;
if (img) ctx.drawImage(img, 0, 0);
ctx.strokeText(textT, 10, 45);
ctx.strokeText(textB, 10, canvas.height -10);
}
document.getElementById("image-input")
.addEventListener("change", readImage, false);
<input type="file" id="image-input" accept="image/*"><br>
<input type="text" id="top-text" placeholder="Top text" oninput="draw()"><br>
<input type="text" id="bottom-text" placeholder="Bottom text" oninput="draw()"><br>
<canvas id="meme-canvas"></canvas>

Get canvas toDataUrl() after processing Javascript

I have a Javascript function that create a canvas, write a image and a text on it. At the and I need the base64 dataUrl but what I get is only a blank canvas.
This is my function:
function createBreadCrumb(label) {
var canvas = document.createElement('canvas');
canvas.width = 25;
canvas.height = 30;
var img = new Image;
img.src = 'map-pin-breadcrumb.png';
var ctx=canvas.getContext("2d");
img.onload = function(){
ctx.drawImage(img, 0, 0);
ctx.font = "11px Arial";
ctx.textAlign="center";
ctx.fillText(label, 12, 16);
};
return canvas.toDataURL();
}
You are calling toDataURL before the image is loaded. As a result, none of your canvas instructions have run yet. Because the image is loaded asynchronously, you cannot get the resulting canvas synchronously and must use a callback or a promise.
Try this.
function createBreadCrumb(label, callback) {
var canvas = document.createElement('canvas');
canvas.width = 25;
canvas.height = 30;
var img = new Image;
var ctx = canvas.getContext("2d");
img.onload = function(){
ctx.drawImage(img, 0, 0);
ctx.font = "11px Arial";
ctx.textAlign="center";
ctx.fillText(label, 12, 16);
callback(canvas.toDataURL());
};
img.src = 'map-pin-breadcrumb.png';
}
createBreadCrumb("hello", function(crumb){
// do your stuff
});

How to Draw on Image Angular2 Ionic2

I know how to draw in Angular1 Ionic1.
In my html:
<img ng-src="{{image}}" style="width: 100%">
<canvas id="tempCanvas"></canvas>
In my controller
var startimg="img/face.jpg";
$scope.image=startimg;
var canvas = document.getElementById('tempCanvas');
var context = canvas.getContext('2d');
var source = new Image();
source.src = startimg;
canvas.width = source.width;
canvas.height = source.height;
console.log(canvas);
context.drawImage(source,0,0);
context.font = "100px impact";
textWidth = context.measureText($scope.frase).width;
if (textWidth > canvas.offsetWidth) {
context.font = "40px impact";
}
context.textAlign = 'center';
context.fillStyle = 'white';
context.fillText('HELLO WORLD',canvas.width/2,canvas.height*0.8);
var imgURI = canvas.toDataURL();
$timeout( function(){
$scope.image = imgURI;
}, 200);
This code would definitely draw HELLO WORLD text on the top of face image.
However, in Ionic2/Angular2, it seems doesn't work. I can't even get the document.getElementById('tempCanvas') to work.
Please help.
Thanks.
You can write the following:
#Component({
selector: 'my-app',
template: `<h1>Angular 2 Systemjs start</h1>
<img [src]="image">
<canvas #layout></canvas>
`
})
export class App {
#ViewChild('layout') canvasRef;
image = 'http://upload.wikimedia.org/wikipedia/commons/4/4a/Logo_2013_Google.png';
ngAfterViewInit() {
let canvas = this.canvasRef.nativeElement;
let context = canvas.getContext('2d');
let source = new Image();
source.crossOrigin = 'Anonymous';
source.onload = () => {
canvas.height = source.height;
canvas.width = source.width;
context.drawImage(source, 0, 0);
context.font = "100px impact";
context.textAlign = 'center';
context.fillStyle = 'black';
context.fillText('HELLO WORLD', canvas.width / 2, canvas.height * 0.8);
this.image = canvas.toDataURL();
};
source.src = this.image;
}
}
See also the plunkr https://plnkr.co/edit/qAGyQVqbo3IGSFzC0DcQ?p=preview
Or you can use custom directive like this:
#Directive({
selector: '[draw-text]'
})
class ImageDrawTextDirective {
loaded = false;
#Input() text: String;
#HostListener('load', ['$event.target'])
onLoad(img) {
if(this.loaded) {
return;
}
this.loaded = true;
let canvas = document.createElement('canvas');
let context = canvas.getContext('2d');
canvas.height = img.height;
canvas.width = img.width;
context.drawImage(img, 0, 0);
context.font = "100px impact";
context.textAlign = 'center';
context.fillStyle = 'black';
context.fillText(this.text, canvas.width / 2, canvas.height * 0.8);
img.src = canvas.toDataURL();
}
}
See plunkr for this case https://plnkr.co/edit/BrbAoBlLcbDcx8iDXACv?p=preview

Categories