如何下载Base64编码的图片?

102

我有一张从服务器获取的base64编码的图片,我想通过JavaScript强制下载它。这可能吗?

10个回答

124
  1. 如果你想使用JavaScript(没有后端)下载它,请使用:

window.location.href = 'data:application/octet-stream;base64,' + img;

其中 img 是您的 base64 编码图像。

如果您想允许用户指定文件名,请使用 a 标签的 download 属性:

<a download="FILENAME.EXT" href="data:image/png;base64,asdasd...">Download</a>
  • 注意:下载属性不被非常旧的浏览器支持

2
谢谢,但第一个选项不会强制下载。 - Mario
12
windows.location.href不能下载图像,而是显示所有文本。 - Charlie
只需编辑第二个解决方案中的a标签,添加id="d",然后调用document.getElementById("d").click(); - rubo77
没有人应该使用第二个选项,它是一个非常沉重的选项。就像在下载一个1080px编码的jpg文件时会使普通计算机变得很慢。 - Harsh Jadon
对我来说,window.location.href可以工作,但我需要添加文件名。我该怎么做? - Amazon

102

使用JavaScript实现这个简单的方法...

    var a = document.createElement("a"); //Create <a>
    a.href = "data:image/png;base64," + ImageBase64; //Image Base64 Goes here
    a.download = "Image.png"; //File name Here
    a.click(); //Downloaded file


5
如果文件太大,比如有4M个字符,就会出现错误。 - canbax
谢谢你的回答!我的下载出现了“无网络”错误,导致失败。虽然我确定网络连接是正常的。我是不是漏掉了什么? - Suraj Ingle

44

使用下面的函数非常简单:

// Parameters:
// contentType: The content type of your file. 
//              its like application/pdf or application/msword or image/jpeg or
//              image/png and so on
// base64Data: Its your actual base64 data
// fileName: Its the file name of the file which will be downloaded. 

function downloadBase64File(contentType, base64Data, fileName) {
     const linkSource = `data:${contentType};base64,${base64Data}`;
     const downloadLink = document.createElement("a");
     downloadLink.href = linkSource;
     downloadLink.download = fileName;
     downloadLink.click();
}

2
谢谢你!你是救命恩人。 顺便说一下,我们不需要使用 `data:${contentType};base64,${base64Data}`; ,只需要使用 `${base64Data}`; 就足够了。 - ahmednawazbutt
使用长度大于1000000的base64时性能较差。 - Rodrigo Vieira

10

我从 Chrome 的源代码中找到了如何拍摄全屏截图的解决方案。

const base64string = "";
const pageImage = new Image();
pageImage.src = 'data:image/png;base64,' + base64string;
pageImage.onload = function() {
    const canvas = document.createElement('canvas');
    canvas.width = pageImage.naturalWidth;
    canvas.height= pageImage.naturalHeight;

    const ctx = canvas.getContext('2d');
    ctx.imageSmoothingEnabled = false;
    ctx.drawImage(pageImage, 0, 0);
    console.log(canvas, pageImage)
    saveScreenshot(canvas);
}
function saveScreenshot(canvas) {
    let fileName = "image"
    const link = document.createElement('a');
    link.download = fileName + '.png';
    console.log(canvas)
    canvas.toBlob(function(blob) {
        console.log(blob)
        link.href = URL.createObjectURL(blob);
        link.click();
    });
};


我知道你没写这个。而且我愿意相信它能够工作。但是……真的吗?创建虚拟链接来进行虚拟点击?看起来非常糟糕。 - Travis Bear
@TravisBear 这里就是:https://source.chromium.org/chromium/chromium/src/+/master:third_party/devtools-frontend/src/front_end/emulation/DeviceModeView.js?q=saveScreenshot - Sentient

9

我不知道是否已经晚了回答这个问题,但是我认为更好的解决方案可能是这个。

  1. Create a file from the base64string

    const convertBase64ToFile = (base64String, fileName) => {
         let arr = base64String.split(',');
         let mime = arr[0].match(/:(.*?);/)[1];
         let bstr = atob(arr[1]);
         let n = bstr.length;
         let uint8Array = new Uint8Array(n);
         while (n--) {
            uint8Array[n] = bstr.charCodeAt(n);
         }
         let file = new File([uint8Array], fileName, { type: mime });
         return file;
    }
    
  2. Install File Saver from npm with

    npm install file-saver
    
  3. Import File Saver

    const { saveAs } = require('file-saver');
    /// OR 
    import { saveAs } from 'file-saver';
    
  4. Using File Saver download the file

    const downloadBase64Data = (base64String, fileName) => {
         let file = convertBase64ToFile(base64String, fileName);
         saveAs(file, fileName);
    }
    
如果这个答案对您有用,请点赞并将其标记为正确答案,以帮助其他人更轻松地找到它。

1
获取(base64文件) .then(res => res.blob()) .then(res => { saveAs(res, 'QR'); })可以节省一些代码行。 - Sudam Dissanayake
saveAs 返回任何 Promise 吗? - Rodrigo Vieira
@Slowaways,我猜它会返回一个在成功时解决的Promise。 - Garande
@Garande 返回undefined。 - Rodrigo Vieira
这个比 @Ehsan 的答案更高效吗? - Artur Müller Romanov
@ArturMüllerRomanov 这个程序非常高效,因为你不需要创建或绘制任何HTML元素。试用一下并发送你的反馈。 - Garande

8
在我的 Angular 应用中,我从服务器获得了 Base64 文件。
在 HTML 中:
<button type="button" (click)="downloadFile(fileName,base64data,fileType)"></button>

In Ts:-

  downloadFile(fileName:string,data: any,fileFormat:string): void {
    const linkSource = 'data:'+fileFormat+';base64'+data;
    const downloadLink = document.createElement("a");
    downloadLink.href = linkSource;
    downloadLink.download = fileName;
    downloadLink.click();
}

7
你可以尝试这个方法:
    <!doctype html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Download Text File DataURL Demo</title>
        <style>
            body{ font: menu; }
        </style>
        <script src='//js.zapjs.com/js/download.js'></script>
    </head>
    <body>
        <h1>Download Text File DataURL Demo</h1>
        <main></main>
        <script>
            download("data:application/octet-stream;base64,YOUR BASE64URL", "dlDataUrlText.jpeg", "application/octet-stream;base64");
        </script>
    </body>

</html>

下载标签使用包含的脚本下载图像。

您可以尝试此链接以进行参考:http://danml.com/download.html


2
攻击者目前可能会在js.zapjs.com上尝试安装危险程序,这些程序会窃取或删除您的信息。 - tscpp

2
如果您已经有了base64格式的图片,请在base64前面添加图片标签,并将其附加到元素中。"最初的回答"。
png64 = "data:image/" + png64; 
$('#downloadPNG').attr('href', png64);

在下载时,将要下载的文件名添加到download标签中。最初的回答。
<a download="chart.png" id="downloadPNG">Export img</a>

如果文件太大,例如4M个字符,它会出现错误。 - canbax
你可以试一下。尝试下载大图片。https://appuals.com/how-to-fix-failed-network-error-when-downloading-on-google-chrome/ - canbax
@canbax 可能是因为URL太长了吗?在这种情况下,你可以尝试一下这个:https://dev59.com/UGQo5IYBdhLWcg3wMs-2#36183085 - Kasper Seweryn
@KasperSeweryn 谢谢。我想我早就找到了那个。 - canbax

2

在我的React应用程序中,我从API获取了base64图像,将其存储在全局属性中,并借助<a>标签下载它。

<a href={`data:application/octet-stream;base64,${this.props.base64image}`} download={"imageName"}>Click to Download the image</a>

0

首先:这个问题非常依赖于浏览器!我尝试了很多种方法,最终得出了以下答案:

您应该将base64数据放在IMG元素的src标签中: 如何在HTML中显示Base64图像? 然后,在以下浏览器中,您可以右键单击图像并单击“保存图像...”(或类似选项):

  • Chrome 79
  • Edge 44
  • Firefox 71
  • IE 11
  • Safari 13

在使用Chrome和Firefox的Android上也可以。 最大的文件是23 MB的PNG文件,在IE 11和Safari 13中工作正常。但是Firefox和Chrome也可以处理86 MB的JPEG。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接