How to force a download instead of opening the file? - javascript

So basically, I am using a simple library called HTML2Canvas
This is my current code working great and is being called from an onclick event from a button:
function saveForm()
{
html2canvas(document.body, {
onrendered: function(canvas) {
document.body.appendChild(canvas);
}
});
}
Basically, all it does is take a screen shot and append it to the bottom of the page.
There was already a question similar to this, although the answer did not work and the download is always a corrupt jpg file:
html2canvas saving as a jpeg without opening in browser
Would there be a way to force a download within this function instead of appending it to the bottom of the page?

Use canvas.toDataURL to get the canvas content as an image src
open a window/popup
add an <img> to the popup
assign the image src as src for the image
function saveForm() {
html2canvas(document.body, {
onrendered: function(canvas) {
var img = canvas.toDataURL("image/png");
var open = window.open('','','width=500,height=500')
open.document.write('<img id="img" style="width="400">');
open.document.getElementById('img').setAttribute('src', img);
}
});
}
Tested the code inside onrendered, and it works for sure - but not along with html2canvas.
If you right click on the image in the popup -> save image as, the saved image is valid.
The reason why I am using setAttribute and not simply src="..." is that if you assign the data src as string the image get corrupted.
Edit
I know :( I think you have to set HTTP Headers to force a download, and this can only be done by the server (correct me if I am wrong). I think of a "proxy" on the server like this mockup, download.php :
<?
$src=$_POST['src'];
header('Content-Type: image/png');
header('Content-Disposition: inline; filename="download.png"');
header('Content-Length: '.count($src));
echo $src;
?>
and call it by
var img = canvas.toDataURL("image/png");
window.open('download.php?src='+img);
But then you will face a lot of Request-URI Too Large-messages, unless all your canvas-images is in icon-size.
A second way - and probably the one that would work - would be to save img in a table on the server through ajax, eg calling a script with img src that saves it. When this call is finished, you could call another server script with the correct headers for image download, including the img src saved just before. But this is a more extensive approach you could try yourself..?

Here is a solution that builds on the accepted one to enable a download button without server-side code using jQuery.
https://codepen.io/nathansouza/pen/OXdJbo
function download(url){
var a = $("<a style='display:none' id='js-downloder'>")
.attr("href", url)
.attr("download", "test.png")
.appendTo("body");
a[0].click();
a.remove();
}
function saveCapture(element) {
html2canvas(element).then(function(canvas) {
download(canvas.toDataURL("image/png"));
})
}
$('#btnDownload').click(function(){
var element = document.querySelector("#capture");
saveCapture(element)
})

Related

How to display a base64 image that is inside a .txt file on the img src

Below is my img tag as you can see the src is a .txt file
<img id="loading" src="assets/images/loader_gif.txt" alt="Red dot" />
Below is the value of the loader_gif.txt its a base64 image.
The problem is the image doesn't show if I do it like this. But if I put directly the whole base64 on the src, it will display the image.
Is there anything I am missing?
A .txt is not a supported format to directly use as an image src, so that's not possible.
If the content inside your .txt doesn't change, I would recommend to directly use the base64 as an image src.
You already said you did it (which is working), so just for those people who don't know how to use base64 as image src. Heres an example
<img src="data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" />
In order to use the txt file however, you would have to load the file via Javascript, get the contents of the file and add the base64 as an image src.
XMLHttpRequest would be one way to get the contents.
const client = new XMLHttpRequest();
// instead of foo.txt you need to add your .txt file of course
client.open('GET', '/foo.txt');
client.onreadystatechange = () => {
// Make sure the request was done
if (client.readyState === XMLHttpRequest.DONE) {
const status = client.status;
// make sure the request ended up successfully
if (status === 0 || (status >= 200 && status < 400)) {
// If request was successful, grab the base64 from the response
const base64Image = client.responseText;
console.log(base64Image);
// add the base64 as image src
const image = document.querySelector('#loading');
image.src = base64Image;
} else {
// In case the request to get the .txt content failed, you can do something else.
// For example add a static fallback image
}
}
}
client.send();
One additional note:
There may be cases where the processing power of either client-side or server-side is (or even both) is very low. For example on low-end phones or shared web hosting.
So you have to know it could take a while until the image is displayed since all those steps have to run first:
get HTML content from page (here an empty / broken image is shown since nor src is set yet)
javascript need to be parsed and run
the HttpRequest will be executed
the server need to respond with the contents of your txt
JS need to add the image src
So in order to not have a broken image or flickering while all the image loading is done, you can deliver a placeholder image right in html. Something which is small in file size and static.
As soon as image.src = base64Image; runs, it would be replaced.
But in your case, it's saying "loader_gif", so I guess it's already for some loading action. Having a placeholder image until a loader image is being loaded via Javascript seems a bit "over the top" for a loading action.
Your use-case is not much different than having the browser load the actual image just as it does any other resources. I assume you have already considered having the image as an actual image.
Because the image is not really an image, you need to manage that. In your case, it is "almost" in an image format, so the processing is minimal, meaning you just need to get the data from the file and set it at the src of the image element.
<body>
<img id="loading" alt="Red dot" />
<script>
fetch('/assets/images/loader_gif.txt').then(response => response.text())
.then(b64img => {
document.getElementById('loading').src = b64img;
})
</script>
</body>

Save screenshot of a DIV as and image

How to take screenshot of a DIV which contain more than one images? Actually I am dragging images into DIV and want to take screenshot using Jquery or Javascript but without using server side scripting language.
Assuming you have a button to click (to trigger the capture), and that the images are on the same domain, load the html2canvas JS file, then add this:
$('#btn').click(function() {
html2canvas($('#DIV'), {
onrendered: function(canvas) {
//do something with the canvas element - upload, append to a display element, etc. For example:
var myImage = canvas.toDataURL("image/png");
window.open(myImage);
}
});
});

how to save DIV as Image with canvas2image with extension

I have done the following code to convert HTML Content(DIV) to save as Image (JPEG, PNG,GIF Etc) with below code.
<pre>
html2canvas($(".mainbox"), {
onrendered: function(canvas) {
theCanvas = canvas;
document.body.appendChild(canvas);
Canvas2Image.saveAsImage(canvas);
$("#FinalImage").append(canvas);
}
});
</pre>
I have also included html2canvas.js,base64.js and canvas2image.js in my page. At the end Image is shown in #FinalImage DIV and browser ask me to save it in my drive up to now all are working fine.
Now the question is name of the saved image has no Extension, every time I need to go to the image and assign the Extension(".jpg",".png" etc...). Is there any solution to set extension by default when user saves from the browser.
Thanks in advance.
I have done same functionality for capturing signature. This is different from your approach. but this code snippet may help you. plz comment if u need whole source code.
var canvas = document.getElementById(<canvas element id>)// get canvas element
var dataURL = canvas.toDataURL("image/png");// convert to img, specify extension
document.getElementById(<new image id>).src = dataURL; // write as an image
In line two I specified png.there you can change the extension of image. Hope it helps

How do I set the image source to a Picture from 'Pictures' library?

I'm currently using a File Picker to get a picture, using the example code from the Quickstart Tutorial: Accessing files with file pickers to select the picture.
This works fine, the problem comes when I try to use the selected image on screen, using an HTML img tag.
openPicker.pickSingleFileAsync().then(
function (file) {
if (file) {
var picture = document.getElementById("pictureId");
picture.src = new Windows.Foundation.Uri(file.path);
}
}
);
The picture's file.path is in the form of C:\Users\<user>\Pictures\example.jpg
I've tried using:
picture.src = file.path
picture.src = new Windows.Foundation.Uri(file.path)
I've also tried copying the path directly to the <img> tag to make sure it's not a screen refresh issue, but it still doesn't load.
The corresponding HTML, if relevant, is:
<div>
<img id="pictureId" class="pictureClass" src="" />
<button id="addPictureButton" class="">Add Picture</button>
</div>
What am I missing here?
Perhaps try one of the following
picture.src = URL.createObjectURL(file);
OR
picture.src = window.URL.createObjectURL(file);
References
createObjectURL method: http://msdn.microsoft.com/library/windows/apps/hh453196
How can I draw an image from the HTML5 File API on Canvas?

Pre Load images to display later on click event jQuery

I have a web page where lots of images called from server using image
scr attribute.
I have created a function like which is triggered by td click.
function GoToStep(stepNo) {
var imgSrc = $("#h1" + stepNo).val();
$(".img_vertical").css("background-image", "url(" + imgSrc + ")");
}
Now the problem is this. For slower connections the images come after some
moment.
Can I pre load images to avoid waiting time when user clicks
td?
I have seen some jquery function to pre load images.
Kindly give some idea how can I achieve it.
Pre-loading an image is equivalent to loading an image but never displaying it. So, you can easily do it like this:
<img src="image.png" alt="" style="display:none;"/>
Now this image will be loaded as soon as the html starts rendering. Whenever you need to use this image as a display or background, just set the address to image.png and it will automatically be fetched from browser's cache.
This can be done using some javascript functions. Quoting from another question.
function preload(arrayOfImages) {
$(arrayOfImages).each(function(){
$('<img/>')[0].src = this;
// Alternatively you could use:
// (new Image()).src = this;
});
}
// Usage:
preload([
'img/imageName.jpg',
'img/anotherOne.jpg',
'img/blahblahblah.jpg'
]);
Explanation of how javascript preloaders work (different question)
[...] The way it works is simply by creating a new Image object and setting
the src of it, the browser is going to go grab the image. We're not
adding this particular image to the browser, but when the time comes
to show the image in the page via whatever method we have setup, the
browser will already have it in its cache and will not go fetch it
again. [...]
So in your case, you should use something like
$(function() {
// Do stuff when DOM is ready
preload([
'img/bg1.jpg',
'img/bg2.jpg',
'img/bg3.jpg'
]);
});

Categories

Resources