Clear HTML Canvas and Re-Upload an Element in the Same Function - javascript

I'm creating a web-based application which allows users to upload an image and then add logos and text.
Obviously, if they need to change the logo it will be necessary for them to clear the canvas and add the logo again. However, I can't work out how to clear the canvas and re-upload the background image they have already added, to save them from having to upload the background image for a second time too.
The code to upload the background image in the first place is as follows:
document.getElementById('upload').addEventListener('change', doUpload);
function doUpload(e){
var file = e.target.files[0];
if(file){
var reader = new FileReader();
reader.onload = function loadBg(event){
canvasLoadImage(event.target.result);
}
reader.readAsDataURL(file);
}
}
function canvasLoadImage(imgData){
var img = new Image();
img.src = imgData;
img.onload = function drawBg(){
context.drawImage(img, 0, 0, 1280, img.height * (1280/img.width));
}
}
The code I'm using to clear the canvas is as follows:
document.getElementById('clear').addEventListener('click', function() {
context.clearRect(0, 0, canvas.width, canvas.height);
}, false);
Does anyone know how I might re-add the image a user has already uploaded as part of the same function, and without them having to upload it for a second time?

you may save the data in a global variable and reuse it as a result of the cancellation of the canvas. For example:
var oData = null;
...
function canvasLoadImage(imgData){
var img = new Image();
img.src = imgData;
oData = imgData;
img.onload = function drawBg(){
var c = document.getElementById("myCanvas");
var context = c.getContext("2d");
context.drawImage(img, 0, 0, 1280, img.height * (1280/img.width));
}
}
...
document.getElementById('clear').addEventListener('click', function() {
var c = document.getElementById("myCanvas");
var context = c.getContext("2d");
context.clearRect(0, 0, c.width, c.height);
var img = new Image();
img.src = oData;
context.drawImage(img, 0, 0, 1280, img.height * (1280/img.width));
}, false);

Related

Resize a current canvas image after one has already been created

I'm trying to create a smaller thumbnail of an image on a canvas.
The thumbnail size I'd like is 200 x 200
According to the documentation it should be as easy as drawImage(img, 0, 0, 200, 200) but I get the same results here is my code:
_canvas = document.createElement('canvas'),
ctx = _canvas.getContext("2d"),
img = new Image();
img.onload = function() {
ctx.drawImage(this, 0, 0, 1200, 600);
var dataURL = _canvas.toDataURL();
// The above creates the first image
//Then while I'm still in the load method I attempt to save another size:
ctx.drawImage(this,0,0,300,300);
var dataThumbURL = _canvas.toDataURL();
}
I save both dataURL and dataThumbURL to the server and both images are the same size.
My assumption is ctx.drawImage could be repeated with just a different size. Any idea how I can achieve this?
The width and height parameters of the drawImage() method do not alter the dimensions of the canvas you draw onto. So if your source image is bigger than the canvas it will simply be cropped.
To have snapshots of different sizes, you need to change the dimensions of the canvas to the desired size prior calling drawImage().
Here's an example:
let image = new Image();
let _canvas = document.createElement('canvas');
let ctx = _canvas.getContext("2d");
image.crossOrigin = "";
image.onload = function() {
let img, dataURL;
_canvas.width = 200;
_canvas.height = 150;
ctx.drawImage(this, 0, 0, _canvas.width, _canvas.height);
dataURL = _canvas.toDataURL();
img = new Image();
document.body.appendChild(img);
img.src = dataURL;
_canvas.width = 40;
_canvas.height = 30;
ctx.drawImage(this, 0, 0, _canvas.width, _canvas.height);
dataURL = _canvas.toDataURL();
img = new Image();
document.body.appendChild(img);
img.src = dataURL;
}
image.src = "https://api.codetabs.com/v1/proxy?quest=https://picsum.photos/id/237/200/300";

pdfmake base64 image callback

I have to work with pdfmake to build a pdf preview within my laravel application. I am a javascript noob and going nuts to generate the dataURI for an image in b. Hope you can help me out.
How can I get that generated base64 into my docdefinition?
function convertImageToDataURL(src, callback, outputFormat) {
// Create an Image object
var img = new Image();
// Add CORS approval to prevent a tainted canvas
img.crossOrigin = 'Anonymous';
img.onload = function() {
var canvas = document.createElement('CANVAS');
var ctx = canvas.getContext('2d');
var dataURL;
canvas.height = this.naturalHeight;
canvas.width = this.naturalWidth;
ctx.drawImage(this, 0, 0);
dataURL = canvas.toDataURL(outputFormat);
callback(dataURL);
// Mark the canvas to be ready for garbage
// collection
canvas = null;
};
img.src = src;
// make sure the load event fires for cached images too
if (img.complete || img.complete === undefined) {
// Flush cache
img.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==';
// Try again
img.src = src;
}
}
convertImageToDataURL(
'{{asset('storage/'.$report->author->enterprises->first()->logo_image)}}',
function(dataUrl) {
// console.log('RESULT:', dataUrl);
// Put dataUrl into DocDefinition here!?!?
// return dataUrl is undefined
}
);`
Okay. As I said: I am a javascript noob. So I changed the script to this one:
function convertImageToDataURL(imgSrc) {
img = new Image();
img.src = imgSrc;
img.crossOrigin = "Anonymous";
var canvas = document.createElement("canvas");
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
var dataURL = canvas.toDataURL("image/jpg");
canvas = null;
return dataURL;
}
It might not be beautyful nor elegant, but it works for me.

getImageData returns white image

I need to read the image data from an image object in javascript.
But my code returns always a blank array (set to 255)
<html>
<header>
</header>
<body>
<input type="file" id="imgfile" onchange="testImageData(event);" />
<canvas id="canvas1" width="640" height="480"></canvas>
<script src="./../scripts/cam.js" ></script>
</body>
</html>
Here is the script
var canvas1 = document.getElementById('canvas1');
var context1 = canvas1.getContext('2d');
function getImageData(image){
/*
returns Uint8ClampedArray object
takes an image obj
*/
var canvas = document.createElement("canvas");
canvas.height = image.height;
canvas.width = image.width;
var ctx = canvas.getContext("2d");
ctx.width = image.width;
ctx.height = image.height;
ctx.drawImage(image,0,0);
return ctx.getImageData(0, 0, ctx.width, ctx.height);
}
function testImageData(event){
var selectedFile = event.target.files[0];
var reader = new FileReader();
var img = new Image();
reader.onload = function(event) {
console.log('onload');
img.src = event.target.result;
img.onload = function(){
context1.drawImage(img, 0,0, img.width, img.height);
var imgData = getImageData(img);
// console.log(imgData);
var data = imgData.data;
for(var i = 0; i<data.length;i+=4){
console.log(data[i],data[i+1],data[i+2],data[i+3]);
}
}
};
In my understanding, the console.log should return me the data in RGBA.
But I'm just getting 255.
console.log output
EDIT:
Okay I found a work around but I don't understand why this is working.
Instead using getImageData, I get the data directly from the drawn context1.
function testImageData(event){
var selectedFile = event.target.files[0];
var reader = new FileReader();
var img = new Image();
reader.onload = function(event) {
console.log('onload');
img.src = event.target.result;
img.onload = function(){
context1.drawImage(img, 0,0, img.width, img.height);
var imgData = context1.getImageData(0,0,img.width,img.height);
var data = imgData.data;
for(var i = 0; i<data.length;i+=4){
console.log(data[i],data[i+1],data[i+2],data[i+3]);
}
}
};
So the problem must lie in creating a new canvas.
You should wait for the image to load img.onload you are waiting for the readers onload event...
you also forget to read the file... missed reader.readAsDataURL
but you don't need the filereader.
window.URL = window.URL || webkitURL
var img = new Image();
img.src = URL.createObjectURL(file)
img.onload = function(){
// put your image on the canvas
}

Canvas DrawImage does not work on IOS Safari

I have a canvas with an id called napkin. When I call the following function it is supposed to draw an image and the napkin canvas onto another canvas in memory. It works on every browser but IOS Safari. The operation does not seem to exceed the IOS memory cap for the canvas. I test this by calling k().toDataURL(). Any ideas?
function k() {
var canvas = document.createElement('canvas');
var napkin = document.getElementById("napkin");
var img = new Image();
img.src = picurl;
var ctx = canvas.getContext("2d");
var imgdata = new Image();
imgdata.src = napkin.toDataURL();
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0);
ctx.globalAlpha = 0.5;
ctx.drawImage(imgdata, 0, 0);
return canvas;
}
You need to wait for the image data to load before using it...
var img = new Image();
img.onload = function(){
// do stuff here with img
};
img.src = picurl;
// not here

Create Canvas from image on javascript

I'm trying to learn manipulate image and canvas in javascript. I'm wondering why we can not do :
var urlimg='http://images.aviary.com/imagesv5/feather_default.jpg';
var can = document.getElementById('canvas');
var ctx = can.getContext('2d');
var img = new Image();
img.onload = function(){
}
img.src =urlimg ;
can.width = img.width;
can.height = img.height;
ctx.drawImage(img, 0, 0, img.width, img.height);
$('#image1').attr('src', img.src);
And we have to do this :
var urlimg='http://images.aviary.com/imagesv5/feather_default.jpg';
var can = document.getElementById('canvas');
var ctx = can.getContext('2d');
var img = new Image();
img.onload = function(){
can.width = img.width;
can.height = img.height;
ctx.drawImage(img, 0, 0, img.width, img.height);
}
img.src =urlimg ;
$('#image1').attr('src', img.src);
Is it due to time of image to load ?
Can I create a canvas from an existing object image ?
Thanks.
Is it due to time of image to load ?
Yes in part, but mostly because image loading is asynchronous so the next lines of code are executed right away while the image is loaded. To let you know an event is raised when it's done.
Can I create a canvas from an existing object image ?
No (not directly), but you can draw the image onto a canvas to initialize it (as you already do):
ctx.drawImage(imageElement, 0, 0, width, height);

Categories

Resources