Upload picture to canvas - javascript

I've done a single upload for image and put image to canvas, here is the DEMO. Now, the problem is that when I upload a picture and then I want to upload another one the previous picture still remain underneath.
This is my code:
JS:
var canvas = document.getElementById('main');
var ctx = canvas.getContext('2d');
var fileInput = document.getElementById('fileInputTest');
fileInput.addEventListener('change', imageLoader, false);
function imageLoader() {
var reader = new FileReader();
reader.onload = function(event) {
img = new Image();
img.onload = function() {
var MAX_WIDTH = 150;
var MAX_HEIGHT = 150;
var width = img.width;
var height = img.height;
if (width > height) {
if (width > MAX_WIDTH) {
height *= MAX_WIDTH / width;
width = MAX_WIDTH;
}
} else {
if (height > MAX_HEIGHT) {
width *= MAX_HEIGHT / height;
height = MAX_HEIGHT;
}
}
ctx.drawImage(img, 0, 0, width, height);
}
img.src = reader.result;
}
reader.readAsDataURL(fileInput.files[0]);
}
HTML:
<input type="file" id="fileInputTest" />
<canvas id="main" width="150" height="150"></canvas>
CSS:
#main {
border: 2px dotted black;
border-radius: 5px position: absolute;
}
JSFIDDLE DEMO

Just add this before you draw your image in context.
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(img, 0, 0, width, height);
You just have to clear your canvas area before drawing your image.

Related

How to input an image and use that as the cursor?

I am trying to make a cursor changer, where the user can upload an image, and it will be the cursor anywhere on the document <body>. However it doesn't seem to work. I have tried .append and .appendChild, but it doesn't seem to work. Where have I gone wrong?
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function(e) {
$('#uploaded1').attr('src', e.target.result);
$("#upload-cursor").css("display", "block");
$("#upload-cursor").click(function() {
$("body").css("cursor", "url(" + e.target.result + "), auto");
});
};
reader.readAsDataURL(input.files[0]);
}
}
$("#imgInp").change(function() {
readURL(this);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h5>Upload Cursor</h5>
<form runat="server">
<input type='file' id="imgInp">
<img id="uploaded1" src="#" width="50px" height="50px">
<br>
</form>
<button id="upload-cursor" style="display: none;">Create Cursor</button>
As the above answer, you image size might be big so do resize the Image.
to resize use the File API, then you can process the images with the canvas element.
This Mozilla Hacks blog post walks you through most of the process. For reference here's the assembled source code from the blog post:
// from an input element
var filesToUpload = input.files;
var file = filesToUpload[0];
var img = document.createElement("img");
var reader = new FileReader();
reader.onload = function(e) {img.src = e.target.result}
reader.readAsDataURL(file);
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
var MAX_WIDTH = 800;
var MAX_HEIGHT = 600;
var width = img.width;
var height = img.height;
if (width > height) {
if (width > MAX_WIDTH) {
height *= MAX_WIDTH / width;
width = MAX_WIDTH;
}
}
else {
if (height > MAX_HEIGHT) {
width *= MAX_HEIGHT / height;
height = MAX_HEIGHT;
}
}
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, width, height);
var dataurl = canvas.toDataURL("image/png");
//Post dataurl to the server with AJAX
Resizing before uploading:
HTML5 Pre-resize images before uploading

Reducing size of the image at Client Side in javascript before form submission

Im trying to reduce the size of the image after reading at client side, the javascript code is as below, I'm getting two issues here
1) The image preview is not showing up on the img id "img-upload"
2) The file that is being submitted via form submission "reader.readAsDataURL(input.files[0])" is not the reduced size one.
I did try changing code to move the reader inside the image onload and then pass e.target.files[0] but that didn't work either.
Pls advise how I can resize and then send it via form submission to my backend.
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#img-upload').attr('src', e.target.result);
img.onload = function () {
var MAX_WIDTH = 100;
var MAX_HEIGHT = 100;
var width = img.width;
var height = img.height;
if (width > height) {
if (width > MAX_WIDTH) {
height *= MAX_WIDTH / width;
width = MAX_WIDTH;
}
} else {
if (height > MAX_HEIGHT) {
width *= MAX_HEIGHT / height;
height = MAX_HEIGHT;
}
}
var canvas = document.createElement("canvas");
canvas.width = width;
canvas.height = height;
canvas.getContext("2d").drawImage(this, 0, 0, width, height);
img.src = e.target.result;
$('#img-upload').append(img);
}
}
reader.readAsDataURL(input.files[0]);
}
}
Your code is creating an infinite call to img.onload
because of this
img.src = e.target.result; statement inside onload.
Beside this you are not reading the resized image from the canvas.
You can do this the following way
canvas.toDataURL('image/png');
SNIPPET
var img = $('#img-upload')[0];
var show = $('#show')[0];
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function(e) {
debugger;
$('#img-upload').attr('src', e.target.result);
img.onload = function() {
var MAX_WIDTH = 100;
var MAX_HEIGHT = 100;
var width = img.width;
var height = img.height;
if (width > height) {
if (width > MAX_WIDTH) {
height *= MAX_WIDTH / width;
width = MAX_WIDTH;
}
} else {
if (height > MAX_HEIGHT) {
width *= MAX_HEIGHT / height;
height = MAX_HEIGHT;
}
}
var canvas = document.createElement("canvas");
canvas.width = width;
canvas.height = height;
canvas.getContext("2d").drawImage(this, 0, 0, width, height);
//Causing Infinite Loop in your code
//img.src = e.target.result;
// Get dataURL of resized image from canvas
show.src = canvas.toDataURL('image/png');
}
}
reader.readAsDataURL(input.files[0]);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="file" onchange="readURL(this)">
<img id="img-upload">
<img id="show">

How to center the image inside of canvas in javascript?

I have a problem with centring the image inside of the canvas. Canvas has to be full sized. The whole thing should create a web preloader. Styling image inside of css does not work in this case.
<style> canvas{
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #000000;
z-index: 99; }
</style> <body>
<canvas id="c"><img id="logo" width="800" height="150" src="imgsource" alt="logo"></canvas> <div> web content </div>
<script>
jQuery(window).on('load', function() {
jQuery('#c').delay(7000).fadeOut('slow');
jQuery('body').delay(7000).css({'overflow':'visible'});
})
window.onload = function() {
var c = document.getElementById("c");
var ctx = c.getContext("2d");
var img = document.getElementById("logo");
ctx.drawImage(img, 50, 0);
} </script>
The following only demonstrates the centering of an image inside a canvas with drawImg. Note that the image to the left is from the html <img> element while the other is from the drawImg call.
Outside of stackoverflow you'd have to wait for the image to load before drawing it, but as you also already use .on('load', ...) i assume you are aware of that.
To avoid having two images, create the image element in javascript and don't add it to the document but only use it for rendering.
let canvas = document.getElementById("canvas");
let ctx = canvas.getContext("2d");
let img = document.getElementById("i");
//just to make the area the canvas occupies visible
ctx.fillStyle = 'grey';
ctx.fillRect(0, 0, canvas.width, canvas.height);
//draw the image centered
ctx.drawImage(
img,
canvas.width / 2 - img.width / 2,
canvas.height / 2 - img.height / 2
);
<html>
<body>
<img id="i" src="http://i.imgur.com/kdJicdy.png"/>
<canvas id="canvas" width="320" height="240">Your browser doesn't support canvas</canvas>
</body>
</html>
var canvas = document.getElementById('canvas');
var image = new Image();
image.src = 'http://placehold.it/300x550';
image.onload = function () {
var canvasContext = canvas.getContext('2d');
var wrh = image.width / image.height;
var newWidth = canvas.width;
var newHeight = newWidth / wrh;
if (newHeight > canvas.height) {
newHeight = canvas.height;
newWidth = newHeight * wrh;
}
var xOffset = newWidth < canvas.width ? ((canvas.width - newWidth) / 2) : 0;
var yOffset = newHeight < canvas.height ? ((canvas.height - newHeight) / 2) : 0;
canvasContext.drawImage(image, xOffset, yOffset, newWidth, newHeight);
};
<canvas id="canvas" width="500" height="500" style="border: 1px solid black" />

JS multiselect images and draw them into canvas - sometimes canvas blank or same image drawn

I am using JS and a multi select field.
A user can select multiple images from a folder and then each image should be drawn into a canvas. Each image has a predefined canvas and a predefined input field where then the decoded base64 dataurl is placed in.
The multiselect field:
<input id="bild" multiple="" name="bild" type="file">
In my example there are 3 different canvas elements and 3 different dataurl input fields:
$( "input#bild" ).change(function() {
console.log("multiple");
// from an input element
var filesToUpload = this.files;
//console.log(filesToUpload);
if(typeof this.files[0] !== "undefined") {
console.log("multiple-1");
var img = document.createElement("img");
img.src = window.URL.createObjectURL(this.files[0]);
$( img ).load(function() {
console.log("multiple-1-loaded");
canvas = $("#uploading_canvas_image_1").get(0);
var MAX_WIDTH = 550;
var MAX_HEIGHT = 400;
var width = img.width;
var height = img.height;
if (width > height) {
if (width > MAX_WIDTH) {
height *= MAX_WIDTH / width;
width = MAX_WIDTH;
}
} else {
if (height > MAX_HEIGHT) {
width *= MAX_HEIGHT / height;
height = MAX_HEIGHT;
}
}
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, width, height);
var dataurl = canvas.toDataURL("image/jpg");
$( "#dataurl_image_1" ).val(dataurl);
});
}
if(typeof this.files[1] !== "undefined") {
console.log("multiple-2");
var img = document.createElement("img");
img.src = window.URL.createObjectURL(this.files[1]);
$( img ).load(function() {
console.log("multiple-2-loaded");
canvas = $("#uploading_canvas_image_2").get(0);
var MAX_WIDTH = 550;
var MAX_HEIGHT = 400;
var width = img.width;
var height = img.height;
if (width > height) {
if (width > MAX_WIDTH) {
height *= MAX_WIDTH / width;
width = MAX_WIDTH;
}
} else {
if (height > MAX_HEIGHT) {
width *= MAX_HEIGHT / height;
height = MAX_HEIGHT;
}
}
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, width, height);
var dataurl = canvas.toDataURL("image/jpg");
$( "#dataurl_image_2" ).val(dataurl);
});
}
if(typeof this.files[2] !== "undefined") {
console.log("multiple-3");
var img = document.createElement("img");
img.src = window.URL.createObjectURL(this.files[2]);
$( img ).load(function() {
console.log("multiple-3-loaded");
canvas = $("#uploading_canvas_image_3").get(0);
var MAX_WIDTH = 550;
var MAX_HEIGHT = 400;
var width = img.width;
var height = img.height;
if (width > height) {
if (width > MAX_WIDTH) {
height *= MAX_WIDTH / width;
width = MAX_WIDTH;
}
} else {
if (height > MAX_HEIGHT) {
width *= MAX_HEIGHT / height;
height = MAX_HEIGHT;
}
}
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, width, height);
var dataurl = canvas.toDataURL("image/jpg");
$( "#dataurl_image_3" ).val(dataurl);
});
}
For each image I am checking if it is really there and not undefined. Then it is drawn into the canvas and the corresponding field for dataurl is populated with the dataurl.
The Problem is:
I do not get any errors.
The behaviour is different with different sets of images but its always the same with the same set. For example: I am marking 3 different images in the folder which I want to upload, but always all 3 canvas show the same image (3rd) one also all 3 dataurls are the same.
Sometimes some canvas are blank.
Sometimes it works
It seems like a general problem, but I havent managed to locate why this happens. My guess is it maybe has something to do with the onload function for the image and that the dataurl is created in the same steps. The dataurl itself is insanly long. I am looking at this atm. Maybe someone here has an idea.
I found the issue. The img was causing these problems. Because I always used the same img, eventhough it is in the if condition block. It seems that the function itself is stronger then the if condition?
I had to create a new img variable for every image selected, which means I needed this for image 1:
var img1 = document.createElement("img");
img1.src = window.URL.createObjectURL(this.files[0]);
$( img1 ).load(function() {
//...
ctx.drawImage(img1, 0, 0, width, height);
});
For image 2:
var img2 = document.createElement("img");
img2.src = window.URL.createObjectURL(this.files[1]);
$( img2 ).load(function() {
//...
ctx.drawImage(img2, 0, 0, width, height);
});
For image 3:
var img3 = document.createElement("img");
img3.src = window.URL.createObjectURL(this.files[2]);
$( img3 ).load(function() {
//...
ctx.drawImage(img3, 0, 0, width, height);
});

Show resized Base64 output of an image

I'm trying hard to accomplish and understand the following 'monstercode' that I wrote. Basically, this function should fire when the File input dialog (HTML) was fired. But the code goes well only a few lines. It loads the image, and then in the first alert() it shows me the base64 of the original image, but then, later in the code, when the actual image should be loaded in a canvas, it returns (in another alert()) height 0, probably meaning that the image wasn't loaded correctly or at all.
The HTML input form (simplified) looks like this:
<input type='File' accept='image/*' onChange='changeBtn(this);' />
And the function below:
function changeBtn(elem) {
selfile = document.getElementById(elem.id);
if ('files' in selfile) {
var file = selfile.files[0];
if ('name' in file) {
str1 = file.name;
}
if ('size' in file) {
str1 += ' (' + ((file.size / 1024) / 1024).toFixed(2) + 'MB)';
}
document.getElementById("label_" + elem.id).innerHTML = str1;
var FR= new FileReader();
var img = document.createElement("img");
FR.onload = function(e) {
img.src = e.target.result;
alert(e.target.result); // Returns B64 of the original image
};
FR.readAsDataURL(file);
var canvas = document.createElement('canvas');
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
var MAX_WIDTH = 800;
var MAX_HEIGHT = 600;
var width = img.width;
var height = img.height;
alert(height); // Returns 0
if (width > height) {
if (width > MAX_WIDTH) {
height *= MAX_WIDTH / width;
width = MAX_WIDTH;
}
} else {
if (height > MAX_HEIGHT) {
width *= MAX_HEIGHT / height;
height = MAX_HEIGHT;
}
}
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, width, height);
var dataurl = canvas.toDataURL("image/png");
alert(dataurl); // Returns only "data; " and nothing more
}
}
Thanks in advance for any help. Seems quite simple, but I don't get it. I rewrote the code at least 3 times, but I get always the same result.
Figured it out!
I was calling FR.readAsDataURL(file); before loading the image into it, leading it to load an undefined file.
If we look at following code that has failed:
var FR= new FileReader();
var img = document.createElement("img");
FR.onload = function(e) {
img.src = e.target.result;
alert(e.target.result); // Returns B64 of the original image
};
FR.readAsDataURL(file);
we now know why. First var FR= new FileReader(); is called, then FR.readAsDataURL(file); and then, at last, when the onload fires: img.src = e.target.result;. That's the wrong order. The right order is:
function changeBtn(elem) {
selfile = document.getElementById(elem.id);
if ('files' in selfile) {
var file = selfile.files[0];
if ('name' in file) {
str1 = file.name;
}
if ('size' in file) {
str1 += ' (' + ((file.size / 1024) / 1024).toFixed(2) + 'MB)';
}
document.getElementById("label_" + elem.id).innerHTML = str1;
var FR= new FileReader();
FR.readAsDataURL(file);
var img = document.createElement("img");
FR.onload = function(e) {
img.src = e.target.result;
alert(e.target.result);
var canvas = document.createElement('canvas');
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
var MAX_WIDTH = 800;
var MAX_HEIGHT = 600;
var width = img.width;
var height = img.height;
alert(height);
if (width > height) {
if (width > MAX_WIDTH) {
height *= MAX_WIDTH / width;
width = MAX_WIDTH;
}
} else {
if (height > MAX_HEIGHT) {
width *= MAX_HEIGHT / height;
height = MAX_HEIGHT;
}
}
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, width, height);
var dataurl = canvas.toDataURL("image/png");
alert(dataurl);
};
}
}

Categories

Resources