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?
Related
If I have an image in base64 ex.
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABDAAwfqNRk/rjcYX+PxrV/wtWqwJSTlboMgAAAABJRU5ErkJggg==
What's the fastest way to change a filter (ex. brightness, contrast) programmatically and without creating any img or canvas tag in the view? Then once changed, convert it back to a base64 url?
You can do this by putting the image onto a HTML canvas with filters applied, then turning that canvas back into a base64 URL.
Since you never add the canvas to the document, it will never be seen.
This is how you would do it asynchronously:
This takes about 1-10ms
function applyFiltersToImage(imageURL, callBack) {
// load the image url into an image object
const image = new Image();
image.src = imageURL;
const canvas = document.createElement("canvas");
const ctx = canvas.getContext('2d');
image.onload = () => {
canvas.width = image.width;
canvas.height = image.height;
// apply css filters here
ctx.filter = 'brightness(0.5) contrast(2)';
ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
// turn canvas back into a base64 image URL
callBack(canvas.toDataURL("image/png"));
}
}
You could do it synchronously if you already have the Image instance loaded.
This is how you will do it synchronously:
function applyFiltersToImageSync(imageObject) {
const canvas = document.createElement("canvas");
const ctx = canvas.getContext('2d');
canvas.width = imageObject.width;
canvas.height = imageObject.height;
// apply css filters here
ctx.filter = 'brightness(0.5) contrast(2)';
ctx.drawImage(imageObject, 0, 0, canvas.width, canvas.height);
//turn canvas back into a base64 image
return canvas.toDataURL("image/png");
}
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.
I need the base64-string (not URL) from an existing PNG (photo from a text document).
I use the following function to receive base64-String for my photo. The string, which I get back, is valid but if I test it in a online decoder, I get this image:
imageResult is an image-Element in my DOM. Any hints what is going wrong?
JS
var img = this.imageResult.nativeElement;
var ocrImage = this.getBase64Image(img);
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);
var dataURL = canvas.toDataURL("image/png");
return dataURL.replace(/^data:image\/(png|jpg);base64,/, "");
}
I have two main questions. I'm trying to resize a base64 image according to the answer in
JavaScript reduce the size and quality of image with based64 encoded code
This seemed simple enough, except for the fact that I need to get only the base64 string from that function, without the data:image... header.
I tried to modify the function like this:
function resizeBase64Img(base64, width, height) {
var canvas = document.createElement("canvas");
canvas.width = width;
canvas.height = height;
var context = canvas.getContext("2d");
var deferred = $.Deferred();
$("<img/>").attr("src", "data:image/gif;base64," + base64).load(function () {
context.scale(width / this.width, height / this.height);
context.drawImage(this, 0, 0);
deferred.resolve($("<img/>").attr("src", canvas.toDataURL()));
});
var result = canvas.toDataURL();
return result.substr(result.indexOf(",") + 1)
}
which returns a base64 string. This string is corrupted, and it never displays correctly. Why is this happening and how can I fix it?
The other question is, is there a way to resize the image based on percentage and not on pixel size?
Thanks
I ended up rewriting the function based on another canvas function I found. This function takes the src of a base64 img, modifies the size and assigns the result in base64 to another element:
function resizeBase64Img(url, width, height) {
var img = new Image();
img.setAttribute('crossOrigin', 'anonymous');
img.onload = function () {
var canvas = document.createElement("canvas");
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext("2d");
ctx.scale(width/this.width, height/this.height);
ctx.drawImage(this, 0, 0);
result=canvas.toDataURL();
$('#ASSIGNEDELEMENT').val(result.substr(result.indexOf(",") + 1));
};
img.src = url;
}
And it should be invoked like this:
resizeBase64Img($('#image').attr('src'),300,300);
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?