A have a page with image.
Javascript code periodically loads new content for image from server as data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAUAAAADwCAYAAAB.... Well, you understand, it is image as base64 encoded.
Javascript code changes image src to new one, but it looks like old data is not being deleted.
If I leave page running for some time, it eats all the memory.
Is there some way to remove previous images completely?
I have a suggestion. Please test and see if it works for you.
Create blob from base64 string. Read:
Creating a Blob from a base64 string in JavaScript
var url = URL.createObjectURL(blob). And set the url as src of
image
When done, try URL.revokeObjectURL(url)
If I understand you correctly, you are downloading the image as a base64 encoded string, then passing that string into an img src? If that is the case it sounds like the scope of your strings is not expiring somehow. To ensure the deletion of a primitive object like a string, you must keep a reference to the string by proxy with an object. Something like below.
// Somewhere in a persistent scope like global
image_reference = {};
// In your ajax callback
if(image_reference.data != null) {
delete image_reference.data;
}
image_reference['data'] = response.data;
// Put image_reference.data into your img element
Related
I have a JavaScript app that calculates various values. I would like to have a function that stores calculated output values (e.g. when you click a "store value" button), creating a list in the background that the user could then download as, e.g., a text file. I'm wondering what the easiest implementation of this would be in the browser -- values can get wiped on page refresh so no need to store long-term. Thanks!
Are you asking for a way to download a file with these values?
Here is a quick example of how to do that:
Let's say I have an a-tag in my html like this
<a id="Button" download="download.txt">Download</a>
I can then use javascript to make it download a file with text in it
Button = document.getElementById('Button');
theText="Hello";
var textFile = null,
makeTextFile = function (text) {
var data = new Blob([text], {type: 'text/plain'});
// If we are replacing a previously generated file we need to
// manually revoke the object URL to avoid memory leaks.
if (textFile !== null) {
window.URL.revokeObjectURL(textFile);
}
textFile = window.URL.createObjectURL(data);
// returns a URL you can use as a href
return textFile;
};
Button.href=makeTextFile(theText);
Then when we click the link, it downloads a text file with the contents "Hello". I got this code from somewhere a really long time ago when I was working on a project, but I don't remember where it is from.
If this isn't what you are asking for, please clarify your question.
I am using JSZip to make a program that generates the image data from a canvas element and puts the image into a zip file.
Right now, it is turning the canvas image into an DataURL. Then, I get rid of the part of the resulting string that says data:image/png;base64,. Now, there is nothing left but the base64 data. I then use atob to change it to ascii.
It seems like putting the remaining string into an image file should work, but the generated ascii text is not correct. Many parts of it are correct, but something is not right.
Here is my code:
//screen is the name of the canvas.
var imgData = screen.toDataURL();
imgData = imgData.substr(22);
imgData = atob(imgData);
console.log(imgData);
Here is an image of the resulting png file (in notepad):
incorrect text http://upurs.us/image/71280.png
And here is what is should look like:
correct text http://upurs.us/image/71281.png
As you can see, there are slight differences, and I have no idea why. I know absolutely nothing about the PNG file type or ASCII, so I don't know where to go from here.
If you want to see all my work, here's the project:
http://s000.tinyupload.com/download.php?file_id=09682586927694868772&t=0968258692769486877226111
EDIT: My end goal is to have a program that exports every single frame of a canvas animation so that I can use them to make a video. If anyone knows a program that does that, please post it!
When you use zip.file("hello.png", imgData) where imgData is a string, you tell JSZip to save an (unicode) string. Since it's not a textual content, you get a corrupted content. To fix that, you can do:
zip.file("hello.png", imgData, {binary: true})
As dandavis suggested, using a blob will be more efficient here. You can convert a canvas to a blob with canvas.toBlob:
screen.toBlob(function (blob) {
zip.file("hello.png", blob);
});
The only caveat is that toBlob is asynchronous: you should disable the download button during that time (or else, if a user is quick enough or the browser slow enough, zip.file won't be executed and you will give an empty zip to your user).
document.getElementById("download_button").disabled = true;
screen.toBlob(function (blob) {
zip.file("hello.png", blob);
document.getElementById("download_button").disabled = false;
});
When one right clicks an image in a webpage and selects "Properties", one gets a display which details the URL, Size, Dimensions, Created (date), Modified (date), etc.
Obviously I know the URL as it is in my code, but some of the others are not, for example created and modified dates, they have to be coming from the server at the image source. I have tried using the
document.getElementById("photo").attributes
where the related HTML code is this
<img id="photo" src="http://www.somesite.com/photo.jpg" width="320" height="240" alt="offline" >
but that only returns the 5 attributes found in the above img line.
Since the dates and other information are available for the "Properties Dialogue" I assume there are also available somewhere in the document object.
Any ideas as to how I might access them using JavaScript or VBScript?
Thanks....RDK
Have you investigated using the JavaScript Image object?
Well, you could try get the the URL of the image, then do an AJAX request to the image, get the response headers and they will tell you the created date, etc.. that you are after...
Example...
var myImageURL = %YOUR_IMAGE_URL%
var modifiedHeader = 'Last-Modified';
var req = new XMLHttpRequest();
req.open('HEAD', myImageURL, false);
req.send();
var header = req.getResponseHeader(modifiedHeader);
if (header) {
console.log(header); // this is the last modified date
}
EDIT:
This would work only if the image was accessible via AJAX... (same-origin policy, etc...)
EDIT:
Changed to head so SOP does not matter now.. Thanks #Musa
Information like the creation and modification dates will be stored (if anywhere) in the image's EXIF metadata.
There is a jQuery library for reading EXIF metadata that provides an exif() method, e.g. $('img').exif('DateTimeOriginal').
Note that images hosted on a different domain will not be accessible to JavaScript.
Information about the width and height of the original image file should be properties of the image object itself, e.g. document.getElementById('photo').naturalHeight
Say I have an <img/>. This img has src='http://somelocation/getmypic'. At some later time, I may want to change the content of the img based on an ajax call that receives binary data. I only know once I have received the data in the ajax callback whether I want to apply it to the image. I might decide not to.
As far as I can tell from the research that I have done, the only way to set binary data on the img is by base64 encoding the binary data and setting the img src to the resultant base 64 encoded string.
My first and main question is: what is the overhead? Doesn't this mean that I have tripled the processing and memory usage for an image download? My ajax callback gets the binary data that has been loaded into memory, then I base 64 encode the binary stream and then (I assume) the browser decodes this stream back to binary? Or am I missing something and it's actually not that bad?
My secondary question is: Why is there no way to set binary data directly into the img without base64encoding? Most UI languages that I have used allow you to load an image into a 'PictureBox' (for example ) from file and also draw in the 'PictureBox'. Why is this not allowed with an img? I am thinking img.binary=bytes which would set src to 'binary' or something like that. It seems this functionality is split between img and canvas, but sometimes you want to do both. I am just wondering if I am missing something in my understanding (e.g. there is some design or implementation benefit in not allowing binary data to be set directly on img).
Thank you.
Well, this is what I came up with. I am not sure what the performance or memory usage is, but it is a lot easier than base64 encoding and it works with the asp.net MVC FileStreamResult. So, I thought that I would post it here in case it helps somebody else:
var oReq = new XMLHttpRequest();
oReq.open("post", '/somelocation/getmypic', true );
oReq.responseType = "blob";
oReq.onload = function ( oEvent )
{
var blob = oReq.response;
var imgSrc = URL.createObjectURL( blob );
var $img = $( '<img/>', {
"alt": "test image",
"src": imgSrc
} ).appendTo( $( '#bb_theImageContainer' ) );
window.URL.revokeObjectURL( imgSrc );
};
oReq.send( null );
The basic idea is that the data is not tampered with and it is received as a blob. A url is constructed for that blob (I think that essentially means that you can use a URL to access that blob in memory). But the good thing is that you can set the img src to this, which is...awesome.
This answer put me on the right track, then this page and this page on mdn. Note supported browsers.
I have some text data (say var a = 'Hello World From Javascript';)in javascript variable in current window. I want to do the following
through javascript-
1. open a new window and write the text data to the window.
2. set the content type to text/plain.
3. set the content-disposition to attachment, so that download prompt comes.
4. user downloads the text data as a text file and saves it to his local disk.
is this all possible through javascript?
I know we can make ajax calls to server or redirect but in this case instead of following above steps. But in this case, these workarounds are not adaptable.
you can do that using JS & HTML5 features. Please find below a sample code.
var fileParts = ['Hello World From Javascript'];
// Create a blob object.
var bb = new Blob(fileParts,{type : 'text/plain'});
// Create a blob url for this.
var dnlnk = window.URL.createObjectURL(bb);
var currentLnk = $('#blobFl').attr('href');
// blobFl is the id of the anchor tag through which the download will be triggered.
$('#blobFl').attr('href',dnlnk);
$('#blobFl').attr('download','helloworld.txt');
// For some reason trigger from jquery dint work for me.
document.getElementById('blobFl').click();
Triggering a file download without any server request
Unfortunately this is not something you can do with normal browser capabilities. Something like flash or a browser-specific plugin will get you what you need, but security limitations within javascript will not let you download arbitrary data created within the browser.
Also the 'data' url is not supported across all browser/version combinations. I am not sure if your users are constrained on what browser they are using or not but that may limit what you can do with that solution.
Source: Triggering a file download without any server request
If you already have the file on the server (I make an ajax call to generate and save a PDF on the server) - you can do this
window.location.replace(fileUrl);
No, Content-Disposition is a response header, it has to come from the server. I think you could do it with Flash but I wouldn't recommend it.
Here's a clean, pure js version of #Rajagopalan Srinivasan's answer:
var fileParts = ["Hello World From Javascript"];
// The anchor tag to use.
const blobLink = document.getElementById("blobLink");
// Create a blob object.
var blob = new Blob(fileParts, { type: "text/plain" });
// Create a blob url for this.
var blobUrl = window.URL.createObjectURL(blob);
blobLink.setAttribute("href", blobUrl);
blobLink.setAttribute("download", "helloworld.txt");
blobLink.click();
<a id="blobLink">Download</a>