简体   繁体   English

如何从Blob或BlobURL获取dataURL

[英]How to get dataURL from Blob or BlobURL

I need to take a ScreenShot of a div and need to send it to server(Java) to store.The existing code in my company project used Html2Canvas.js where it's getting the element(div,body ...) and returning the base64 dataURI, it's working fine but freezing the application in Chrome. 我需要获取一个div的ScreenShot并将其发送到服务器(Java)进行存储。我公司项目中的现有代码使用Html2Canvas.js来获取元素(div,body ...)并返回base64 dataURI,它工作正常,但将应用程序冻结在Chrome中。 So i am looking for some other solution and found the below code from stack overflow. 所以我正在寻找其他解决方案,并从堆栈溢出中找到了以下代码。

 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"/> 

Here url i am getting is Blob-Url (blob:https%3A//fiddle.jshell.net/a5b366a2-ff0c-4c7b-9b20-a80395d7f536) which i am able to use as img src or if i directly open that url in a new tab it's also opening. 我在这里获得的网址是Blob-Url(blob:https%3A // fiddle.jshell.net / a5b366a2-ff0c-4c7b-9b20-a80395d7f536),我可以将其用作img src或直接在其中打开该网址一个新的标签页也正在打开。 Is there anyway to get the base64 dataUri like this (data:image/png;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAA) from that blob URL or Blob object ? 无论如何,是否可以从blob对象中获取像这样的base64 dataUri(data:image / png; base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o / XBs / fNwfjZ0frl3 / zy7 //// wAAAAA Blob)?

@thepio is right about how to get a dataURI from a Blob : use a FileReader and its readAsDataURL() method. @thepio关于如何从Blob获取dataURI是正确的:使用FileReader及其readAsDataURL()方法。
This will give you a base64 encoded dataURI representation of the Blob/File. 这将为您提供Blob /文件的base64编码的 dataURI表示形式。

But, let's take a step back from what you are doing : 但是,让我们退后一步:
You are using a hack to get some kind of a screenshot of your HTML markup, using SVG's foreignObject . 您正在使用hack使用SVG的foreignObject来获取HTML标记的屏幕截图。

You absolutely don't need the Blob, nor the base64 version to show this in an <img> element : 您绝对不需要Blob,也不需要base64版本在<img>元素中显示此内容:
You just need to set the header of your dataURI to 'data:image/svg+xml; charset=utf8, ' 您只需要将dataURI的标头设置为'data:image/svg+xml; charset=utf8, ' 'data:image/svg+xml; charset=utf8, ' and then append your svg markup, this will save up to 30% of data size. 'data:image/svg+xml; charset=utf8, ' ,然后附加您的svg标记,这将节省多达30%的数据量。
Some characters need to be encoded though, so you can just call encodeURIComponent(yourSVGMarkup) . 不过,有些字符需要进行编码,因此您可以仅调用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" /> 

But this will only save an svg version, which won't work in IE<11 since these browsers didn't support the foreignObject element. 但这只会保存一个svg版本,该版本在IE <11中不起作用,因为这些浏览器不支持foreignObject元素。

I guess that what you want is a raster version. 我想您想要的是光栅版本。

For this, you could try to draw your svg on a canvas, using the drawImage method, and then call one of the canvas' export methods ( toDataURL() or toBlob() ). 为此,您可以尝试使用drawImage方法在画布上绘制svg,然后调用画布的导出方法之一( toDataURL()toBlob() )。

But this will taint the canvas in Safari 9, since they have some security issue with foreignObject and on IE<Edge which had a security issue with svg in general. 但这会污染Safari 9中的画布,因为它们与foreignObject以及IE <Edge在svg上均存在安全问题时存在一些安全问题。 Tainting the canvas will make its export methods unavailable, and the whole operation a failure. 污染画布将使其导出方法不可用,并且整个操作将失败。

Also, even in browsers that would support it, there is an other big limitation : 此外,即使在支持该功能的浏览器中,也存在另一个很大的限制:

  • Your elements inside the dataURI version are out of your document, and aren't able to request any other external resource (CSS, fonts, images...) which means that you will need to append it (or a dataURI encoded version for the two lasts) inside the svg markup before transforming it to a dataURI. 您的dataURI版本中的元素不在您的文档中,并且无法请求任何其他外部资源(CSS,字体,图片...),这意味着您需要附加它(或转换为dataURI之前,在svg标记内)。

Maybe less important but some browser's default styling will disappear on some elements (mostly inputs). 也许不太重要,但是某些元素(主要是输入)上某些浏览器的默认样式将消失。

So in your case, I would refrain myself to use this hack. 因此,就您而言,我将避免使用此技巧。
The only acceptable way to get a raster version of your HTML elements is to draw it using the canvas drawing methods, just like html2canvas and other libraries do. 获得HTML元素的光栅版本的唯一可接受的方法是使用画布绘制方法进行绘制,就像html2canvas和其他库一样。
So I would try to fix the current issue which doesn't seem normal. 因此,我将尝试解决似乎不正常的当前问题。

If you don't need a raster version, the easiest way is to just save the HTML markup in your db, then append it in your document (be sure you cleaned it though). 如果不需要光栅版本,最简单的方法是将HTML标记保存在数据库中,然后将其附加到文档中(但请确保已将其清除)。

You could use FileReader and do it like this: 您可以使用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"/> 

Documentation says this about readAsDataURL : 文档说了有关readAsDataURL

Starts reading the contents of the specified Blob, once finished, the result attribute contains a data: URL representing the file's data. 开始读取指定Blob的内容,完成后,result属性包含一个数据:表示文件数据的URL。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM