Element Background Image DataURL - javascript

Is there any way to get a callback on background-image is loaded with a base 64 DataURL. I can cache this with image src attribute, but with data url ? How ?

Should work the way it usually does:
var image = new Image();
image.src = "data:image/ png;base64,iVBORw0KGgoAAAANSUh.......";
image.onload = function() {
//image was loaded
};
Caching by the browser is of course disabled for Base64 strings, that's why it's normally only used for small images, like icons and stuff.
You can convert images to Base64 online here : http://base64img.com/#encode
Note that some browsers can have limitations on size for Base64.

Seems that style.BackgroundImage property do not set the value asynchronously. So my problem is solved.

Related

Img src via blob/b64 does not work on iOS

I am trying to set the src of an img tag in order to display an image. The following works on android/mac/windows, but not on iOS:
let b64Bmp = pageModel.image;
this.$currentPageImage.src = `data:image/bmp;base64,${b64Bmp}`;
b64Bmp is a b64 encoded bitmap image. I also tried the same using a blob:
const blobUrl = URL.createObjectURL(resultBlob);
this.$currentPageImage.src = blobUrl;
None of these solutions work on iOS specifically. Also, when trying to create a new Image object like so:
const image = new Image();
image.src = ...
The image.onerror throws an error without any information.
What do I have to change to make this work on iOS?
Found the solution. Apparently, iOS does not display BMP files with a color depth of less than 24 bits (see https://developer.apple.com/forums/thread/715255). It works now, when sending a BMP with color depth of 24 bits

save css computed background image as a variable or object for later use

Is it possible to get the image data from a computed style and save it in a variable or object for later use ?
For example in HTML web page I load the background from an image with CSS:
document.body.style.background = "url(...path/image.php) #FFF";
Now I need to save the image which was loaded in document.body.style.background
because i will use it later. I would like to save the image in localStorage as DATA URI and access it even after i restart the browser.
I cannot use AJAX or send request to server. I have to copy/save somehow from webpage which was loaded. But I'm not sure if this is possible and if yes , how
I cannot use the image URL because the url generates random images everytime, it something like http://url.php ... and not a standard image url
Maybe using HTML5 Canvas is possible to copy from document.body ?
the webpage is populated with other child elements
Create a canvas > object - load your generated image into the canvas, then use canvas.toDataURL to grab the base64 representation of the image. You can then store that base64 string as a variable and reload it whenever you want.
Detailed example in this SO answer: How to convert image into base64 string using javascript
There is no way to take a real screen-shot of any element through canvas. (at least not in WebAPI, in some browsers, extensions are allowed to do so).
You will have to create a new Image object, set it's src to the one of the background-image, and then only be able to draw it on the canvas.
But if the server answers with a no-cache, then the Image will just load an other image than the one set as background.
So you will have to make things in the other way :
First load the image through an Image Object.
Then draw this image to a canvas and get its dataURI version by calling canvas.toDataURL().
Finally, set your element's background to this dataURI you just extracted.
// first load your image from the server once, into an Image object
var img = new Image();
// wait for the image has loaded
img.onload = function(){
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
canvas.width = this.width;
canvas.height = this.height;
ctx.drawImage(this, 0,0);
// since I'm receiving photos, jpeg is better
var dataURL = canvas.toDataURL('image/jpeg');
// if we could use local storage in snippets...
//localStorage.setItem('background-image', dataURL);
// since we can't
saved = dataURL;
document.body.style.backgroundImage = 'url('+dataURL+')';
}
// I'm loading it from an external server
img.crossOrigin = 'anonymous';
img.src = 'http://lorempixel.com/200/200/?'+Math.random();
// since we can't use local storage in sand-boxed iframe
// we will use a global in this snippet
var saved;
button.onclick = function(){
// if we could use localStorage
// var saved = localStorage.getItem('background-image');
document.getElementById('result').style.backgroundImage = 'url('+saved+')';
};
div{width: 200px; height: 200px; border: 1px solid; background-color: white;}
body{width: 100vw; height: 100vh; margin: 0;}
<button id="button">set the div's background to the saved one</button>
<div id="result"></div>
Note that localStorage is limited so depending on your graphics, you may want to use the image/jpeg compression type of the toDataURL() method.
Also, you'll be limited by cross-origin policies, if the php page is not on the same domain, make sure it is correctly configured to accept cross-origin requests and set you Image object's crossOrigin property to "anonymous".
Ps : You could also avoid the canvas part by using an XMLHttpRequest and a FileReader(), wich will involve different cross-origin restrictions.

fabric.js - toDataURL shows blank page when there is image on canvas

I'm using fabric.js for my canvas application, toDataURL method works properly except when there is a image on canvas. When i add an image to canvas and call toDataURL it shows me a blank page.
//When i call it from chrome console
canvas.toDataURL();
//It returns a working data url with no problem.
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAPAAAAGkCAYAAAAPPajHAAAgAElEQ…fpmwgogX1TrjoqP0FACewngtZh+iYCSmDflKuOyk8Q+H+CKCqUW0spTgAAAABJRU5ErkJggg=="
//When i execute same code in a .js file it returns a data url which shows a blank image.
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAPAAAAGkCAYAAAAPPajHAAAKC0lEQ…sBAmEBAw6XJzoBA/YDBMICBhwuT3QCBuwHCIQFDDhcnugEHt/IAaW9dzALAAAAAElFTkSuQmCC"
It's interesting that it's working on chrome dev console but not works in .js file even if it's same code. I noticed that working data url finishes with '==' but other one not. However i don't know what this means.
You didn't give much to analyze but I'll go from there on my gut feeling.
The image you are using is probably violating Cross-Origin Resource Sharing (CORS) requirements. When this happens the canvas will return a blank image when you try to get the pixel data either by using canvas.toDataURL() or context.getImageData().
It basically happens when the image is not located on the same domain as the page or is loaded from the file:// protocol.
You can try to add the following to the image object before setting the source:
image.crossOrigin = 'anonymous';
image.src = '...';
From tag:
<img crossOrigin='anonymous' src='...' alt='' />
This will request permission from the server to use the image cross-origin. If the server allows you should be fine.
If not you will either have to copy the image to your own server so it loads from the same domain as your page, or create a proxy page that loads the image externally and serves it to your page from the proxy page (it sounds complicated but really isn't).
If the image does not show up at all on the canvas you are probably not using load callback which you need since image loading is asynchronous. If so just add:
image.onload = function() {
/// now you can draw the image to canvas
}
image.crossOrigin = 'anonymous';
image.src = '...';
The problem is solved. The point i missed is, i was calling toDataURL function before canvas is loaded, that's why it was showing me a blank page.
canvas.loadFromJSON(json,function(){
var dataURL = canvas.toDataURL();
});
This solved my problem when i gave toDataURL() function as a callback to loadFromJSON function.
But after a while i had a different issue about CORS when i tried to upload my images from s3 bucket and i solved this problem as upward solution.
I was facing the same issues when I was trying to generate images from the canvas using Fabricsjs and generate PDF from images using JSPDF so below is my case I also spend hours on this may this can help someone to save time.
Load the canvas from JSON that i.e
canvas.loadFromJSON(json, canvas.renderAll.bind(canvas), function(obj, object) {
//fabric.log(obj, object);
});
Canvas was drawing images all fine then I was generating the images from that canvas it was a case of multiple images in a single canvas and I was generating PDF based on each page of the canvas.
Instead of this
canvas.toDataURL('image/png', 0.1)
I used this and it starts returning me the propper images dataurl
var imgData = document.getElementById('canvas_0').toDataURL();
Below are snippets
$("#pdfSelector .canvas-container").each(function(index, value){ // canvas selector
html2canvas($("#canvas_"+index), { // html2canvas used to get images
onrendered: function(canvas) { // on successfully render of images
//var imgData = canvas.toDataURL('image/png', 0.1);
var imgData = document.getElementById('canvas_0').toDataURL();
const imgProps= doc.getImageProperties(imgData);
const pdfWidth = doc.internal.pageSize.getWidth();
const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width;
doc.addImage(imgData, 'PNG', 0, 0, pdfWidth, pdfHeight, 'page_'+index, 'FAST');
}
});
});

Load image... when time is eating up

here is a sameple code, I would like to know when the browser is REALLY loading image
when you assign an image path to a array like that
imageNames[0] = 'image1.jpg';
or when you make
myImage = new Image();
myImage.src = imageNames[0];
i have put some timer.. but did not get concluant result ! HELP
You would look at the load event. Attach it with the ancient onload or addEventListener()/attachEvent() depending on your browser support requirements.
myImage = new Image;
myImage.onload = function() {
alert('Image loaded');
}
myImage.src = imageNames[0];
jsFiddle.
You could also check if the image is already loaded by checking the complete property.
The key thing to note is that just because a human being can see that something could be a resource identifier / locator, the computer cannot.
When you assign a string to a point in an array:
imageNames[0] = 'image1.jpg';
the fact that 'image1.jpg' is a licit path to an image on your.host.net is not something the browser can determine on its own - the browser cannot recognize that the string 'image1.jpg' is a resource representation rather than a resource itself.
Once you set a DOM image's src property to be the string 'image1.jpg' the browser can recognize the string should be treated as a resource identifier (because the DOM element you created is an image, and the image's src property is supposed to be a URI pointing at an image resource which can be accessed and downloaded) and the browser will try and acquire that resource through means of its own.
The browser downloads the image when you assign a URL to the src attribute of an img element. Try this in the console of your browser and watch the Network tab:
var img = document.createElement('img');
img.src = 'foo';
You'll see network activity as soon as that second line executes.
It most certainly does nothing for imageNames[0] = 'image1.jpg'; since a string in an array could be anything, there's no way the browser has any idea this is supposed to be the URL of an image.

Create HTML image from data in Javascript variable

I have image data (either JPEG or PNG) in a Javascript variable. How do I display the image in an HTML document? These are very large images and code like this doesn't work because the URI is too long:
// doesn't work because the URI is too long
$('img#target').attr('src', 'data:...');
Using canvas is probably the answer but I cannot figure out how to load it with the image data.
In case you are wondering: no, I cannot just download the image data directly to the img tag. It came from the server encrypted and was decrypted within the browser using Javascript.
Thanks,
-- Art Z.
To use a data URL to draw on a canvas:
var img = new Image;
img.onload = function(){
myCanvasContext.drawImage(img,0,0);
};
img.src = "data:...";
Per this question/answer be sure that you set the onload before the src.
You say that "the URI is too long", but it is not clear what you mean by this. Only IE8 has a 32kB limit on the data URI; for other browsers it should work fine. If you are experiencing an error, please describe it.
It turns out that
$('img#target').attr('src', 'data:...');
does work in all except IE. My problem originated elsewhere.

Categories