-2

This seems like it should be incredibly simple, but I've searched for about 3 hours. I want to do something very simple. I have an <img> html element, which gets some data in the form of a base64 image that is stored only temporarily. All I want to do is take that image and save it as a jpeg when i click on a certain button. That's it.

so something as simple as (in pseudo code of course) :

x = document.getElementByID("myImgTagID").image.saveToFile(myPath)

I've tried 50 different things, from jquery to php handling of a form POST. All I want is something straightforward and simple that takes the contents of the image ie image.value and writes it to a jpeg or png.

And the problem is I'm not clever enough to figure it out even though I feel like I've gotten close a few times. help!

Jaydeep
  • 1,686
  • 1
  • 16
  • 29
Rocks
  • 107
  • 2
  • 12
  • jQuery and Ajax would be what you need – mplungjan Jul 15 '19 at 09:58
  • 1
    Possible duplicate of [Browser/HTML Force download of image from src="data:image/jpeg;base64..."](https://stackoverflow.com/questions/10473932/browser-html-force-download-of-image-from-src-dataimage-jpegbase64) – tevemadar Jul 15 '19 at 10:23

3 Answers3

0

This is not possible, because it's not secure. You can't just "save" something using Javascript, it would lead to people writing EXEs to your machine, which could cause all sorts of damage.

What you would have to do is take the base64 encoded image, send it to a server, then return it as a "real" JPG with the header Content-disposition: attachment; filename=whatever.jpg, which will make the browser prompt the user to save it, like a normal download. I don't know PHP, but this looks like a good start - How to save the jpg file from base64 data

<?php

// Create the image from the request parameter
$image = imagecreatefromstring(base64_decode($_GET['image']));

// Set the headers
header('Content-Disposition: attachment; filename=your_image.jpg');
header('Content-type: image/jpeg');

// Output the image
imagejpeg($image);

// Free up memory
imagedestroy($image);

?>

Usage:

<script>

// Attach the "on click" event to the button
document.getElementById('your_button').onclick = function() {

    // "redirect" the browser to download the image
    document.location('your_php_file.php?image=' + document.getElementById('your_img').src);

}

</script>
Vitani
  • 1,594
  • 1
  • 14
  • 28
  • PHP in such context is a content-generator language running on the webserver. That approach is not adaptable to OP's scenario (which would be right-click + "Save image as...", just from code). – tevemadar Jul 15 '19 at 10:15
  • 1
    The best answer is right-click + "save image as", for sure, but OP wants a button, and they mentioned attempting to use PHP to solve it, so I went down that route. – Vitani Jul 15 '19 at 10:18
  • Oh, I missed the php part. – tevemadar Jul 15 '19 at 10:19
0

Approach from the proposed duplicate, with some extensions:

function load(){
  a.download=nam.value;
  img.src=a.href=dat.value;
}
<a id="a" download="" href=""><img id="img" src=""></a>
<hr>
<input id="nam"><input id="dat"><button onclick="load()">Load</button><br>
Example1<br>red.png<br>
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==<br>
<br>
Example2<br>something.jpg<br>
data:image/jpeg;base64,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<br><br>

Usage: put a desired filename into the first box, a data uri (select complete line) in the second one, and click "Load". Then the snippet configures the anchor and image elements to display the image, and download it with the given filename when you click on it. Or at least in certain browsers (works in Chrome).

tevemadar
  • 12,389
  • 3
  • 21
  • 49
-1

Ok so i managed to solve it. Using snippets of several of the answers here, I also found an extremely helpful article on another site. Not sure if I am allowed to link to it (mods feel free to delete if not allowed) :

How to save a base64

Anyway, I was able to keep it super simple and not have to convert to octet and back or anything like that. Just used a variable to hold the base64 data, turned it into an ajax data object, and posted it to a php handler. Code below, for anyone who needs a solution like this :

First the js function called by a button click :

function saveThisImage() {
var image = avatar.src;
$.ajax({
  url:"../../saveImg.php",
  data:{ base64: image },
  type:"post",
  complete:function(){
    console.log("Ready");
  } }); }

and the php handler :

$baseFromJavascript = "data:image/png;".$_POST['base64'].",BBBFBfj42Pj4"; 
$base_to_php = explode(',', $baseFromJavascript);
$data = base64_decode($base_to_php[1]);
$filepath = "image99.png"; 
file_put_contents($filepath,$data);

where "image99.png" is simply a placeholder til i create a script to generate unique filenames for them. but that's all it took to make it work.

thanks for all the help guys, you pointed me in the right direction

Rocks
  • 107
  • 2
  • 12