Wait while image is loaded in Javascript - javascript

I have the following problem.
function getBase64Image() {
var svg = //some svg string;
var canvas = document.createElement('canvas');
var mimetype = 'image/png';
canvas.width = 600;
canvas.height = 600;
var timg = new Image(),
ctx = canvas.getContext('2d');
timg.width = 600;
timg.height = 600;
timg.onload = function () {
document.body.appendChild(canvas);
try {
ctx.clearRect(0, 0, 600, 600);
ctx.drawImage(timg, 0, 0);
}
catch (e) {
return false;
}
var strData = canvas.toDataURL(mimetype);
document.body.removeChild(canvas);
img_data = strData;
}
timg.src = 'data:image/svg+xml;base64,' + svg;
}
return img_data;
}
Basically, I want to convert svg to png.
I have svg string, I then load image and draw it with canvas. Then I fetch base64 string for png image.
The problem I encounter is that function getBase64Image exits before image is loaded.
How can I prevent it?
Maybe use deferred or rewrite function?
I Googled, but couldn't find close answers.
Thank you.

You can't change an asynchronous function in a synchronous one.
The simplest solution is to pass a callback :
function fetchBase64Image(callback) {
var svg = //some svg string;
var canvas = document.createElement('canvas');
var mimetype = 'image/png';
canvas.width = 600;
canvas.height = 600;
var timg = new Image(),
ctx = canvas.getContext('2d');
timg.width = 600;
timg.height = 600;
timg.onload = function () {
document.body.appendChild(canvas);
try {
ctx.clearRect(0, 0, 600, 600);
ctx.drawImage(timg, 0, 0);
}
catch (e) {
return false;
}
var strData = canvas.toDataURL(mimetype);
document.body.removeChild(canvas);
img_data = strData;
callback(img_data);
}
timg.src = 'data:image/svg+xml;base64,' + svg;
}
}
And you use it like this :
fetchBase64Image(function(img_data){
// use the image img_data
}):

Related

JSON to PNG Empty picture

Need help with my function to download a PNG from a SVG.
I read many similar post about that but don't succeed to apply to my code.
The image that I download is empty ...
My code :
function downloadCarteJPEG(nom,dpi) {
var svg = document.querySelector("svg");
var svgData = "";
if (typeof window.XMLSerializer != "undefined") {
svgData = (new XMLSerializer()).serializeToString(svg);
} else {
console.error("XMLSerializer undefined");
return;
}
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
var svgSize = svg.getBoundingClientRect();
canvas.width = svgSize.width * dpi / 25.4;
canvas.height = svgSize.height * dpi / 25.4;
var data = btoa(unescape(encodeURIComponent(svgData)));
data = 'data:image/svg+xml;base64,' + data;
var image = document.createElement("img");
image.onload = function() {
ctx.drawImage(image, 0, 0);
var link = document.createElement("a");
link.download = nom;
link.href = canvas.toDataURL("image/png");
document.querySelector("body").appendChild(link);
link.click();
document.querySelector("body").removeChild(link);
};
image.src = data;
console.log("EXIT");
}

Drawing ends up all black

I'm trying to resize an image via HTML canvas, but when I display it, it displays all black.
My code
function onSuccess(imageData) {
var img = new Image();
img.src = imageData;
window.setTimeout(function() {
var maxSize = 200;
var canvas = document.createElement("canvas");
canvas.width = maxSize;
canvas.height = maxSize;
var ctx = canvas.getContext("2d");
ctx.drawImage(img.src, 0, 0, maxSize, maxSize);
dataurl = canvas.toDataURL("image/jpeg");
alert(dataurl);
}, 1000);
}
I'm not exactly sure what it is I'm doing incorrectly. Thanks for the help!

Dynamically add multiple images from input

I have the following code:
var imageLoader = document.getElementById('imageLoader');
var patternLoader = document.getElementById("patternLoader");
var canvas = document.getElementById('imageCanvas');
var ctx = canvas.getContext('2d');
function handleImage(e) {
var reader = new FileReader();
reader.onload = function (event) {
var img = new Image();
img.onload = function () {
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0);
}
img.src = event.target.result;
}
reader.readAsDataURL(e.target.files[0]);
};
imageLoader.addEventListener("change", handleImage, false);
patternLoader.addEventListener("change", handleImage, false);
How can I load one image over another from inputs and not replace them?
I want it to be like that http://i.gyazo.com/85c8c6bdcd2efcdd6a1c1b156000f204.png
Here's a crude way to add images dynamically. Declare an array to keep track on all your images and scale the canvas based on the largest image.
Since I didn't konw what kind of DOM elements the OP used for "imageLoader" and "patternLoader", I simply used an <input>-tag.
Just keep pasting URLs for images to add images to your canvas. The images will be drawn in the order as you add them.
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
var maxWidth = 0;
var maxHeight = 0;
var images = [];
var myInput = document.getElementById("myInput");
myInput.addEventListener('change',handleImage,false);
function handleImage(e) {
var myImage = new Image();
myImage.onload = function () {
if (myImage.width > maxWidth) {
maxWidth = myImage.width;
}
if (myImage.height > maxHeight) {
maxHeight = myImage.height;
}
canvas.width = maxWidth;
canvas.height = maxHeight;
images.push(myImage);
drawImages();
}
myImage.src = e.target.value;
}
function drawImages() {
for (var i = 0; i<images.length; i++) {
ctx.drawImage(images[i],canvas.width/2-images[i].width/2,canvas.height/2-images[i].height/2);
}
}
<input type="text" id="myInput"><br />
<canvas id="canvas"></canvas>

Converting images to base64 within a loop before adding to jspdf - javascript

I have researched issues with the base64 conversion and jspdf function quite a bit. ( PS this is my first question on stackoverflow, please bare with any rookie mistakes ).
All seems to work fine with the below code except that the pdf is generated and saved before the loop where the images are converted to base64 and placed to the document is finished. I added a couple alerts to check timing. Would the solution be to check when the loop is finished, the images placed before continuing with the pdf function? if so, how? please help.
$(document).ready(function(){
$("a#getdoc").click(function(){
var doc = new jsPDF('landscape, in, legal');
var myimages = 'img1.jpg|img2.jpg|img3.png';
var myimgarray = myimages.split('|');
function convertImgToBase64(url, callback, outputFormat){
var canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
return canvas.toDataURL("image/jpeg");
var dataURL = canvas.toDataURL("image/jpeg");
callback(dataURL);
canvas = null;
}
for(var i = 0; i < myimgarray.length; i++)
{
icount.count = i;
var img = new Image();
alert(checkoutimgarray);
img.src = '/Portals/0/repair-images/' + myimgarray[i];
img.onload = function(){
newData = convertImgToBase64(img);
alert(newData);
doc.addImage(newData, 'JPEG', (icount * 100), 10, 70, 15); // would doc be undefined here? out of scope?
};
}
doc.setFontSize(20);
doc.text(100, 20, "This is a test to see if images will show");
doc.save('My_file.pdf');
});
});
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
function convertImgToBase64(img, outputFormat){
// clear canvas
canvas.width = img.width;
canvas.height = img.height;
// draw image
ctx.drawImage(img, 0, 0);
// get data url of output format or defaults to jpeg if not set
return canvas.toDataURL("image/" + (outputFormat || "jpeg"));
}
var images = [];
for(var i = 0; i < myimgarray.length; i++) {
var img = new Image();
img.onload = function() {
images.push({
base64: convertImgToBase64(this),
width: this.width,
height: this.height
});
// all images loaded
if(images.length === myimgarray.length) {
for(var j = 0; j < images.length; j++) {
doc.addImage(images[j].base64, 'JPEG', (j * 100), 10, 70, 15);
}
doc.setFontSize(20);
doc.text(100, 20, "This is a test to see if images will show");
doc.save('My_file.pdf');
}
};
img.src = '/Portals/0/repair-images/' + myimgarray[i];
}

HTML5 video frame capture to bitmap

I got this script:
function capture(video, scaleFactor) {
if(scaleFactor == null){
scaleFactor = 1;
}
var w = video.videoWidth * scaleFactor;
var h = video.videoHeight * scaleFactor;
var canvas = document.createElement('canvas');
canvas.width = w;
canvas.height = h;
var ctx = canvas.getContext('2d');
ctx.drawImage(video, 0, 0, w, h);
return canvas;
}
function shoot(){
var video = document.getElementById(videoId);
var output = document.getElementById('output');
var canvas = capture(video, scaleFactor);
canvas.onclick = function(){
window.open(this.toDataURL());
};
snapshots.unshift(canvas);
output.innerHTML = '';
for(var i=0; i<1; i++){
output.appendChild(snapshots[i]);
}
}
What I want to do is export the snapshot to a bitmap image. I read that I could use this line:
canvas.toDataURL('image/jpeg');
But I don't know where to add it.
Any ideas?
ctx.drawImage(video, 0, 0, w, h);
canvas.toDataURL(...)
toDataURL will return you a string which is usually base64 encoded image (file) content. You can display it in image tag by < img src="the string"/>. Or you can use javascript to do whatever you want...
Pass it to window.open
canvas.onclick = function () {
window.open(canvas.toDataURL('image/png'));
};
Full Example : http://www.nihilogic.dk/labs/canvas2image/

Categories