HTML5 canvas drawImage, how to preserve image source size - javascript

function getImageBase64Data(_id)
{
var c = document.createElement('CANVAS');
var ctx = c.getContext("2d");
var img = document.getElementById(_id);
ctx.drawImage(img, 0, 0);
var dataURL = c.toDataURL();
return dataURL.replace(/^data:image\/(png|jpg);base64,/, "");
}
I'm using HTML5 canvas to obtain base64-encoded image data. However, the resulting base64 encoded string is different and smaller than encoding the original image file with external software.
I suspect what is drawn on the canvas is the the resized/compressed image data rendered on the page, not the original source data. Is this the case, and how could I obtain the original bytes of the image? It is essential, that original bytes aren't manipulated in any way.

To make it shown without compress, change the height/width for canvas itself:
var img = new Image(); // var img = document.getElementById(_id);
img.onload = function() {
var c = document.createElement('canvas');
c.width = img.width;
c.height = img.height;
// ... other stuff
};

Related

How to make a base64 array from an array of photos

const arrUrl = [
'https://avatars.mds.yandex.net/getzen_doc/1714479/pub_5e4b9183baec8f365f1ff215_5e4b91c9bb4a6d368b8d9d4c/scale_1200',
'https://avatars.mds.yandex.net/getzen_doc/1714479/pub_5e4b9183baec8f365f1ff215_5e4b91c9bb4a6d368b8d9d4c/scale_1200',
'https://avatars.mds.yandex.net/getzen_doc/1714479/pub_5e4b9183baec8f365f1ff215_5e4b91c9bb4a6d368b8d9d4c/scale_1200',
'https://avatars.mds.yandex.net/getzen_doc/1714479/pub_5e4b9183baec8f365f1ff215_5e4b91c9bb4a6d368b8d9d4c/scale_1200'
];
there is an array of different links to photos, how to make them all in base64, I have a script that makes base64 photos, but I can't combine them
var img = new Image();
img.crossOrigin = 'Anonymous';
// The magic begins after the image is successfully loaded
img.onload = function () {
var canvas = document.createElement('canvas'),
ctx = canvas.getContext('2d');
canvas.height = img.naturalHeight;
canvas.width = img.naturalWidth;
ctx.drawImage(img, 0, 0);
// Unfortunately, we cannot keep the original image type, so all images will be converted to PNG
// For this reason, we cannot get the original Base64 string
var uri = canvas.toDataURL('image/png'),
b64 = uri.replace(/^data:image.+;base64,/, '');
console.log(b64); //-> "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWP4z8DwHwAFAAH/q842iQAAAABJRU5ErkJggg=="
};
// If you are loading images from a remote server, be sure to configure “Access-Control-Allow-Origin”
// For example, the following image can be loaded from anywhere.
var url = '//static.base64.guru/uploads/images/1x1.gif';
img.src = url;
or
https://gist.github.com/CawaKharkov/1c477d44fcfdf67aea3f/revisions#diff-7b3e9484330c338cea137079906c2390c4961003e07e3a9d13bed49d9d63805eR17

How to store image locally from image URL by using jquery?

I want to store image locally and use it to anywhere in tizen application.
I tried by using canvas but canvas data uri not showing exact image which have in URL.
The snippet of code who I am using.
var img = new Image();
img.src = imageURL;
var canvas = document.createElement('canvas');
document.body.appendChild(canvas);
var context = canvas.getContext('2d');
context.drawImage(img, 0, 0);
var data = context.getImageData(x, y, img.width, img.height).data;
localStorage.setItem('image', data);
Your code does not work because you want save an array to localStorage. Instead of context.getImageData() you have to use canvas.toDataURL() and then convert dataURL to Base64 string image. After this you can save it to the localStorage.
Your image must be online and in the same domain like your script. It is because of Cross-origin resource sharing (CORS). But if you convert your image like me in dataURL before and then you should not have any problem.
And to localStorage you have today (in 2018) an access only in online mode. Please read:
localStorage access from local file
Full example
See this working example on codepen.io (link to example) because on StackOverflow the snippets are sandboxed and because of this we can not have an access to the localStorage.
var canvas = document.createElement('canvas');
var image = new Image();
var ctx = canvas.getContext('2d');
image.onload = function()
{
canvas.width = image.width;
canvas.height = image.height;
ctx.drawImage(image, 0, 0);
var dataURL = canvas.toDataURL('image/png');
var Base64StringImage = dataURL.replace(/^data:image\/(png|jpg);base64,/, "");
localStorage.setItem('image', Base64StringImage);
//read from localStorage:
document.querySelector('img').src = 'data:image/png;base64,' + localStorage.getItem('image');
};
image.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAA7EAAAOxAGVKw4bAAADnElEQVRYhaWXz2/cRBTHP/Y4zka0ShPQJluJLkl/0EsSl24OCAgRFQoH1Ir/oNmeEJdScYUDXOitSBxASFmQ4MSJay6EtojLgvIDCUKhaQIipCI/SlKy690Zc2jWa3ttT4Tn9p3v6H3fe/Pm2c/wPM/jYC25n1Nnl5L9emuLDbnIgBj18ba6S5857ONPHz5P3MqbIzh2meNi3N+Ls28Fye8bH/lE69C8O8NUzw1/f8GtMJl7L1Y0STjNvhUkz1iXsI0j/Nj4wj+0rqqhLPwpqx1ZSRPW2beC5LP2WxiGAeAfistCEKcJR8Xj7Ft1dgGwjSM+2c1RAFxvD6AjC0G8o+4xV3unQzgvRnC6yujsW627aHnUzdGQx780v0rNgnsg4AtHMvKEOJtq32rdRfBQNF3BqJNw2lWk2beih1xvr0M8GHUU62pAZ9/4q7ngpb3zb+vvs6XusKmWQwaPGUMURIkm+6n8T80vYx0qmOdx7DJmNKoFtxLCf6ufeTX3CRe6r/O4+TTHjCEmu9/lUs9n7KgVLR9dg+Y5Xsl9yFTPBwyIMSzdO99Wv7Imb1O0JthWK7js8pT1EhtykXVVBdDyAAPmGI59hYJ4JuSQBenvHGC+McMDtcoPjY/9vU25fCg+b44e1Egp9iosSH/nAMprhJ6b6+0hqfs4jd9RK8zV3u4QLojzOPZ0+xWkZWHMvsyw9TJg+FW8rqrM1t7U8tE+MWiew7GvMCicdgaCUUdxr1FkSFxgQy6yKZeR1FlXVY6LcfLmCHXvn1T+vloCkmvAqOw953+OC2aJTbXse10wS/SaT/JA/R4qKHjUePJilKb3byp/Xy6l18Dlx27HEtvqLgtuBUmjI41wcM+eq+VzRi+ztav+/gnxAmvyVtuBJOF7cg7w6DNPcTE3wx/yO+YbM0jPxbGnKYpJZmvXqLGTyo/bb4QEna5yvANR4fZ+tj7QL06Hoo5iK0k4uLL0gbiog9jqM4djf7Hajn2dqQ/ERR3E2hqAbH1AlwVtDWTtA9EsRLGxJX/z0mrgrPVapj4Q/AXfknfoF6dD2NDNBUmrlTGFZE3e9PdPiIkQDvaZ/zUXJAm3MnYxVwkJOl3TIayzr50LkoRb69FdtqOOYp197Vxw0prS9gnHLrO2f8vngzjzXKDrEwD95imKYoJV+U0HzjwXJAlHMzJml1ndv9mBdfYPPRfoWna/eZKieDEWZ5oLDvOtaC3Hnk7ESfb/A1K3qRpcj5DtAAAAAElFTkSuQmCC';
<img src="#">

Can't redraw image represented in base64

First part of my application loads picture with file chooser from my file system and draws image to canvas. I take that canvas and convert it to data URL and also save it in my database.
var imgData = canvas.toDataURL("image/jpg");
factory.saveData(imgData); // execute some java code
Here is the problem. I can't redraw that image, my javascript:
var pic = new Image();
pic.onload = function() {
ctx.drawImage(pic, 0, 0); // ctx = canvas.getContext("2d")
};
// This data url is copy/pasted from database for simplicity
pic.src = "data:image/png;base64,iVBOR..........ElFTkSuQmCC";
Onload function is called but I just get transparent image.
Probably has something to do with the fact that getDataFromDatabase() is asynchronous so you're returning a promise object to pic.src instead of the data url. Fix this by using a then call on getDataFromDatabase and using the result on pic.src like this:
var pic = new Image();
var pic.onload = function() {
ctx.drawImage(pic, 0, 0);
};
getDataFromDatabase().then(dataUrl => {
pic.src = dataUrl;
});
Here's a full example of this in action. I draw to a canvas, store the canvas data as a base64 data url into a variable, save it into a mock DB using closures, then reload the data from a simulated asynchronous function call by using a promise.
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
// Initialize canvas to a random image
const imageUrl = 'https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-logo.svg?v=a010291124bf';
const initialImage = new Image();
initialImage.src = imageUrl;
initialImage.onload = function() {
ctx.drawImage(initialImage, 0, 0);
}
// Convert canvas to base64 data url
const imageData = canvas.toDataURL('image/png');
const getDataFromDatabase = saveData(imageData);
// Clear the canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Redraw the image
const pic = new Image();
getDataFromDatabase().then(data => {
pic.src = data;
});
pic.onload = function() {
ctx.drawImage(pic, 0, 0);
}
function saveData(image) {
return function getDataFromDatabase() {
return new Promise(resolve => {
resolve(image);
});
}
}
<canvas id="myCanvas">
</canvas>
Edit: It shouldn't really matter where you get the image data from. If the data is not malformed, it should draw to the canvas. Here's an example identical to the way you're loading image data (from a hardcoded data url):
const imageData = 'data:image/png;base64,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';
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
const image = new Image();
image.onload = function() {
ctx.drawImage(image, 0, 0);
}
image.src = imageData;
<canvas id="myCanvas">
</canvas>
I suggest you check your image data using a base64 image decoder to see if your image data is malformed or not. If your data url is valid, then something else I can suggest is ensuring your canvas width and height are equal to or greater than the image's width and height or else it'll be hidden (if the image you're supplying has empty space / padding).

Loading image and resizing through canvas causes infinite loop

I want to get an image scaled correctly after loading it with a dummy click on a <input type='file'> and compressing it via drawing it onto a canvas. When calling a console.log() inside the img.onload I discovered it was being run in a loop. Putting the img.src = canvas.toDataURL("image/png") outside of the onload results in a blank image but no loop. Moving things around by trial and error has not been effective as I don't get the dynamics at play here (even though I can get images redrawn when rescaling a canvas). Thanks!
$('button.picture').on('click',function(){
var outerWrapper = $(this).closest('.outerWrapper')
$(this).siblings('.imageLoad').on('change', function(e){
var loadedImage = e.target.files[0]
var img = new Image();
img.src = window.URL.createObjectURL(loadedImage);
var canvas = document.createElement("canvas");
canvas.width = outerWrapper.width()
canvas.height = outerWrapper.height()
img.onload = function(e){
//still here the img.width returns the canvas width and not the original image's width
console.log(img.width)
var context = canvas.getContext("2d");
context.drawImage(img,0,0, canvas.width, canvas.height )
img.src = canvas.toDataURL("image/png")
}
$(this).closest('.outerWrapper').children('.imageWrapper').append(img)
})
$(this).siblings('.imageLoad').trigger('click')
})
To answer my own question I want to make clear what my aims were:
Load in image through a dummy click on an <input type="file">
Keeps the aspect ratio of the original image
Compress it
What worked was not setting img.src = canvas.toDataURL("image/png") as you would when resizing a canvas but by loading the original again image with URL.createObjectURL(loadedImage). To preserve the aspect ration I had to create two separate images, one to get the img.naturalWidth and img.naturalHeight for calculation and the next to load the image onto the canvas. Works a charm. Would be interested to learn where it can be refined.
$('button.picture').on('click',function(){
var outerWrapper = $(this).closest('.outerWrapper')
$(this).siblings('.imageLoad').on('change', function(e){
var loadedImage = e.target.files[0]
var img = new Image();
img.src = window.URL.createObjectURL(loadedImage);
var canvasPic = $('<canvas class="canvasPic"></canvas>')
canvasPic.prependTo(outerWrapper)
var canvas = canvasPic[0]
canvas.width = outerWrapper.width()
canvas.height = outerWrapper.height()
var context = canvas.getContext("2d");
var image = new Image();
image.onload = function(){
var w = img.naturalWidth
var h = img.naturalHeight
var ratio = h/w
var newWidth = canvas.height/ratio
context.drawImage(img,0,0,newWidth,canvas.height)
}
image.src = URL.createObjectURL(loadedImage);
})
$(this).siblings('.imageLoad').trigger('click')
})

Unable to load an Image into Canvas and get base64 encoding for that image

I am trying to generate a PDF from HTML using jspdf plugin. I am stuck with loading Images into PDF. There is a function addImage() in plugin which takes base64 encoding of an image, but converting an image to base64 is not working.
I have used below two ways
//Create canvas, draw image in context and get the data url
imgToDataURL = function (img, outputFormat){
var canvas = document.createElement('canvas');
canvas.width = 20;
canvas.height = 20;
var c = canvas.getContext('2d');
c.height = img.height;
c.width=img.width;
c.drawImage(img, 0, 0);
c.save();
var dataurl = canvas.toDataURL(outputFormat);
return dataurl;
}
var img = new Image();
img.crossOrigin = 'Anonymous';
img.src = "image path"
img.height= 60;
img.width=60;
var dataURL = this.imgToDataURL(img,"image/jpeg");
renderer.pdf.addImage(dataURL, 'png',x+padding,y + this.internal.getLineHeight(),imageWidth,imageHeight);
This is printing wrong dataURL I am getting a white image. If I hard code the base64 code i.e return a hardcoded dataURL then addImage works fine. So the issue is with canvas.toDataURL which is giving me wrong output
this is the 2nd way
convertImgToBase64URL = function (url, callback, outputFormat){
var img = new Image();
img.crossOrigin = 'Anonymous';
img.onload = function(){
var canvas = document.createElement('CANVAS'),
ctx = canvas.getContext('2d'), dataURL;
canvas.height = this.height;
canvas.width = this.width;
ctx.drawImage(this, 0, 0);
dataURL = canvas.toDataURL(outputFormat);
callback(dataURL);
canvas = null;
};
img.src = url;
}
this.convertImgToBase64URL("Image Path",function(base64){
renderer.pdf.addImage(base64, 'PNG', 20, 20,48,48);
})
I have run this inside a javascript and the onload function is not even running I am not sure what is my mistake is.
Please suggest me what mistake I am doing in either way
In the first you missed assigning an onload function to your image. For that reason, the moment you try to create the dataURL, the image might not be loaded yet, ergo, the blank image. You could try changing the last few lines to this:
...
img.width=60;
img.onload = function () {
var dataURL = this.imgToDataURL(img,"image/jpeg");
renderer.pdf.addImage(dataURL, 'png',x+padding,y + this.internal.getLineHeight(),imageWidth,imageHeight);
}
img.src = "image path";
As for the second one, there seems to be a problem with the convertImgToBase64URL() which accepts 3 parameters, but you are passing 2. In you example, outputFormat parameter is undefined.

Categories

Resources