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

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>

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

How to add class to element on canvas?

I would like to add a class in my FirstImg in my code so I can modify it in my CSS but it's not working :
onImageFetch = () =>
{
const imageFirst = 'myfirstimg.jpg';
const imgSecond = 'mysecondimg.jpg';
const canvas = this.canvas;
const img = new Image();
const secondImg = new Image();
img.height = 400;
img.width = 400;
img.padding = 10;
img.classList.add('image-canvas'); // Here I want to add my class
secondImg.padding = 10;
img.onload = () =>
{
let ctx = canvas.getContext('2d');
const width = img.width;
const height = img.height;
ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, width, height);
ctx.drawImage(secondImg, 260, 30, 70, 25);
};
img.src = imageFirst;
secondImg.src = imgSecond;
}
and my CSS will be something like this :
.myNewClassCreate {
height: 50px;
width: 50px;
}
I tried img.className = 'myclass'; and img.class = 'myclass'; but it's not working.
Need some help, thanks you !

JavaScript canvas.drawImage alpha loss

Pretty new to JavaScript.
I'm building a site that compares the template image with the user's input and builds some image processing directives. The template image is stored in the site's folder.
$(function() {
$("#btnDirective").click(generateEmoteDirectiveFile);
});
function generateEmoteDirectiveFile() {
getImageData('imgs/templates/human.png');
}
function getImageData(source) {
var image = new Image();
image.onload = function () {
var canvas = document.createElement('canvas');
canvas.width = this.naturalWidth;
canvas.height = this.naturalHeight;
var ctx = canvas.getContext('2d');
ctx.drawImage(this, 0, 0, canvas.width, canvas.height);
var data = ctx.getImageData(0, 0, canvas.width, canvas.height).data;
for (var px = 0, cx = canvas.width * canvas.height * 4; px < cx; px += 4)
if (data[px+3] != 255 && data[px+3] != 0)
console.log("Alpha: " + data[px+3]);
};
image.src = source;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="scripts/jquery-1.11.3.min.js"></script>
<script src="scripts/script.js"></script>
</head>
<body>
<button id="btnDirective">Generate</button>
</body>
</html>
'imgs/templates/human.png' contains a lot of semitransparent values, that are never fetched:
So you are trying to get the integer values for each pixel where it's alpha value of neither 0 nor 255?
Well, your image has pixels that are either full transparent, or they are solid white/black. So you will have no partially-transparent pixels.
See the image of the chili pepper emoji from Emojipedia that is used below. Around ~6% of its pixels are partially transparent (around the borders).
$(function() {
$('#btnDirective').click(generateEmoteDirectiveFile);
});
function generateEmoteDirectiveFile() {
getImageData('https://i.imgur.com/4LzuX3G.png');
getImageData('https://i.imgur.com/R7g697w.png'); // Using a testable image
}
function getImageData(source) {
var image = new Image();
image.crossOrigin = 'Anonymous'; // This allows Imgur CORS...
image.onload = function() {
var canvas = document.createElement('canvas');
canvas.width = this.naturalWidth;
canvas.height = this.naturalHeight;
document.body.appendChild(canvas); // Add canvas to body...
var ctx = canvas.getContext('2d');
ctx.drawImage(this, 0, 0, canvas.width, canvas.height);
var data = ctx.getImageData(0, 0, canvas.width, canvas.height).data;
var pixels = canvas.width * canvas.height;
var alphaValues = [];
for (var px = 0, cx = pixels * 4; px < cx; px += 4) {
if (data[px + 3] != 255 && data[px + 3] != 0) {
alphaValues.push(data[px + 3]);
}
}
var nonAlphaPixels = (alphaValues.length / pixels * 100).toFixed(2);
console.log('Alpha (' + nonAlphaPixels + '%): ' + alphaValues.join(','));
};
image.src = source;
}
function drawPartialPixels(imageData) {
}
body { background: #444; }
#btnDirective { display: block; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="btnDirective">Generate</button>
Here is an example of drawing only the partial pixels.
$(function() {
$('#btnDirective').click(generateEmoteDirectiveFile);
});
function generateEmoteDirectiveFile() {
getImageData('https://i.imgur.com/R7g697w.png', onImageLoad);
}
function getImageData(source, onLoadFn) {
var image = new Image();
image.src = source;
image.crossOrigin = 'Anonymous'; // This allows Imgur CORS...
image.onload = function() {
onLoadFn(this);
};
}
function onImageLoad(image) {
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
canvas.width = image.naturalWidth;
canvas.height = image.naturalHeight;
ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
var pixels = canvas.width * canvas.height;
for (var px = 0, cx = pixels * 4; px < cx; px += 4) {
var partialAlpha = imageData.data[px + 3] != 255 && imageData.data[px + 3] != 0;
imageData.data[px + 0] = partialAlpha ? 255 : 0;
imageData.data[px + 1] = partialAlpha ? 0 : 0;
imageData.data[px + 2] = partialAlpha ? 0 : 0;
imageData.data[px + 3] = partialAlpha ? 255 : 0;
}
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.putImageData(imageData, 0, 0);
document.body.appendChild(canvas); // Add canvas to body...
}
body { background: #444; }
#btnDirective { display: block; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="btnDirective">Generate</button>

Is it possible to show / hide part of canvas image like Image Sprite?

Is it possible to show / hide part of canvas image like Image Sprite ?
Example Case:
I have a canvas of 200 X 200 dimension.
On One button click i want to show part of canvas from point (100, 100) to (120, 120).
On another i want to show entire canvas.
Any help in how to do this?
As sprite are usually shown within another element as a background, perhaps hiding the parent element would take care of your problem?
<style>
#sprite {
width: 100px;
height: 100px;
background-image: src(sprite.png);
background-position: 100px 100px;
}
</style>
<script>
var hide = false;
function show() {
if(!hide) {
document.getElementById("sprite").style.width="200px";
hide = true;
}
else {
document.getElementById("sprite").style.width="100px";
hide = false;
}
}
</script>
<div id="button" onclick="show();">button</div>
<div id="sprite"></div>
This is if the sprite's position is 100px to the right. You could also use document.getElementById('#sprite').style.backgroundPosition="200px 200px"; to change position of the sprite background entirely.
You can use the clipping form of drawImage to display your desired portion of the full image:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var img=new Image();
img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/cats.png";
function start(){
ctx.drawImage(img, 0,0,78,86, 0,0,78,86);
document.getElementById('partial').onclick=function(){
ctx.clearRect(0,0,cw,ch);
ctx.drawImage(img, 0,0,78,86, 0,0,78,86);
}
document.getElementById('full').onclick=function(){
ctx.clearRect(0,0,cw,ch);
ctx.drawImage(img, 0,0);
}
}
body{ background-color: ivory; }
#canvas{border:1px solid red;}
<button id='partial'>Show partial canvas</button>
<button id='full'>Show full canvas</button>
<br><canvas id="canvas" width=300 height=300></canvas>
You can clip the image this way.
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var btn = document.getElementById('btn');
var c = 0;
var img = new Image();
img.src = 'http://placehold.it/200/200';
img.onload = function() {
canvas.width = img.width;
canvas.height = img.height;
context.drawImage(img, 0, 0)
}
btn.onclick = function() {
if (c++ % 2 == 0) {
context.clearRect(0, 0, canvas.width, canvas.height);
context.drawImage(img, 100, 100, 20, 20, 100, 100, 20, 20);
btn.value = 'Unclip';
}
else {
context.drawImage(img, 0, 0);
btn.value = 'Clip';
}
}
<input id="btn" type="button" value="Clip" /><br />
<canvas id="canvas"></canvas>
EDIT
When a user clicks on the canvas, you can get the exact co-ordinates of where the event happened and if the co-ordinates lies inside of the middle circle, you can toggle the whole image by using the same clipping method.
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var c = 0;
var img = new Image();
img.src = 'http://s25.postimg.org/cv29exevj/index.png';
img.onload = function() {
canvas.width = img.width;
canvas.height = img.height;
context.drawImage(img, 80, 80, 40, 40, 80, 80, 40, 40);
}
canvas.onclick = function(e) {
var x = e.clientX - canvas.getBoundingClientRect().left;
var y = e.clientY - canvas.getBoundingClientRect().top;
if (x >= 80 && x <= 120 && y >= 80 && y <= 120) {
if (c++ % 2 == 0) {
context.clearRect(0, 0, canvas.width, canvas.height);
context.drawImage(img, 0, 0);
} else {
context.clearRect(0, 0, canvas.width, canvas.height);
context.drawImage(img, 80, 80, 40, 40, 80, 80, 40, 40);
}
}
}
<canvas id="canvas"></canvas>

Loading an image onto a canvas with javaScript

I am currently testing using the <canvas> element to draw all of the backgrounds (I will add effects later to these images later and is the reason I'm not using CSS to load the images). That said, I'm currently having difficulty loading a image on to the canvas. Here is the code:
<html>
<head>
<title>Canvas image testing</title>
<script type="text/javascript">
function Test1() {
var ctx = document.getElementById('canvas');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
//Loading of the home test image - img1
var img1 = new Image();
img1.src = 'img/Home.jpg';
//drawing of the test image - img1
img1.onload = function () {
//draw background image
ctx.drawimage(img1, 0, 0);
//draw a box over the top
ctx.fillStyle = "rgba(200, 0, 0, 0.5)";
ctx.fillRect(0, 0, 500, 500);
};
}
}
</script>
<style type="text/css">
canvas { border: 2px solid black; width: 100%; height: 98%; }
</style>
</head>
<body onload="Test1();">
<canvas id="canvas" width="1280" height="720"></canvas>
</body>
</html>
I think that I'm not loading the image correctly, but I'm not sure.
There are a few things:
drawimage should be drawImage - note the capital i.
Your getElementById is looking for an element with ID of canvas, but it should be test1. canvas is the tag, not the ID.
Replace the canvas variable (e.g. in your canvas.getContext lines) with ctx, since that's the variable you've used to select your canvas element.
Bind your onload handler before you set the src of the image.
So your function should end up like this:
function Test1() {
var ctx = document.getElementById('test1');
if (ctx.getContext) {
ctx = ctx.getContext('2d');
//Loading of the home test image - img1
var img1 = new Image();
//drawing of the test image - img1
img1.onload = function () {
//draw background image
ctx.drawImage(img1, 0, 0);
//draw a box over the top
ctx.fillStyle = "rgba(200, 0, 0, 0.5)";
ctx.fillRect(0, 0, 500, 500);
};
img1.src = 'img/Home.jpg';
}
}
Using newer JavaScript features:
let img = await loadImage("./my/image/path.jpg");
ctx.drawImage(img, 0, 0);
and the loadImage function looks like this:
function loadImage(url) {
return new Promise(r => { let i = new Image(); i.onload = (() => r(i)); i.src = url; });
}
move the onload event listener to before you set the src for the image.
var img1 = new Image();
//drawing of the test image - img1
img1.onload = function () {
//draw background image
ctx.drawImage(img1, 0, 0);
//draw a box over the top
ctx.fillStyle = "rgba(200, 0, 0, 0.5)";
ctx.fillRect(0, 0, 500, 500);
};
img1.src = 'img/Home.jpg';
Assign your local file resource (url) to image source and draw image using context from canvas you want to load. That's it. See code bellow.
var loadImage = function (url, ctx) {
var img = new Image();
img.src = url
img.onload = function () {
ctx.drawImage(img, 0, 0);
}
}
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
var img1 = new Image();
//drawing of the test image - img1
img1.onload = function () {
//draw background image
ctx.drawImage(img1, 0, 0);
//draw a box over the top
ctx.fillStyle = "rgba(200, 0, 0, 0.5)";
ctx.fillRect(0, 0, 500, 500);
};
img1.src = 'img/Home.jpg';
<canvas id="canvas"></canvas>

Categories

Resources