如何从Blob或BlobURL获取dataURL

时间:2016-05-24 11:39:59

标签: javascript html5 canvas blob data-url

我需要使用一个div的ScreenShot并需要将它发送到服务器(Java)来存储。我公司项目中的现有代码使用Html2Canvas.js来获取元素(div,body ...)和返回base64 dataURI,它工作正常但冻结Chrome中的应用程序。所以我正在寻找其他解决方案,并从堆栈溢出中找到以下代码。

var data = '<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">' +
           '<foreignObject width="100%" height="100%">' +
           '<div xmlns="http://www.w3.org/1999/xhtml" style="height:200px;width:200px;background-color:red;font-size:40px">' +
             '<em></em> l ' + 
             '<span style="color:white; text-shadow:0 0 2px blue;">' +
             '</span>' +
           '</div>' +
           '</foreignObject>' +
           '</svg>';

var DOMURL = window.URL || window.webkitURL || window;
var svg = new Blob([data], {type: 'image/svg+xml;charset=utf-8'});
var url = DOMURL.createObjectURL(svg);
document.getElementById("image1").src=url;
<img id='image1' width="200px" height="200px"/>

我在这里获取的是Blob-Url(blob:https%3A // fiddle.jshell.net / a5b366a2-ff0c-4c7b-9b20-a80395d7f536),我可以将其用作img src或直接打开它在新标签中的网址也打开了。 无论如何从这个blob URL或Blob对象获取这样的base64 dataUri(data:image / png; base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o / XBs / fNwfjZ0frl3 / zy7 //// wAAAAA)?

2 个答案:

答案 0 :(得分:3)

@thepio关于如何从Blob获取dataURI是正确的:使用FileReader及其readAsDataURL()方法。
这将为您提供Blob /文件的 base64编码 dataURI表示。

但是,让我们从你正在做的事情中退一步:
您正在使用 hack 来使用SVG foreignObject获取某种HTML标记的屏幕截图。

您绝对不需要Blob,也不需要base64版本在<img>元素中显示: 您只需将dataURI的标题设置为'data:image/svg+xml; charset=utf8, ',然后附加svg标记,这样可以节省高达30%的数据量。
有些字符需要编码,因此您只需拨打encodeURIComponent(yourSVGMarkup)

var svgString = '<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">' +
  '<foreignObject width="100%" height="100%">' +
  '<div xmlns="http://www.w3.org/1999/xhtml" style="height:200px;width:200px;background-color:red;font-size:40px">' +
  '<em></em> l ' +
  '<span style="color:white; text-shadow:0 0 2px blue;">' +
  'I\'m white'+
  '</span>' +
  '</div>' +
  '</foreignObject>' +
  '</svg>';

var dataURI = 'data:image/svg+xml; charset=utf8, ' + encodeURIComponent(svgString);

img.src = dataURI;
<img id="img" />

但是这只会保存一个svg版本,因为这些浏览器不支持foreignObject元素,所以在IE&lt; 11中无效。

我想你想要的是一个光栅版本。

为此,您可以尝试使用drawImage方法在画布上绘制svg,然后调用其中一个画布的导出方法(toDataURL()toBlob())。

但是这会污染Safari 9中的画布,因为它们与foreignObject和IE&lt; Edge存在一些安全问题,一般来说与svg存在安全问题。污染画布会使其导出方法不可用,整个操作失败。

此外,即使在支持它的浏览器中,还有另一个很大的限制:

  • 您的dataURI版本中的元素不在您的文档中,并且无法请求任何其他外部资源(CSS,字体,图像......),这意味着您需要附加它(或者dataURI编码)在将svg标记转换为dataURI之前,svg标记内的两个标签的版本。

可能不太重要但是某些浏览器的默认样式会在某些元素上消失(主要是输入)。

所以在你的情况下,我会克制自己使用这个黑客 获取HTML元素的栅格版本的唯一可接受方法是使用画布绘制方法绘制它,就像html2canvas和其他库一样。 所以我会尝试修复当前看似不正常的问题。

如果您不需要光栅版本,最简单的方法是在您的数据库中保存HTML标记,然后将其附加到您的文档中(请确保您已将其清除)。

答案 1 :(得分:2)

你可以使用FileReader并像这样:

var data = '<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">' +
           '<foreignObject width="100%" height="100%">' +
           '<div xmlns="http://www.w3.org/1999/xhtml" style="height:200px;width:200px;background-color:red;font-size:40px">' +
             '<em></em> l ' + 
             '<span style="color:white; text-shadow:0 0 2px blue;">' +
             '</span>' +
           '</div>' +
           '</foreignObject>' +
           '</svg>';

var DOMURL = window.URL || window.webkitURL || window;
var svg = new Blob([data], {type: 'image/svg+xml;charset=utf-8'});
var url = DOMURL.createObjectURL(svg);

var base64data;

var reader = new window.FileReader();
 reader.readAsDataURL(svg); 
 reader.onloadend = function() {
   base64data = reader.result; 
   document.getElementById("image1").src=base64data;
 }
<img id='image1' width="200px" height="200px"/>

文档说明readAsDataURL

  

开始读取指定Blob的内容,完成后,result属性包含一个数据:表示文件数据的URL。