Canvas Layers (Z Index) - javascript

I understand that Canvas is as ink dries and each item that is draw is on top.
I'm having a little problem, I have a list of sources of background images
var sources = {
bg: 'images/room-1/bg.png',
rightWall: 'images/room-1/wall-right.png',
leftWall: 'images/room-1/wall-left.png',
beam: 'images/room-1/beam-left.png',
sofa: 'images/room-1/sofa.png'
};
loadImages(sources, function(images) {
context.drawImage(images.bg, 0, 0, 760, 500);
context.drawImage(images.rightWall, 714, 0, 46, 392);
context.drawImage(images.leftWall, 0, 160, 194,322);
context.drawImage(images.beam, 0, 45, 143,110);
context.drawImage(images.sofa, 194, 280, 436,140);
});
This is fine and they order how I like.
My issue is I have an image upload for a user to upload their image into the Canvas.
I am just using an upload box to test the theory, but the idea is the user will upload their image, crop, scale it, using JQuery / PHP and this saves the image. I will then grab this manipulated URL and pull this in, however the problem is that the Canvas is loaded so when i upload an image, it goes on top off the sources image.
I do not want to use multiple Canvas as I need to save this canvas as an image as a whole.
var imageLoader = document.getElementById('imageLoader');
imageLoader.addEventListener('change', handleImage, false);
function handleImage(e){
var reader = new FileReader();
reader.onload = function(event){
var img = new Image();
img.onload = function(){
canvas.width = 760;
canvas.height = 300;
}
img.src = event.target.result;
img.onload = function(){
context.drawImage(img, 0, 0);
};
}
reader.readAsDataURL(e.target.files[0]);
}

Canvas does not have layers.
But you can still get 1 final image with both your background and your user's scaled/rotated foreground.
Since you want to let the user rotate/scale their image but you don't want to affect the background, you will need 2 canvases -- a background canvas and a user canvas.
// HTML
<div id="container">
<canvas id="background" class="subcanvs" width=760 height=300></canvas>
<canvas id="canvas" class="subcanvs" width=760 height=300></canvas>
</div>
// CSS
#container{
position:relative;
border:1px solid blue;
width:760px;
height:300px;
}
.subcanvs{
position:absolute;
}
// JavaScript
// a background canvas
var background=document.getElementById("background");
var bkCtx=background.getContext("2d");
// a foreground canvas the user can rotate/scale
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
Then when the user is done rotating/scaling, drawImage the users canvas to the background canvas.
// combine the users finished canvas with the background canvas
bkCtx.drawImage(canvas,0,0);
// and save the background canvas (now it's combined) as an image
var imageURL=background.toDataURL();

Related

Add white spaces to image Javascript

is there a way to add white spaces to an image in javascript ?
I this the image 1 and I want to edit or create a new image, to add white spaces and the result would be the image 2.
The following code achieves this task. Basically, we create a canvas and set it to the size of the desired output. We then fill it with white before drawing the original image at (0,250) This centers the image (I should have done this with code, but instead looked at your output image in an image editor. (OutputHeight-InputHeight)/2 = Y offset to draw image at.
Since you're not actually adding any detail, it's possible this isn't the best way to go about what you're trying to achieve. It's possible that you should use margin/padding to expand the room the image appears to occupy.
window.addEventListener('load', onLoaded, false);
function onLoaded(evt)
{
let img = document.querySelector('img');
let canvas = document.querySelector('#output');
let ctx = canvas.getContext('2d');
ctx.fillStyle = '#fff';
ctx.fillRect(0,0,759,759);
ctx.drawImage(img, 0, 250);
}
body{
background-color: #ddd;
}
<img src='https://i.stack.imgur.com/bN5hp.jpg'/>
<hr>
<canvas id='output' width=760 height=760/></canvas>
You can do it using the canvas object.. if you have the image for instance
<img src="some.jpeg" id="myImg">
You can copy it to a new canvas and play with the drawImage properties
var img = document.getElementById('myImg');
var canvas = document.createElement('canvas');
canvas.width = img.width; // add here the extra width you want
canvas.height = img.height; // add here the extra height you want
canvas.getContext('2d').drawImage(img, 0, 0, img.width, img.height); // play here with the position, 0, 0 are the top x,y axis
Here is the link to mozilla documentation:
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/drawImage

Creating image from two other images using javascript [duplicate]

I am wondering if there is a way to combine multiple images into a single image using only JavaScript. Is this something that Canvas will be able to do. The effect can be done with positing, but can you combine them into a single image for download?
Update Oct 1, 2008:
Thanks for the advice, I was helping someone work on a js/css only site, with jQuery and they were looking to have some MacOS dock-like image effects with multiple images that overlay each other. The solution we came up with was just absolute positioning, and using the effect on a parent <div> relatively positioned. It would have been much easier to combine the images and create the effect on that single image.
It then got me thinking about online image editors like Picnik and wondering if there could be a browser based image editor with photoshop capabilities written only in javascript. I guess that is not a possibility, maybe in the future?
I know this is an old question and the OP found a workaround solution, but this will work if the images and canvas are already part of the HTML page.
<img id="img1" src="imgfile1.png">
<img id="img2" src="imgfile2.png">
<canvas id="canvas"></canvas>
<script type="text/javascript">
var img1 = document.getElementById('img1');
var img2 = document.getElementById('img2');
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
canvas.width = img1.width;
canvas.height = img1.height;
context.globalAlpha = 1.0;
context.drawImage(img1, 0, 0);
context.globalAlpha = 0.5; //Remove if pngs have alpha
context.drawImage(img2, 0, 0);
</script>
Or, if you want to load the images on the fly:
<canvas id="canvas"></canvas>
<script type="text/javascript">
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var img1 = new Image();
var img2 = new Image();
img1.onload = function() {
canvas.width = img1.width;
canvas.height = img1.height;
img2.src = 'imgfile2.png';
};
img2.onload = function() {
context.globalAlpha = 1.0;
context.drawImage(img1, 0, 0);
context.globalAlpha = 0.5; //Remove if pngs have alpha
context.drawImage(img2, 0, 0);
};
img1.src = 'imgfile1.png';
</script>
MarvinJ provides the method combineByAlpha() in which combines multiple images using its alpha channel. Therefore, you just need to have your images in a format that supports transparency, like PNG, and use that method, as follow:
Marvin.combineByAlpha(image, imageOver, imageOutput, x, y);
image1:
image2:
image3:
Result:
Runnable Example:
var canvas = document.getElementById("canvas");
image1 = new MarvinImage();
image1.load("https://i.imgur.com/ChdMiH7.jpg", imageLoaded);
image2 = new MarvinImage();
image2.load("https://i.imgur.com/h3HBUBt.png", imageLoaded);
image3 = new MarvinImage();
image3.load("https://i.imgur.com/UoISVdT.png", imageLoaded);
var loaded=0;
function imageLoaded(){
if(++loaded == 3){
var image = new MarvinImage(image1.getWidth(), image1.getHeight());
Marvin.combineByAlpha(image1, image2, image, 0, 0);
Marvin.combineByAlpha(image, image3, image, 190, 120);
image.draw(canvas);
}
}
<script src="https://www.marvinj.org/releases/marvinj-0.8.js"></script>
<canvas id="canvas" width="450" height="297"></canvas>
I don't think you can or would want to do this with client side javascript ("combing them into a single image for download"), because it's running on the client: even if you could combine them into a single image file on the client, at that point you've already downloaded all of the individual images, so the merge is pointless.

Image is not filling full canvas space

I am working on HTML5 application for mobile. I am using a canvas element and file upload element. Whenever user hit this file upload element from mobile. He sees two options.
Choose existing photo
Take new photo
If he choose existing photo, this is fixed well in my canvas but if he clicks new photo, it does not fit into canvas. Width is fine but height of click image shown in canvas in not more than 50px.
I am facing this issue only in iPhone.
HTML
<canvas id="myCanvas" width="270" height="300"></canvas>
<input type="file" id="uploadImage" name="upload" value="Upload" onchange="PreviewImage();" />
Javascript
function PreviewImage() {
var oFReader = new FileReader();
oFReader.readAsDataURL(document.getElementById("uploadImage").files[0]);
oFReader.onload = function (oFREvent) {
var canvas = document.getElementById('myCanvas');
ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, 270, 300);
imageUrl = oFREvent.target.result;
var base_image = new Image();
base_image.src = imageUrl;
base_image.onload = function () {
ctx.drawImage(base_image, 0, 0, 270, 300);
}
};
}
I have searched many sites but could not find solution of this issue. Any help?
Attachment
Find this image to see the demo image.

HTML5/ Javascript - Stretch image source

Hi I'm getting image from webcam and I save it on canvas, what I want to do is to stretch it by x and y cooridnates keeping same img dimensions, what I mean is, this is the original webcam picture:
and this is how I wanna it to be when stretched:
<canvas id="canvas" width="640" height="480" style="border:1px solid #d3d3d3;"></canvas>
this is the piece of code that shows source image to <img> element in html , so I have to stretch source image before to show it in html
function snap() {
if (localMediaStream) {
ctx.drawImage(video, 0, 0);
var oImg=document.createElement("img");
oImg.setAttribute('src', canvas.toDataURL());
oImg.setAttribute('alt', 'na');
oImg.setAttribute('width', '1300');
oImg.setAttribute('height', '1300');
var img = document.body.appendChild(oImg);
return img;
}
}
any idea on how to stretch the canvas.toDataUrL() source by x and y coordinates and return it stretched to the the src <img> element?
The real problem imo is how to stretch image without altering width
and height (as shown via example photos above), is this possible?
You can use the extended properties on context.drawImage that allow scaling/positioning.
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var img=new Image();
img.onload=function(){
var w=img.width;
var h=img.height;
canvas.width=w; // set the canvas size to the original image size
canvas.height=h;
ctx.drawImage(img,
0,0,w,h, // start with the image at original size
-w/4,0,w*1.25,h // widen the original image by 1.25X
// and start drawing 1/4th off the left edge of the canvas
);
}
img.src="temp18.png";

Can you combine multiple images into a single one using JavaScript?

I am wondering if there is a way to combine multiple images into a single image using only JavaScript. Is this something that Canvas will be able to do. The effect can be done with positing, but can you combine them into a single image for download?
Update Oct 1, 2008:
Thanks for the advice, I was helping someone work on a js/css only site, with jQuery and they were looking to have some MacOS dock-like image effects with multiple images that overlay each other. The solution we came up with was just absolute positioning, and using the effect on a parent <div> relatively positioned. It would have been much easier to combine the images and create the effect on that single image.
It then got me thinking about online image editors like Picnik and wondering if there could be a browser based image editor with photoshop capabilities written only in javascript. I guess that is not a possibility, maybe in the future?
I know this is an old question and the OP found a workaround solution, but this will work if the images and canvas are already part of the HTML page.
<img id="img1" src="imgfile1.png">
<img id="img2" src="imgfile2.png">
<canvas id="canvas"></canvas>
<script type="text/javascript">
var img1 = document.getElementById('img1');
var img2 = document.getElementById('img2');
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
canvas.width = img1.width;
canvas.height = img1.height;
context.globalAlpha = 1.0;
context.drawImage(img1, 0, 0);
context.globalAlpha = 0.5; //Remove if pngs have alpha
context.drawImage(img2, 0, 0);
</script>
Or, if you want to load the images on the fly:
<canvas id="canvas"></canvas>
<script type="text/javascript">
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var img1 = new Image();
var img2 = new Image();
img1.onload = function() {
canvas.width = img1.width;
canvas.height = img1.height;
img2.src = 'imgfile2.png';
};
img2.onload = function() {
context.globalAlpha = 1.0;
context.drawImage(img1, 0, 0);
context.globalAlpha = 0.5; //Remove if pngs have alpha
context.drawImage(img2, 0, 0);
};
img1.src = 'imgfile1.png';
</script>
MarvinJ provides the method combineByAlpha() in which combines multiple images using its alpha channel. Therefore, you just need to have your images in a format that supports transparency, like PNG, and use that method, as follow:
Marvin.combineByAlpha(image, imageOver, imageOutput, x, y);
image1:
image2:
image3:
Result:
Runnable Example:
var canvas = document.getElementById("canvas");
image1 = new MarvinImage();
image1.load("https://i.imgur.com/ChdMiH7.jpg", imageLoaded);
image2 = new MarvinImage();
image2.load("https://i.imgur.com/h3HBUBt.png", imageLoaded);
image3 = new MarvinImage();
image3.load("https://i.imgur.com/UoISVdT.png", imageLoaded);
var loaded=0;
function imageLoaded(){
if(++loaded == 3){
var image = new MarvinImage(image1.getWidth(), image1.getHeight());
Marvin.combineByAlpha(image1, image2, image, 0, 0);
Marvin.combineByAlpha(image, image3, image, 190, 120);
image.draw(canvas);
}
}
<script src="https://www.marvinj.org/releases/marvinj-0.8.js"></script>
<canvas id="canvas" width="450" height="297"></canvas>
I don't think you can or would want to do this with client side javascript ("combing them into a single image for download"), because it's running on the client: even if you could combine them into a single image file on the client, at that point you've already downloaded all of the individual images, so the merge is pointless.

Categories