Convert image to base64 works but bad [duplicate] - javascript

This question already has an answer here:
CanvasContext2D drawImage() issue [onload and CORS]
(1 answer)
Closed 7 years ago.
I want convert a picture to base64. So, in the html i put a img and canvas with display:none
html :
<img style="display:none" id="imgDownload" />
<canvas style="display:none" id="myCanvas" />
and in the controller i do this :
controller :
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var img = document.getElementById("imgDownload");
img.crossOrigin = 'anonymous';
img.src = conf.storeUrl + '/' +$scope.fRoot.name + $scope.getFileWay() + value.name;
console.log(img);
ctx.drawImage(img, img.naturalHeight, img.naturalWidth);
var base64Img = c.toDataURL();
i get a base64 but it's not good...
see an example :
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAACWCAYAAABkW7XSAAAAxUlEQVR4nO3BMQEAAADCoPVPbQhfoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOA1v9QAATX68/0AAAAASUVORK5CYII=
you can test it here.
and i tried giving a height and width to the canvas but the result is that :
data:,
and it's the same thing for différents images, you have a idea?

You're trying to draw the image on the canvas before it has finished loading.
After setting img.src, it takes some time to load the image, so you have to wait until that has happened before you proceed.
You can use img.onload for that:
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var img = document.getElementById("imgDownload");
img.crossOrigin = 'anonymous';
img.onload = function()
{
console.log(img);
ctx.drawImage(img, img.naturalHeight, img.naturalWidth);
var base64Img = c.toDataURL();
};
img.src = conf.storeUrl + '/' +$scope.fRoot.name + $scope.getFileWay() + value.name;

Related

How to draw an image in a canvas

So I was trying to draw animgin a canvas I tried everything but in the console it says img is not a property or something like that I don't remember so can anyone help?
Here's the js
function setupcanvas() {
var canvas = document.querySelector('canvas')
var c = canvas.getContext("2d")
c.beginPath();
var img = new image()
img.src = "flappy_bird_bird.png"
img.onload = function(){
c.drawImage(img, 100, 100)
}
}
Edit
Thx to mhkanfer "sorry if the name is wrong" I fixed it
You were mostly right, though their are a couple of things:
Make sure Image() is capitalized
Make sure your image src file actually exists in that directory
And make sure your canvas has a width and height, if you haven't specified that anywhere, you canvas wont be shown
If you were to revise this, it would look something like:
function setupcanvas() {
var canvas = document.querySelector('canvas')
var c = canvas.getContext("2d")
canvas.width = canvas.height = 200;
var img = new Image()
img.src = "example.png"
img.onload = function(){
c.drawImage(img, 0, 0)
}
}

Base64 image not displaying unless hardcoded or in setTimeout set to 0

Im converting an SVG to a PNG and it's working fine except for some super bizarre behavior that setting the image src to the b64 value only works if you put it in a setTimeout of 0. If you copy the b64 value and hardcode it as the src it also works. Here's the JS:
var testSVG = {
height: 31.987199999999998,
template: '<svg width="19.2" height="31.987199999999998" viewBox="0 0 149.39 248.95" xmlns="http://www.w3.org/2000/svg"><path fill="#c599fe" stroke="#000" stroke-miterlimit="10" stroke-width="5" d="M74.89,236.14c-5.35-26.25-14.78-48.1-26.2-68.35-8.47-15-18.29-28.88-27.37-43.45-3-4.86-5.65-10-8.56-15C6.94,99.2,2.21,87.5,2.51,72.32A68.92,68.92,0,0,1,13.28,35.88,71.31,71.31,0,0,1,63.34,3.32,75.55,75.55,0,0,1,112,12.53a70.38,70.38,0,0,1,24,23.22,68.1,68.1,0,0,1,10.9,36.32A67.12,67.12,0,0,1,144,92.82c-1.8,6-4.69,11-7.26,16.34-5,10.44-11.32,20-17.64,29.57C100.29,167.24,82.62,196.3,74.89,236.14Z"/><circle cx="74.69" cy="72.16" r="25.29"/></svg>',
width: 19.2
}
// Pass in the testSVG object
var convertSVGtoBitmap = function (svgObject) {
if(!svgObject) return null;
var canvas = document.createElement("canvas");
canvas.width = Math.ceil(svgObject.width);
canvas.height = Math.ceil(svgObject.height);
var ctx = canvas.getContext("2d");
// Convert the SVG string into a base64 and append a header
var svg = btoa(svgObject.template);
var b64Start = 'data:image/svg+xml;base64,';
var image64 = b64Start + svg;
// Draw the SVG onto the canvas instance
var img = new Image();
img.src = image64;
ctx.drawImage(img, 0, 0);
// Return both svg base64 and png base64
return {svg: image64, png: canvas.toDataURL()};
};
console.warn('test')
// Get SVG base64 stuff
var svgimg = document.createElement("img");
document.getElementById('svg-render').appendChild(svgimg);
svgimg.src = convertSVGtoBitmap(testSVG).svg;
// Get converted PNG base64 stuff
var pngimg = document.createElement("img");
document.getElementById('png-render').appendChild(pngimg);
setTimeout(function () {
pngimg.src = convertSVGtoBitmap(testSVG).png;
}, 0)
Note, this works because of the setTimeout of 0. If I change it to just pngimg.src = convertSVGtoBitmap(testSVG).png; without the setTimeout it doesn't display. If I do pngimg.src = '...' where the ... is the hardcoded b64 value it also works. Here's a JSBin if you want to mess with it.
https://jsbin.com/qecedev/2/edit?html,js,output
I also tried putting it in a document.ready from jQuery as well as adding an onload to the pngimg object and adding the src in that.
I figured it out. The problem area was this
// Draw the SVG onto the canvas instance
var img = new Image();
img.src = image64;
ctx.drawImage(img, 0, 0);
// Return both svg base64 and png base64
return {svg: image64, png: canvas.toDataURL()};
The png value in the return wasnt loaded yet. I converted it to have a callback (you could use async or promises too) and it started working.
// USE CALLBACK
var convertSVGtoBitmap = function (svgObject, callback) {
if(!svgObject) return null;
var canvas = document.createElement("canvas");
canvas.width = Math.ceil(svgObject.width);
canvas.height = Math.ceil(svgObject.height);
var ctx = canvas.getContext("2d");
var svg = btoa(svgObject.template);
var b64Start = 'data:image/svg+xml;base64,';
var image64 = b64Start + svg;
var img = new Image();
// WAIT FOR IMAGE TO LOAD
img.onload = function () {
ctx.drawImage(img, 0, 0);
// NOW WE CAN RETURN VALUES!
callback(image64, canvas.toDataURL());
}
img.src = image64;
};

Cannot save big canvas as image [duplicate]

This question already has answers here:
Download Canvas as PNG in fabric.js giving network Error
(5 answers)
Is it possible to programmatically detect size limit for data url?
(1 answer)
Closed 5 years ago.
Good day. I use the following code to save canvas to local image file.
let canvas = document.createElement('canvas');
canvas.width = "1056";
canvas.height = "1248";
document.body.appendChild(canvas);//in case of debug
rasterizeHTML.drawHTML(document.getElementById("canvas").outerHTML, canvas).then(function() {
date = new Date();
let a = document.createElement('a');
let bitmap = canvas.toDataURL("image/png");
a.href = bitmap.replace("image/png", "image/octet-stream");
a.download = "canvas " + date.valueOf()+'.png';
a.click();
});
It works well until canvas height reaches 1k, right after that the resulting file stops loading with error, the file name also corrupts. What could possibly go wrong? Note that save works fine with small images (like 500x500 or 700x900). The canvas rendering works with whatever resolution I set, I can see it by appended image.
Can you post more of your code? It works for me in this snippet.
var size = 2000;
const canvas = document.getElementById('c');
var c = canvas.getContext('2d');
canvas.width = size;
canvas.height = size;
canvas.style.width = size+'px';
canvas.style.height = size+'px';
// fill canvas with color
c.fillStyle = '#123456';
c.fillRect(0, 0, size, size);
const save = document.getElementById('save');
save.onclick = saveCanvas;
function saveCanvas() {
try {
var date = new Date();
const a = document.createElement('a');
const bitmap = canvas.toDataURL("image/png");
a.href = bitmap.replace("image/png", "image/octet-stream");
a.download = "canvas " + date.valueOf() + '.png';
a.click();
} catch (ex) {
alert(ex);
}
}
<a id="save" href="#">save</a>
<canvas id="c"></canvas>

Converting file:/// image to base64 with JavaScript

Here's my code to convert a normal image to base64:
var c = document.createElement("canvas");
var ctx = c.getContext("2d");
var img = document.createElement("img");
img.src = "file:///" + contact.photos[0].value;
ctx.drawImage(img, 100, 100);
console.log(c.toDataURL());
However, this outputs an empty image. The contact.photos[0].value variable is from the Cordova Contacts Plugin, in which all contact photos on iOS are represented as local URLs. How can I accomplish this?

Canvas.toDataURL() not working in IE having SVG content in Canvas [duplicate]

This question already has answers here:
IE throws Security Error when calling toDataUrl on canvas
(2 answers)
Closed 5 years ago.
I have svg content and I want to draw this svg on canvas.Then I want dataURL of canvas but IE gives error of SecurityError.I have spent whole day but i didn't get right thing.Below is code that I have done so far.
var canvas = document.getElementById("canvas");
canvas.setAttribute("height", 500);
canvas.setAttribute("width", 500);
var ctx = canvas.getContext("2d");
var DOMURL = self.URL || self.webkitURL || self;
var img = new Image();
var svg = new Blob([svgString], { type: "image/svg+xml;charset=utf-8" });
var url = DOMURL.createObjectURL(svg);
img.onload = function () {
ctx.drawImage(img, 0, 0);
var image = canvas.toDataURL('image/png');
};
img.onerror = function () {
};
img.src = url;
On above code everything works fine in mozilla and chrome but IE gives an error on canvas.toDataURL. How can I fix this?? Please help me and thanks in advance.
I have solved this issue using Canvg.js

Categories