web-dev-qa-db-fra.com

Comment enregistrer une image base64 sur le disque de l'utilisateur en utilisant JavaScript?

J'ai converti le contenu source du <img> balise html vers une base64String en utilisant JavaScript. L'image était clairement affichée. Maintenant, je veux enregistrer cette image sur le disque de l'utilisateur en utilisant javascript.

<html>
    <head>
    <script>
        function saveImageAs () {
            var imgOrURL;
            embedImage.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA" +
                             "AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO" +
                             "9TXL0Y4OHwAAAABJRU5ErkJggg==";
            imgOrURL = embedImage;
            if (typeof imgOrURL == 'object')
                imgOrURL = embedImage.src;
            window.win = open(imgOrURL);
            setTimeout('win.document.execCommand("SaveAs")', 0);
        }
    </script>
    </head>
    <body>
        <a href="#" ONCLICK="saveImageAs(); return false" >save image</a>

        <img id="embedImage" alt="Red dot">
    </body>
</html>

Ce code a bien fonctionné lorsque j'ai défini le chemin de l'image comme source pour <img> balise html. Cependant, lorsque je passe la source, base64String ne fonctionne pas.

Comment réaliser ce que je veux?

25
vengatesh

Juste pour permettre à l'utilisateur de télécharger l'image ou un autre fichier, vous pouvez utiliser l'attribut HTML5 download.

Téléchargement de fichier statique

<a href="/images/image-name.jpg" download>
<!-- OR -->
<a href="/images/image-name.jpg" download="new-image-name.jpg"> 

Téléchargement de fichier dynamique

Dans les cas où une image est demandée dynamiquement, il est possible d'émuler un tel téléchargement.

Si votre image est déjà chargée et que vous avez le base64 source alors:

saveBase64AsFile(base64, fileName) {

    var link = document.createElement("a");

    link.setAttribute("href", base64);
    link.setAttribute("download", fileName);
    link.click();
}

Sinon, si le fichier image est téléchargé en tant que Blob, vous pouvez utiliser FileReader pour le convertir en Base64:

saveBlobAsFile(blob, fileName) {

    var reader = new FileReader();

    reader.onloadend = function () {    
        var base64 = reader.result ;
        var link = document.createElement("a");

        link.setAttribute("href", base64);
        link.setAttribute("download", fileName);
        link.click();
    };

    reader.readAsDataURL(blob);
}

Mauvaise nouvelle! Attention: IE n'est pas supporté: lien Caniuse

31

En JavaScript, vous ne pouvez pas avoir un accès direct au système de fichiers. Cependant, vous pouvez faire en sorte que le navigateur ouvre une fenêtre de dialogue permettant à l'utilisateur de choisir l'emplacement d'enregistrement. Pour ce faire, utilisez la méthode replace avec votre Base64String et remplacez "image/png" avec "image/octet-stream":

"data:image/png;base64,iVBORw0KG...".replace("image/png", "image/octet-stream");

De plus, les navigateurs compatibles W3C proposent 2 méthodes pour travailler avec des données codées en base64 et binaires:

Vous les trouverez probablement utiles en quelque sorte ...


Voici une version refactorisée de ce dont je comprends que vous avez besoin:

window.addEventListener('DOMContentLoaded', () => {
  const img = document.getElementById('embedImage');
  img.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA' +
    'AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO' +
    '9TXL0Y4OHwAAAABJRU5ErkJggg==';

  img.addEventListener('load', () => button.removeAttribute('disabled'));
  
  const button = document.getElementById('saveImage');
  button.addEventListener('click', () => {
    window.location.href = img.src.replace('image/png', 'image/octet-stream');
  });
});
<!DOCTYPE html>
<html>

<body>
  <img id="embedImage" alt="Red dot" />
  <button id="saveImage" disabled="disabled">save image</button>
</body>

</html>
22
John Doe