I have 2 canvas, canvas1 and canvas2. Both work well, but I want to mix them to export as image. Overlay css based do not work as it prints 2 images. Any point to start? thank you.
<canvas id="canvas1" style="position:relative; float:left;border:1px solid #000 " width="547" height="154">
</canvas>
<canvas id="canvas2" style="z-index: 1; position:absolute; float:left;" width="547" height="500">
</canvas>
Well, there are a few ways to go about this, and what do you mean by mix?
If you simply want to overlay canvas2 over canvas1, but don't want to alter either original canvas, you can send their data to another canvas, and then get that data.
method to follow:
draw canvas1 to canvas3
draw canvas2 to canvas3
get canvas3 image
working javascript:
// Make all the canvas and context variables */
var c1 = document.getElementById('c1');
var c2 = document.getElementById('c2');
var c3 = document.getElementById('c3');
var c4 = document.getElementById('c4');
var ctx1 = c1.getContext('2d');
var ctx2 = c2.getContext('2d');
var ctx3 = c3.getContext('2d');
var ctx4 = c4.getContext('2d');
/* */
// Draw square on canvas 1
ctx1.fillRect(0,0,50,50);
// Draw offset square on canvas 2
ctx2.fillRect(25,25,50,50);
// Make third image and onload function
var img3 = new Image();
img3.onload = function(){
// Draw this image to canvas 4 so that we know it worked
ctx4.drawImage(this,0,0);
}
// So we know when both have loaded
var imagesLoaded = 0;
function draw(){
// increment number loaded
imagesLoaded++;
// draw this image to canvas 3
ctx3.drawImage(this,0,0);
// if the have both loaded, then...
if (imagesLoaded == 2){
// set third image's src to the canvas 3 image
img3.src = c3.toDataURL();
}
}
// First image
var img1 = new Image();
// So it will draw on canvas 3
img1.onload = draw;
// Set the src to canvas 1's image
img1.src = c1.toDataURL();
// Second image
var img2 = new Image();
// So it will draw on canvas 3
img2.onload = draw;
// Set the src to canvas 2's image
img2.src = c2.toDataURL();
Working example here.
However, if that wasn't what you were looking for, I am sorry.
Related
I cannot get my image to display in an HTML canvas using drawImage(). I know the filepath is correct because the image displays just fine when I disable display: none;
I know this can occur when you attempt to draw an image before it is loaded, which you can avoid by using the onload property.
Here is the relevant HTML.
<canvas id='gameScreen'></canvas>
<img id="imgBall"src="assets/images/ball2.png" alt="ball">
<script type="module"src="src/index.js"></script>
Here is the relevant Javascript.
// CANVAS SETUP
let canvas = document.getElementById("gameScreen");
canvas.width = 800;
canvas.height = 600;
let ctx = canvas.getContext("2d");
// DISPLAY BALL
let imgBall = document.getElementById('imgBall');
imgBall.onload = function() {
console.log(imgBall.src + ' successfully loaded');
ctx.drawImage(imgBall, 10, 10);
}
imgBall.onerror = function() {
console.log(imgBall.src + ' failed to load');
}
What makes this so confusing to me is that I'm not getting any console messages from imgBall.onload, or from imgBall.onerror.
I'm pretty new to Javascript and canvas, so I apologize if the answer is extremely obvious.
To fix the issue I am dynamically creating an image tag and then giving it a src AFTER I have added the event handlers for error and onload.
This makes me think that the issue is due to the image loading BEFORE your script tag had a chance to add the event listeners to the img tag.
// CANVAS SETUP
let canvas = document.getElementById("gameScreen");
canvas.width = 800;
canvas.height = 600;
let ctx = canvas.getContext("2d");
// DISPLAY BALL
const imgBall = document.createElement("img");
imgBall.onload = function() {
console.log(imgBall.src + ' successfully loaded');
ctx.drawImage(fitImageOntoCanvas(imgBall,25,25), 10, 10);
}
imgBall.onerror = function() {
console.log(imgBall.src + ' failed to load');
}
imgBall.src = "https://pngimg.com/uploads/football/football_PNG52737.png"
// need to resize because my ball image is huge
// thanks #markE https://stackoverflow.com/questions/38664890/resize-images-with-canvas-before-uploading
function fitImageOntoCanvas(img,MAX_WIDTH,MAX_HEIGHT){
// calculate the scaling factor to resize new image to
// fit MAX dimensions without overflow
var scalingFactor=Math.min((MAX_WIDTH/img.width),(MAX_HEIGHT/img.height))
// calc the resized img dimensions
var iw=img.width*scalingFactor;
var ih=img.height*scalingFactor;
// create a new canvas
var c=document.createElement('canvas');
var ctx=c.getContext('2d');
// resize the canvas to the new dimensions
c.width=iw;
c.height=ih;
// scale & draw the image onto the canvas
ctx.drawImage(img,0,0,iw,ih);
// return the new canvas with the resized image
return(c);
}
<canvas id="gameScreen" height="500" width="500"></canvas>
I want to change the opacity of an image to make it transparent and loads that image over another image in canvas as I don't want to use any other tool to change opacity of first image. To change opacity of an image loaded in canvas
var imgObject=new Image();
imgObject.src="myImage.jpg";
// getting context of canvas
var ctx=document.getElementById("myCanvas").getContext("2d");
// global transparency applied on canvas context..
ctx.globalAlpha=0.5;
imgObject.onload=function(){
ctx.drawImage(imgObject,0,0);
}
Is there any way to save transparent image (of canvas) and then use it to load it in new canvas on another image.
I don't know how to change opacity of image in HTML but you can change the opacity of context drawn on canvas element by setting globalALphaalALpha value:
var canvas = document.getElementById("myCanvas");
var ctx1 = canvas.getContext('2d');
var img1 = new Image();
img1.src = "img1.png";
// drawing first image on canvas..
img1.onload = function(){
ctx1.drawImage(img1,0,0,canvas.width,canvas.height);
};
var clonedCanvas = canvas.cloneNode(true);
var ctx2 = clonedCanvas.getContext('2d');
var img2 = new Image();
ctx2.globalAlpha = 0.4;
img2.src = "img2.jpg";
img2.onload = function(){
ctx2.drawImage(img2,0,0);
// copying clonedCanvas to myCanvas.....
ctx1.drawImage(clonedCanvas,0,0);
};
As starting point I have a image on my canvas:
var canvas = $('canvas')[0];
var ctx=canvas.getContext("2d");
var img=document.getElementById("scream");
ctx.drawImage(img,0,0,240,297);
Now I would like to add a frame to this Image on the same canvas. For this:
I first replace the image with the Frame.
Next I try to copy the old canvas content inside of this frame
I try to do this like that:
var frame = document.getElementById("frame");
var ctx = $('canvas')[0].getContext("2d");
var dst = ctx.canvas;
ctx.drawImage(frame,0,0, 240, 297);
ctx.drawImage(dst, 40, 40);
But the code is not working because it copies the frame again to the canvas instead of the image: Here you can see a demo: https://jsfiddle.net/35mxfsv0/
What do I wrong? What do I have to change? Thanks
As you just assign the original canvas to dst, when you draw anything on that canvas, the dst will also changed (because they're pointing to same canvas).
So you have to assign a new canvas to dst, and draw the image from origin to dst, then draw the frame on origin, and last, draw dst's image to origin.
window.onload = function() { // Make it safe that window.onload ensures all images loaded.
var canvas = $('canvas')[0];
var ctx=canvas.getContext("2d");
var img=document.getElementById("scream");
ctx.drawImage(img,0,0,240,297);
//START OF MY CODE
var frame = document.getElementById("frame");
// Comment out as we demo in same scope, ctx is already have what we want.
//var ctx = $('canvas')[0].getContext("2d");
// Create a new canvas, and draw the image on the origin canvas to it.
var dst = document.createElement('canvas');
dst.width = canvas.width;
dst.height = canvas.height;
var dstCtx = dst.getContext('2d');
dstCtx.drawImage(canvas, 0, 0);
// Above is what you suppose the canvas should do.
//var dst = ctx.canvas;
// Draw frame
ctx.drawImage(frame,0,0, 240, 297);
// As your frame is not an opacity one, you have to copy to specific position.
ctx.drawImage(dst, 0, 0, dst.width, dst.height, 10, 10, 220, 277);
}
img{display:none}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<canvas id="myCanvas" width="240" height="297" style="border:1px solid #d3d3d3;">
</canvas>
<img src="http://www.w3schools.com/tags/img_the_scream.jpg" id="scream"/>
<img src="http://www.wpclipart.com/page_frames/picture_frames/wood_picture_frame.jpg" id="frame"/>
However, if you still have the access to that scream image, you can just draw frame first, then draw image on it:
var canvas = $('canvas')[0];
var ctx=canvas.getContext("2d");
var img=document.getElementById("scream");
var frame = document.getElementById("frame");
ctx.drawImage(frame,0,0, 240, 297);
// 10, 10 seems to fit the frame.
ctx.drawImage(img, 10, 10);
Please change id of your html and js file.
I have combined two images and some text using html5 canvas, but I can't seem to position the images the same way I can with the text. With the text I just changed the x and y properties to position it on the canvas, but this does not seem to work with my two images. They are just set at 0, 0 (top left) regardless.
<canvas width="850" height="450" id="canvas"></canvas>
<script>
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var img1 = loadImage('<%= image_url(#entry.picture(:small)) %>', main);
var img2 = loadImage("<%= image_url('overlay.png') %>", main);
var imagesLoaded = 0;
function main() {
imagesLoaded += 1;
if(imagesLoaded == 2) {
// composite now
ctx.drawImage(img1, 0, 0);
ctx.globalAlpha = 1;
ctx.drawImage(img2, 0, 0);
}
}
function loadImage(src, onload) {
var img = new Image();
img.onload = function() {
ctx.drawImage(img, 0, 0);
ctx.font="30px sans-serif";
ctx.fillText("<%= full_name(#entry.user) %>", 60, 435);
ctx.fillStyle="#333333";
};
img.src = src;
return img;
}
</script>
In my head, the line ctx.drawImage(img1, 0, 0,); should position the image when the values of 0 and 0 are changed, but it does not. My Javascript knowledge isn't great, so there is probably something obvious, but I just can't figure it out. Any help would be greatly appreciated.
Thanks.
There are many styles of code used to preload images to insure they are fully loaded before you try to draw them using drawImage:
Here's annotated code and a Demo:
// canvas related variables
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
// put the paths to your images in imageURLs[]
var imageURLs=[];
imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/multple/face1.png");
imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/multple/face2.png");
// the loaded images will be placed in imgs[]
var imgs=[];
var imagesOK=0;
startLoadingAllImages(imagesAreNowLoaded);
// Create a new Image() for each item in imageURLs[]
// When all images are loaded, run the callback (==imagesAreNowLoaded)
function startLoadingAllImages(callback){
// iterate through the imageURLs array and create new images for each
for (var i=0; i<imageURLs.length; i++) {
// create a new image an push it into the imgs[] array
var img = new Image();
imgs.push(img);
// when this image loads, call this img.onload
img.onload = function(){
// this img loaded, increment the image counter
imagesOK++;
// if we've loaded all images, call the callback
if (imagesOK>=imageURLs.length ) {
callback();
}
};
// notify if there's an error
img.onerror=function(){alert("image load failed");}
// set img properties
img.src = imageURLs[i];
}
}
// All the images are now loaded
// Do drawImage & fillText
function imagesAreNowLoaded(){
// the imgs[] array now holds fully loaded images
// the imgs[] are in the same order as imageURLs[]
ctx.font="30px sans-serif";
ctx.fillStyle="#333333";
// drawImage the first image (face1.png) from imgs[0]
// and fillText its label below the image
ctx.drawImage(imgs[0],0,10);
ctx.fillText("face1.png", 0, 135);
// drawImage the first image (face2.png) from imgs[1]
// and fillText its label below the image
ctx.drawImage(imgs[1],200,10);
ctx.fillText("face2.png", 210, 135);
}
body{ background-color: ivory; }
#canvas{border:1px solid red;}
<canvas id="canvas" width=350 height=300></canvas>
I have a background image for a canvas, and added a few basic elements to the canvas. Now I want to save the canvas (in .png), with the background image of the canvas style.
Tried:
var canvas = document.getElementById("mycanvas");
var img = canvas.toDataURL("image/png");
But this doesn't seem to save the background image of the canvas. Is there a way out?
When you want to save the Canvas + background as an image, you will need to do a sequence of events:
Create an in-memory canvas just as big as your normal canvas. Call it can2
ctx2.drawImage(can1, 0, 0) // paint first canvas onto new canvas
ctx.clearRect(0, 0, width, height) // clear first canvas
ctx.drawImage(background, 0, 0) // draw image on first canvas
ctx.drawImage(can2, 0, 0) // draw the (saved) first canvas back to itself
To save an image location, I believe your looking for:
window.location = canvas.canvas.toDataURL('image/png');
The first canvas call is your variable the second is the canvas object.
You should probably rename your variable to something unique.
To set an image in canvas and make that the background requires some more work:
var myCanvas = document.querySelector('myCanvas'),
img = document.createElement('img'),
ctx = myCanvas.getContext ? myCanvas.getContext('2d') : null;
myCanvas.width = window.innerWidth;
myCanvas.height = window.innerHeight;
img.onload = function () {
ctx.drawImage(img, 0, 0, myCanvas.width, myCanvas.height);
};
img.src = 'image.png';
updated to redraw the image.