how to get entire image inside a canvas element? - javascript

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;
}

Related

How can I use globalCompositeOperation to merge/overlay two images?

How can I use globalCompositeOperation to combine two images into one? I am not sure which one is best but I would like to experiment with source-over or source-in
Consider this MWE (but not quite!):
<html>
<div id="t-bg"
style="width: 100%; height: 100%; position: absolute; background-repeat: no-repeat; background-position: 55px top; background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAATwAAABQAQMAAAC+ilvQAAAABlBMVEUAAADu7u6BVFV4AAAFZ0lEQVRIiY2Wv2/bRhTHH0O3l6ExBXSoC6Ri/oMim4EqZYoO/Teyt4OzGYjhY6NBQ4Fo7Wb/Cd2TQhRcQKM9dijCU1hAW0TBLUhH9L2+dz8oSkHTHgTxePfh97179+4HYIX/p5SAC36OO21qh8kdOOXnpNOx2gFjBxa7VtZtTfr/JYMf8DH2lSmDHyjSixctWCdtr+7Y9m5VBpxQrZFtZyOv2/qyrXlFbV25NdXFFrINclljcWMqrDjbQTsgeVCV0n7BirOWkdtgzGPqRH7owkiN7ynir77TGHfldtdHVtWJeebvDceCHBwz4KiJTQRaNWqW9MnEgdqFxyr+9cwmjLVJvn/XMd3Il9ZP0n7j06cxfkj9JXYDvjrz1io/hY2wT+nAiUnBdQsi2hzFJtgeDPn/N1U74E0WdcGpBd9F9nWySZoabDCcX8VGsX13YJiKjiPstE8zLhThWqKm32FYh9xibCxMlphROylKnXpiWAhxODcdFMqRWZcGrDwoiVUMPlzgT9TyHJsIBQel6s71jbGVMZhM2SEdciiFad4Bb26tYmK8aULUIynaONrSkN1Xx6ksEwY/46bfaETCDqsDlrIOb2sIyxj1XjJpQRd1D77FVBJV34EnAvV+Yhr/YPAtyA54PUNIaD4O70A/YEXjDI1Ei/mDmFP4yoFLBHGj4RAgTCX5SG25IlAJBRFPRepAxGOol/UBABwlGmhW9SUogZkBKUBGcYUl4i9wUDR3AYL9mMF1cwR7BuxFzkdNaUTBgwEsGxIM6I1ECl1CQOBI3ffgq5MA1SmmSUp5tQegpCJF2hEzweDbfqtYQ6JkfhWXBgwyVKpPXTIj0yD+bBXRgMNSllTb2xMK68d9nqkMRANCnUa6C84IlKS4Hyu5SAksnxGo94XSglLUgQ9VsmTwNSnGKlbHFJ7smMFElDrYgMGbBBl8QT7GKlLijBLjewWiTkalhg54waaMIoEHiqa3hojAlMFWsaR54+wpn2oGy3scHm3BwahE8KNuwdCATfQgi71ij8Dpu11FuEPggQ7TmgaTJmogXsCoHOvDHZDSjMAeAtDmR/uxOhEaBCUCuSw74Gn9dQsG3KsJfJJgxNWkq3iYsI896UGzU81QbBTDLOT1TOlK1hnEOXWcwH2xVh/R8gLvI4FrVE8Z/AF6gkAe2ZF4JepihHtHG/B1uLpVRxDn9YkDqeMobsSaNhTogDpUyOCsPoYe+dmCvPNQLJINuKK0/jjOyUleNgQqKA04pGXFS8iB364NiB7UOYH9QTS2YKuIlBQKFn3eQn+mZYP8WvYG8aQajlMIpGKwLgVe5OSKvi+rOrjbgjCIsRjmBPI6BVwzOE7O9/U+Lmow4JLABgZf4ZRNB7TvGdME/p6oSAusGDywig08eorXLzENfiywBRWDIQ/mbvB1QGejAg2P1lhNMP10vrQg7RxTWl9CBxY8C2jnfgKXcIh8EqSfr3ALHLEiwicBWtNRGkgGs3gbLEaaN+EysuA5RJnba/sWrBx44cGpAVOISgs2TnHBYAbyYujAlbnFnbcgxjcGvEQVEXgapqcRHejcO7U+etAc8M7HDI7hLOB8pljJeQve+qNgAz6+Rws9ySVensi59iDfZKou+JwyhMIo6aTVj8j/Lwx4zygWDmwkga85Edg1aX50BWHQGvWKmhVp/ZojzheJdo/n86Doms6DxDPuiqTMESJxB5ylGv09R5r/ecZMvDWY8wTza50sTaBzJ7xgoUq2N1AGTVw1fmO+jb0Ll84Td/9i0F3WC3Ntk86Y1O3Ilh401hq5c82ut97GV/681rhT1ltvefrBe3inwH+BPi2s4vjfQeMqjfvqH6domRhN4Ch9AAAAAElFTkSuQmCC");">
</div>
<br> <br> <br> <br> <br>
clickme
<div id="t-fg"
style="width: 100%; height: 100%; position: absolute; background-repeat: no-repeat; background-position: left top; background-image: url("data:image/png;base64,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");">
</div>
</html>
<script>
function b64toImageData(datas) {
return new Promise(async function (resolve, reject) {
// We create an image to receive the Data URI
var img = document.createElement("img");
// When the event "onload" is triggered we can resize the image.
img.onload = function () {
// We create a canvas and get its context.
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
// We set the dimensions at the wanted size.
canvas.width = img.width;
canvas.height = img.height;
// We resize the image with the canvas method drawImage();
ctx.drawImage(this, 0, 0, img.width, img.height);
// get image data
var imageDatas = ctx.getImageData(0, 0, img.width, img.height);
// This is the return of the Promise
resolve(imageDatas);
};
// add data to img
img.src = datas;
});
}
function imagedata_to_image(imagedata) {
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
canvas.width = imagedata.width;
canvas.height = imagedata.height;
ctx.putImageData(imagedata, 0, 0);
var image = new Image();
image.src = canvas.toDataURL();
return image;
}
function MergeImg(bg, fg) {
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
var bg = imagedata_to_image(bg);
var fg = imagedata_to_image(fg);
ctx.drawImage(fg, 0, 0, 300, 80);
ctx.globalCompositeOperation = 'source-over';
ctx.drawImage(bg, 55, 0, 300, 80);
var imageDatas = ctx.getImageData(0, 0, 300, 80);
var newImage = imagedata_to_image(imageDatas);
console.log('newimg', newImage);
return newImage;
}
document.body.addEventListener("click", async (e) => {
let el = e.target;
if (el.id == "t-fg") {
// get base64
var fg = document.getElementById("t-fg").style.backgroundImage.slice(5, -2);
var bg = document.getElementById('t-bg').style.backgroundImage.slice(5, -2);
// get ImageData
var bg_img = await b64toImageData(bg);
var fg_img = await b64toImageData(fg);
// merge
var out = MergeImg(bg_img, fg_img);
}
});
</script>

Upload two images into html5 canvas

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

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