Chrome javascript image to canvas causes empty image - javascript

Converting image to the canvas with canvas.drawImage fails(but not throws err), the canvas looks transparent empty image
It doesn't happen for all image files I could not figure out which property of the image causes this but I uploaded an example photo with this issue
I started having this problem with chrome v83-v84
firefox works fine.
I want to upload a specified photo (its inside fiddle) and want to make canvas and draw canvas from the uploaded image and display it on chrome (chrome version should bigger or equal v85)
function testimg(src) {
var img = document.createElement("img");
img.src = src;
document.querySelector('#test').appendChild(img)
}
$('#file').on('change', fileAdded)
function fileAdded(event) {
var reader = new FileReader;
reader.onload = function () {
var image = new Image();
image.src = reader.result;
image.onload = function () {
document.querySelector('#test').appendChild(this)
var imgToSend = processImg(this, this.width, this.height);
testimg(imgToSend)
};
};
reader.readAsDataURL(event.currentTarget.files[0]);
}
function processImg(image, srcWidth, srcHeight) {
var canvas = document.createElement('canvas');
canvas.width = srcWidth;
canvas.height = srcHeight;
var ctx = canvas.getContext("2d");
ctx.drawImage(image, 0, 0);
ctx.fill();
return canvas.toDataURL();
}
https://jsfiddle.net/msacar/2Lgmc85t/24/

Related

Image dimensions not reflected correctly

I am trying to get the base64 of some images in Javascript and was using this function:
function getBase64Image(img) {
return new Promise((data) => {
var canvas = document.createElement("canvas");
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
data(canvas.toDataURL("image/png").replace(/^data:image\/(png|jpg|jpeg);base64,/, ""))
})
}
Then I call the function to load in the image using:
var img = new Image();
img.crossOrigin = 'Anonymous';
img.onload = function () {
getBase64Image(this).then(data => {})
}
img.src = wha[1][0]
If I look at the naturalWidth of the image (96px), it is different from the actual image itself (640px). I had been looking at other methods of getting base64 from an image but they also return the same results.

Whole image won't be drawn on canvas in JavaScript

I am making a photo editor, where you have the option to upload an image that will be drawn on a canvas. I let the user upload a new image without refreshing the website. However, the second time you try to upload a different image, the whole image won't be drawn on the canvas. The only part that will be drawn is the size of the image that the user uploaded before that. This is pretty weird as a new size is set every time the user uploads a new image.
After some trial and error, I found out that the new canvas size is actually set to the size of the image that is uploaded. However, it still doesn't draw the whole image, even though it is specified that the image should be drawn at the size of the canvas. Therefore, it is a problem lying in the line that draws the image, and not the part that sets the size of canvas. I tried drawing the image twice instead of once just to see what would happen. It actually worked, even though the the two lines for drawing the image are identical. I found this pretty strange, and I feel like this is not the right way to fix it.
Here is the part of the code that loads the image:
var imageLoader = document.getElementById('imageLoader');
imageLoader.addEventListener('change', handleImage, false);
var canvas = document.getElementById('imageCanvas');
var ctx = canvas.getContext('2d');
var img;
var ratio;
var overlay = document.getElementById("overlay")
canvas.width = 400;
function handleImage(e){
var reader = new FileReader();
reader.onload = function(event){
img = new Image();
img.onload = function(){
ratio = this.height / this.width;
canvas.height = canvas.width * ratio;
ctx.drawImage(img,0,0,canvas.width, canvas.height);
}
overlay.style = "display: none;"
img.src = event.target.result;
window.onbeforeunload = function() {
return true;
};
}
reader.readAsDataURL(e.target.files[0]);
}
canvas { border: 1px solid; }
<input type="file" id="imageLoader">
<canvas id="imageCanvas"></canvas>
<div id="overlay">Unrelated overlay...</div>
The behavior you're getting is not weird but makes perfect sense because you’re supposed to adjust the size of the canvas to the NATURAL dimesnions of the image loaded each time!
What makes you think that the canvas automatically adjusts itself to any image loaded?
You need to do this with every new image load...
canvas.width=img.naturalWidth;
canvas.height=img.naturalHeight;
canvas.style.transform='scale(0.5,0.5)';
After some time, I found out that I had to use clearRect before redrawing the image.
Now the JavaScript code looks like this:
var imageLoader = document.getElementById('imageLoader');
imageLoader.addEventListener('change', handleImage, false);
var canvas = document.getElementById('imageCanvas');
var ctx = canvas.getContext('2d');
var img;
var ratio;
var overlay = document.getElementById("overlay")
canvas.width = 400;
function handleImage(e){
var reader = new FileReader();
reader.onload = function(event){
img = new Image();
img.onload = function(){
ratio = this.height / this.width;
canvas.height = canvas.width * ratio;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(img,0,0,canvas.width, canvas.height);
}
overlay.style = "display: none;"
img.src = event.target.result;
window.onbeforeunload = function() {
return true;
};
}
reader.readAsDataURL(e.target.files[0]);
}

Image not getting copied properly in javascript

I need images to be copied and sent to server for image rotations etc.
To copy an image I'm using this code( from Get image data in JavaScript?):
function getBase64Image(img) {
// Create an empty canvas element
var canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
var dataURL = canvas.toDataURL("image/png");
var replaced = dataURL.replace(/^data:image\/(png|jpg);base64,/, "");
console.log("dataurl=",dataURL);
console.log("replaced=",replaced);
return replaced;
}
It is called like this:
$("#xyz").load(send_image).each(function () {
if (this.complete)
$(this).load();
});
function send_image(){
getBase64Image(document.getElementById('xyz'));
}
However in getBase64Image function once in 40-50 times dataURL is being returned as empty.
What could be the reason?

Saving image to localstorage - canvas

I'm using html5 storage to store my image.
It works great in chrome. In FireFox it works 8/10 times.
function getBase64Image(img) {
var canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
console.log("line 1 : " + img.src);
var dataURL = canvas.toDataURL('image/jpeg');
console.log("line 2 : " + dataURL.replace(/^data:image\/(jpeg);base64,/, ""));
return dataURL.replace(/^data:image\/(jpeg);base64,/, "");
}
Sometimes it returns only "data,".
I see that the canvas size is 0x0:
canvas.width = img.width;
canvas.height = img.height;
Why is that happening?
If the height or width of the canvas is 0, the string "data:," is returned.
This is most likely the cause for some images to fail to receive a proper dataUrl.
Check your img elements and/or scripts to obtain and set the width and height of the canvas.
The auto width and height are only available after the image is loaded.
The function is trying to get the height/width before the image is loaded so I get 0x0. To solve that add img.onload before calling the save function.
function readURL(input, image, width, height) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
//Save the image
var img = new Image();
img.src = e.target.result;
img.onload = function (e){
if (image.id == 'photo1') {
save(img, 'image1');
}
else {
save(img, 'image2');
}
}
}
reader.readAsDataURL(input.files[0]);
}
}

Adding SVG image to canvas yields NS_ERROR in Firefox

I'm trying to convert a SVG file to PNG by drawing it to canvas.
var svgToCanvas = function(svgElement) {
setNameSpaceOnEl(svgElement);
appendCSSRules(svgElement, getCssRules(svgElement));
var image = new Image();
// this is ugly but will do:
var svgXml = $('<div>').append($(svgElement).clone()).html();
var b64str = btoa(unescape(encodeURIComponent(svgXml)));
// var svgXml = new XMLSerializer().serializeToString(svgElement);
var defer = $q.defer();
image.onload = function() {
var canvas = document.createElement('canvas');
canvas.width = image.width;
canvas.height = image.height;
var context = canvas.getContext('2d');
context.drawImage(image, 0, 0);
defer.resolve(canvas);
};
image.src = 'data:image/svg+xml;base64,' + b64str;
return defer.promise;
};
The problem is that even though the image handling takes place inside the onload function, Firefox yields error NS_ERROR_NOT_AVAILABLE: ... on the line
context.drawImage(image, 0, 0);.
With breakpoints I see the image.src at this point is a valid base64 string, and I can even open up the image itself.
The code above works in Chrome, but not in Firefox. Any suggestions how to get around this in Firefox?

Categories