代码之家  ›  专栏  ›  技术社区  ›  Museful

http使用fetch api放置与标记的src属性相关联的文件[duplicate]

  •  0
  • Museful  · 技术社区  · 6 年前

    我有一个带有一些图像的常规html页面(只是常规的 <img /> HTML标记)。我想得到他们的内容,最好是base64编码,不需要重新下载图像(即,它已经被浏览器加载,所以现在我想要的内容)。

    我很想用Greasemonkey和Firefox来实现这个目标。

    0 回复  |  直到 5 年前
        1
  •  392
  •   Community c0D3l0g1c    7 年前

    笔记 只有当图像与页面来自同一个域,或具有 crossOrigin="anonymous" 属性和服务器支持CORS。它也不会给你原始文件,而是一个重新编码的版本。如果需要使结果与原始结果相同,请参见 Kaiido's answer 是的。


    您需要创建一个具有正确尺寸的canvas元素,并使用 drawImage 功能。然后你可以使用 toDataURL 函数获取具有base-64编码图像的data:url。请注意,图像必须完全加载,否则您将返回一个空(黑色,透明)图像。

    可能是这样的。我从来没有写过greasemonkey脚本,所以您可能需要调整代码以在该环境中运行。

    function getBase64Image(img) {
        // Create an empty canvas element
        var canvas = document.createElement("canvas");
        canvas.width = img.width;
        canvas.height = img.height;
    
        // Copy the image contents to the canvas
        var ctx = canvas.getContext("2d");
        ctx.drawImage(img, 0, 0);
    
        // Get the data-URL formatted image
        // Firefox supports PNG and JPEG. You could check img.src to
        // guess the original format, but be aware the using "image/jpg"
        // will re-encode the image.
        var dataURL = canvas.toDataURL("image/png");
    
        return dataURL.replace(/^data:image\/(png|jpg);base64,/, "");
    }
    

    获取jpeg格式的图像在较旧版本(大约3.5)的firefox上不起作用,因此如果你想支持它,你需要检查兼容性。如果不支持编码,则默认为“image/png”。

        2
  •  73
  •   Ionică Bizău    9 年前

    此函数获取URL,然后返回图像base64

    function getBase64FromImageUrl(url) {
        var img = new Image();
    
        img.setAttribute('crossOrigin', 'anonymous');
    
        img.onload = function () {
            var canvas = document.createElement("canvas");
            canvas.width =this.width;
            canvas.height =this.height;
    
            var ctx = canvas.getContext("2d");
            ctx.drawImage(this, 0, 0);
    
            var dataURL = canvas.toDataURL("image/png");
    
            alert(dataURL.replace(/^data:image\/(png|jpg);base64,/, ""));
        };
    
        img.src = url;
    }
    

    这样称呼: getBase64FromImageUrl("images/slbltxt.png")

        3
  •  49
  •   lorefnon    6 年前

    很久以后,但这里没有一个答案是完全正确的。

    在画布上绘制时,传递的图像是未压缩+全部预乘的。
    导出时,用不同的算法对其进行解压缩或重新压缩,然后取消相乘。

    在此过程中,所有浏览器和设备都会出现不同的舍入错误
    (见 Canvas fingerprinting )中。

    所以如果你想要一个base64版本的图像文件,他们必须 请求 它再次出现(大部分时间它将来自缓存),但这次是一个blob。

    然后你可以用 FileReader 以arraybuffer或dataurl的形式读取。

    function toDataURL(url, callback){
        var xhr = new XMLHttpRequest();
        xhr.open('get', url);
        xhr.responseType = 'blob';
        xhr.onload = function(){
          var fr = new FileReader();
        
          fr.onload = function(){
            callback(this.result);
          };
        
          fr.readAsDataURL(xhr.response); // async call
        };
        
        xhr.send();
    }
    
    toDataURL(myImage.src, function(dataURL){
      result.src = dataURL;
    
      // now just to show that passing to a canvas doesn't hold the same results
      var canvas = document.createElement('canvas');
      canvas.width = myImage.naturalWidth;
      canvas.height = myImage.naturalHeight;
      canvas.getContext('2d').drawImage(myImage, 0,0);
    
      console.log(canvas.toDataURL() === dataURL); // false - not same data
      });
    <img id="myImage" src="https://dl.dropboxusercontent.com/s/4e90e48s5vtmfbd/aaa.png" crossOrigin="anonymous">
    <img id="result">
        4
  •  17
  •   Zaptree    7 年前

    使用fetch的kaido的答案的一个更现代的版本是:

    function toDataURL(url) {
      return fetch(url)
          .then((response)=> {
            return response.blob();
          })
          .then(blob=> {
            return URL.createObjectURL(blob);
          });
    }
    

    https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch

        5
  •  1
  •   Kamil Kiełczewski    5 年前

    使用 onload 加载后转换图像的事件

    function loaded(img) {
      let c = document.createElement('canvas')
      c.getContext('2d').drawImage(img, 0, 0)
      msg.innerText= c.toDataURL();
    }
    pre { word-wrap: break-word; width: 500px; white-space: pre-wrap; }
    <img onload="loaded(this)" src="https://cors-anywhere.herokuapp.com/http://lorempixel.com/200/140" crossorigin="anonymous"/>
    
    <pre id="msg"></pre>
        6
  •  -1
  •   Parth Raval    7 年前

    function encodeImageFileAsURL(cb) {
        return function() {
            var file = this.files[0];
            var reader = new FileReader();
            reader.onloadend = function() {
                cb(reader.result);
            }
            reader.readAsDataURL(file);
        }
    }
    
    $('#inputFileToLoad').change(encodeImageFileAsURL(function(base64Img) {
        $('.output')
            .find('textarea')
            .val(base64Img)
            .end()
            .find('a')
            .attr('href', base64Img)
            .text(base64Img)
            .end()
            .find('img')
            .attr('src', base64Img);
    }));
    @import url('//netdna.bootstrapcdn.com/bootstrap/3.1.0/css/bootstrap.min.css'); body{ padding: 20px; }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <h2>Input</h2>
    <form class="input-group" id="img2b64">
        <input id="inputFileToLoad" type="file" onchange="encodeImageFileAsURL();" />
    </form>
    <hr>
    下面是工作小提琴的例子: upload & get Image Data
        7
  •  -3
  •   KepHec    6 年前

    在HTML5中,最好使用这个:

    {
    //...
    canvas.width = img.naturalWidth; //img.width;
    canvas.height = img.naturalHeight; //img.height;
    //...
    }