Upload two images into html5 canvas - javascript

I am trying to upload two and more images into one canvas and make some sort of collage. Pictures are the same size. However, when I try upload the second image, the first one disappears. Below there is the code and example to JSfiddle. What is wrong?
jsfiddle
<div>
<input type="file" id="imageLoader1" name="imageLoader" />
<br/>
<input type="file" id="imageLoader2" name="imageLoader" />
<br/>
<canvas id="canvas" style="background:red;"></canvas>
</div>
And JS code:
var imageLoader1 = document.getElementById('imageLoader1');
var imageLoader2 = document.getElementById('imageLoader2');
imageLoader1.addEventListener('change', handleImage, false);
imageLoader2.addEventListener('change', handleImage, false);
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
function handleImage(e) {
if (e.target == imageLoader1) {
var reader = new FileReader();
reader.onload = function (event) {
var img1 = new Image();
img1.onload = function () {
canvas.width = 1000;
canvas.height = 500;
ctx.drawImage(img1, 0, 0, img1.width, img1.height, 0, 0, img1.width * 0.4, img1.height * 0.4);
}
img1.src = event.target.result;
}
reader.readAsDataURL(e.target.files[0]);
}
if (e.target == imageLoader2) {
var reader = new FileReader();
reader.onload = function (event) {
var img2 = new Image();
img2.onload = function () {
canvas.width = 1000;
canvas.height = 500;
ctx.drawImage(img2, 0, 0, img2.width, img2.height, img2.width * 0.4, img2.height * 0.4, img2.width * 0.4, img2.height * 0.4);
}
img2.src = event.target.result;
}
reader.readAsDataURL(e.target.files[0]);
}
}
The idea was taken here: How to upload image into HTML5 canvas

When you are trying to superimpose multiple images in single canvas,You need to use two distinct paths, also you need to clearly circumscribe them with the .beginPath() method.
I have modified you code, please check. It should work for you.
function handleImage(e) {
if (e.target == imageLoader1) {
var reader = new FileReader();
reader.onload = function (event) {
var img1 = new Image();
img1.onload = function () {
canvas.width = 1000;
canvas.height = 500;
//added begin path here
ctx.beginPath();
ctx.drawImage(img1, 0, 0, img1.width, img1.height, 0, 0, img1.width * 0.4, img1.height * 0.4);
}
img1.src = event.target.result;
}
reader.readAsDataURL(e.target.files[0]);
}
if (e.target == imageLoader2) {
var reader = new FileReader();
reader.onload = function (event) {
var img2 = new Image();
img2.onload = function () {
canvas.width = 1000;
canvas.height = 500;
//added begin path here
ctx.beginPath();
ctx.drawImage(img2, 0, 0, img2.width, img2.height, img2.width * 0.4, img2.height * 0.4, img2.width * 0.4, img2.height * 0.4);
}
img2.src = event.target.result;
}
reader.readAsDataURL(e.target.files[0]);
}
}
Alternate :
Or what you can do is use globalAlpha property of canvas.
Try : ctx.globalAlpha = 0.5; .This may solve your issue.
Alternate 2:
You can use multiple canvas layer for multiple images. This will directly superimpose your images. You can superimpose as many images as you want.

I've modified original jsfiddle: click.
Here what have been changed:
var imageLoader1 = document.getElementById('imageLoader1');
var imageLoader2 = document.getElementById('imageLoader2');
imageLoader1.addEventListener('change', handleImage, false);
imageLoader2.addEventListener('change', handleImage, false);
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
let z = 0.4; // zoom
canvas.width = 1000;
canvas.height = 500;
function handleImage(e) {
if (e.target == imageLoader1) {
let img = new Image();
img.src = URL.createObjectURL(e.target.files[0]);
img.onload = function() {
ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, img.width * z, img.height * z);
}
}
if (e.target == imageLoader2) {
let img = new Image();
img.src = URL.createObjectURL(e.target.files[0]);
img.onload = function() {
ctx.drawImage(img, 0, 0, img.width, img.height, img.width * z, img.height * z, img.width * z, img.height * z);
}
}
}
I've moved canvas initialization out of load handler and simplified the loader.
This solution will not superimpose your images (but this is just a fix for original jsfiddle from the Question).

Related

how to get entire image inside a canvas element?

I have a canvas element and want to load an entire image inside.
The canvas should be max 50% width.
The loaded images have different widths and heights but in any case I need entire image inside and not just a part of them.
Is it possible?
var URL = window.webkitURL || window.URL;
window.onload = function() {
var input = document.getElementById('input');
input.addEventListener('change', handleFiles, false);
}
function handleFiles(e) {
var ctx = document.getElementById('canvas').getContext('2d');
var url = URL.createObjectURL(e.target.files[0]);
var img = new Image();
img.onload = function() {
ctx.drawImage(img, 10, 10);
}
img.src = url;
}
#canvas{
max-width:50%;
}
<input type="file" id="input"/>
<canvas id="canvas"/>
drawImage's 4th and 5th parameter is the width and height. The example below will occupy the whole canvas.
var URL = window.webkitURL || window.URL;
window.onload = function() {
var input = document.getElementById('input');
input.addEventListener('change', handleFiles, false);
}
function handleFiles(e) {
var ctx = document.getElementById('canvas').getContext('2d');
var url = URL.createObjectURL(e.target.files[0]);
var img = new Image();
img.onload = function() {
ctx.drawImage(img, 0, 0, ctx.canvas.width, ctx.canvas.height);
}
img.src = url;
}
#canvas {
background-color: salmon;
max-width: 50%;
}
<input type="file" id="input" />
<canvas id="canvas" />
If you want a proportional image, we can use the solution here in calculating
var URL = window.webkitURL || window.URL;
window.onload = function() {
var input = document.getElementById('input');
input.addEventListener('change', handleFiles, false);
}
function handleFiles(e) {
var ctx = document.getElementById('canvas').getContext('2d');
var url = URL.createObjectURL(e.target.files[0]);
var img = new Image();
img.onload = function() {
var newDimen = calculateAspectRatioFit(img.width, img.height, ctx.canvas.width, ctx.canvas.height);
ctx.drawImage(img, 0, 0, newDimen.width, newDimen.height);
}
img.src = url;
}
function calculateAspectRatioFit(srcWidth, srcHeight, maxWidth, maxHeight) {
var ratio = Math.min(maxWidth / srcWidth, maxHeight / srcHeight);
return {
width: srcWidth * ratio,
height: srcHeight * ratio
};
}
#canvas {
background-color: salmon;
max-width: 50%;
}
<input type="file" id="input" />
<canvas id="canvas" />
If you want a centralized image, you can:
function handleFiles(e) {
var ctx = document.getElementById('canvas').getContext('2d');
var url = URL.createObjectURL(e.target.files[0]);
var img = new Image();
img.onload = function() {
var newDimen = calculateAspectRatioFit( img.width, img.height, ctx.canvas.width, ctx.canvas.height );
var tSpace = ( ctx.canvas.height - newDimen.height ) / 2;
var lSpace = ( ctx.canvas.width - newDimen.width ) / 2;
ctx.drawImage(img, lSpace, tSpace, newDimen.width, newDimen.height);
}
img.src = url;
}

HTML 5 Canvas image overlay repeatable

I am trying to take a pattern and apply it over a png image but only cover the non-transparent part of the image similar to this one.
http://jsfiddle.net/eLmmA/1/
$(function() {
var canvas = document.createElement('canvas');
canvas.width = 250;
canvas.height = 250;
var canvas_context = canvas.getContext("2d");
var img = new Image();
img.onload = function(){
var msk = new Image();
msk.onload = function(){
canvas_context.drawImage(img, 0, 0);
canvas_context.globalCompositeOperation = "destination-in";
canvas_context.drawImage(msk, 0, 0);
canvas_context.globalCompositeOperation = "source-over";
};
msk.src = 'http://i.stack.imgur.com/QtQrZ.png';
}
img.src = 'http://i.stack.imgur.com/MDGFY.jpg';
document.body.appendChild(canvas);
});
The example above is really close to what I want but I need to be able to use a smaller texture image and repeat it over the none pattern image. I am not familiar with how to use canvas properly but trying to learn more about it.
Thanks in advance!
Never mind I figured it out.
var canvas = document.createElement('canvas');
canvas.width = 250;
canvas.height = 250;
var canvas_context = canvas.getContext("2d");
var img = new Image();
img.onload = function(){
var msk = new Image();
msk.onload = function(){
var ptrn = canvas_context.createPattern(img, 'repeat');
canvas_context.fillStyle = ptrn;
canvas_context.fillRect(0, 0, canvas.width, canvas.height);
canvas_context.drawImage(img, 0, 0);
canvas_context.globalCompositeOperation = "destination-in";
canvas_context.drawImage(msk, 0, 0);
canvas_context.globalCompositeOperation = "source-over";
};
msk.src = $('#base_url').data('base')+'assets/themes/img/download.png';
}
img.src = $('#base_url').data('base')+'assets/uploads/thumbs/1381413411Purple-Night-Owls-thumb.jpg';
$('#itemPreview').html(canvas);

Combine two images in one canvas

I am using this code to display data of two canvas into third canvas but it is not working.
I am saving the two canvas data using localstorage and passing it to third canvas
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
//First canvas data
var img1 = loadImage(localStorage.getItem('cbdata'), main);
//Second canvas data
var img2 = loadImage(localStorage.getItem('cbdata1'), main);
var imagesLoaded = 0;
function main() {
imagesLoaded += 1;
if (imagesLoaded == 2) {
// composite now
ctx.drawImage(img1, 0, 0);
ctx.globalAlpha = 0.5;
ctx.drawImage(img2, 0, 0);
}
}
function loadImage(src, onload) {
var img = new Image();
img.onload = onload;
img.src = src;
return img;
}
Your code works. Check that the content of localStorage.getItem is non-empty. And I also slightly modified display of the images by changing ctx.drawImage commands:
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
//First canvas data
var img1 = loadImage('http://ep01.epimg.net/elpais/imagenes/2015/10/21/ciencia/1445444934_907402_1445781076_portada_normal.jpg', main);
//Second canvas data
var img2 = loadImage('http://ep01.epimg.net/economia/imagenes/2015/10/22/actualidad/1445508003_507635_1445508894_portada_normal.jpg', main);
var imagesLoaded = 0;
function main() {
imagesLoaded += 1;
if (imagesLoaded == 2) {
// composite now
ctx.drawImage(img1, 0, 0, 100, 100);
ctx.globalAlpha = 0.5;
ctx.drawImage(img2, 100, 0, 100, 100);
}
}
function loadImage(src, onload) {
console.log('loadImage', src);
var img = new Image();
img.onload = onload;
img.src = src;
return img;
}
https://jsfiddle.net/4Le4g8ta/

How to place the two images in single canvas using asp.net?

function draw()
{
var ctx = document.getElementById('canvas').getContext('2d');
var img = new Image();
img.onload = function()
{
ctx.drawImage(img,0,0);
ctx.beginPath();
ctx.moveTo(30,96);
ctx.lineTo(70,66);
ctx.lineTo(103,76);
ctx.lineTo(170,15);
ctx.stroke();
};
img.src = 'https://mdn.mozillademos.org/files/5395/backdrop.png';
}
I have this function in this code two images are placing in canvas but within few sec second img is moving to other place.i want to place both img in canvas how to do?
Try this code, hope this help: DEMO FIDDLE
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var img1 = loadImage('http://upload.wikimedia.org/wikipedia/en/2/24/Lenna.png', main);
var img2 = loadImage('http://introcs.cs.princeton.edu/java/31datatype/peppers.jpg', main);
var imagesLoaded = 0;
function main() {
imagesLoaded += 1;
if (imagesLoaded == 2) {
// composite now
ctx.drawImage(img1, 0, 0);
ctx.globalAlpha = 0.5;
ctx.drawImage(img2, 0, 0);
}
}
function loadImage(src, onload) {
var img = new Image();
img.onload = onload;
img.src = src;
return img;
}

Image Conversion wrongly cropping

In my application i have added the code to convert the image into base 64 with a resized images.When i try the following code the image part has been cropped.
function getBase64FromImageUrl(URL)
{
var img = new Image();
img.style.width = this.width,
img.style.height = this.height,
img.src = URL;
img.onload = function ()
{
var canvas = document.createElement("canvas");
canvas.width =150
canvas.height =150;
var ctx = canvas.getContext("2d");
ctx.drawImage(this, 10, 10);
var dataURL = canvas.toDataURL("image/jpg");
c=dataURL.replace(/^data:image\/(png|jpg);base64,/, "");
return c;
}
}
How to get the full image properly?What change requires in the code
function encodeImage(src, callback) {
var canvas = document.createElement('canvas'),
ctx = canvas.getContext('2d'),
img = new Image();
img.onload = function() {
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0, img.width, img.height);
callback(canvas.toDataURL());
}
img.src = src;
}
See this fiddle:
http://jsfiddle.net/NwaPT/3/

Categories

Resources