3

I hava a dynamically generated image on my page like so:

<img id="my_image" src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEA/gD+AAD/etc............" />

Instead of telling my users to right click on the image and hit save I want to expose a download link which when clicked will prompt the image to be downloaded. How to achieve this?

Initially my attempt with thus in js:

var path = $('#my_image').attr('src');
window.open('./download.php?file=' + path);

and in download.php:

<?php
    header('Content-Description: File Transfer');
    header("Content-type: application/octet-stream");
    header("Content-disposition: attachment; filename= " . $_GET['file'] . "");
?>

<img src="<?= $_GET['file'] ?>" />

But problem is, Base64 url stirngs are so large it exceeds the GET request byte limit.

I am open to a solution in either JavaScript or PHP.

ACJ
  • 2,499
  • 3
  • 24
  • 27
  • Even if the Base64 string did fit in the query string, that PHP code would not do what you expect it to do. – icktoofay Aug 21 '12 at 02:59
  • 1
    make the src point to a php script with the headers etc for downloading. include the image or use file_get_contents() to get the image. –  Aug 21 '12 at 02:59
  • possible duplicate of [How do I make a jpg image download like a pdf file does?](http://stackoverflow.com/questions/6073242/how-do-i-make-a-jpg-image-download-like-a-pdf-file-does) hope it helps as well bruv `:)` – Tats_innit Aug 21 '12 at 03:17
  • How did you generate the inline image in the first place? – Ja͢ck Aug 21 '12 at 03:40
  • @Jack HTML5 FileReader is used to grab the image into the user's browser and the editing he/she does is done through Canvas JavaScript. The JS plugin is what generates the Base64 image code. –  Aug 22 '12 at 00:03

2 Answers2

8

Try this in download.php:

<?php
    header('Content-Description: File Transfer');
    header("Content-type: application/octet-stream");
    header("Content-disposition: attachment; filename= Image.jpg");
    exit(base64_decode($_POST['data'])); //url length is limited, use post instead
?>

And use this for a form:

<form method="post" action="./download.php">
  <input type="hidden" name="data" value="/9j/4AAQSkZJRgABAgEA/gD+AAD/etc............" />
  <a href="#" onclick="this.parentNode.submit();return false;">Download</a>
</form>

like Dagon said this is not the best way to go because submitting the form would be like uploading the whole image.

unloco
  • 6,928
  • 2
  • 47
  • 58
  • 1
    posting the whole image from the server to the client back to the server then back to the client seems a *little* pointless –  Aug 21 '12 at 03:30
  • @UnLoCo so this does prompt an image download. But when the downloaded image is opened it is empty (0 bytes in length). RE the performance issue: the image is never on the server. I am using HTML5 FileReader API to load the image on the client's browser and Canvas JavaScript to allow them to edit it. The JavaScript generates the Base64 image. So maybe there is no performance issue beyond posting the long string. The download should still be served from the client's own browser (correct?) –  Aug 22 '12 at 00:01
  • It worked for me, and i downloaded a viewable image. make sure your are filling the data field before the user clicks on the link and thus submits the form ! – unloco Aug 22 '12 at 01:26
2

Turns out one of the other questions did have the answer:

Browser/HTML Force download of image from src="data:image/jpeg;base64..."

I am doing it strictly on the client sde like so:

$('a#download_image').on('click', function() {
    var url = $('#my_image').attr('src').replace(/^data:image\/[^;]/, 'data:application/octet-stream');
    location.href = url;
});
Community
  • 1
  • 1