用JavaScript获取图像数据网址?

时间:2009-06-01 08:43:42

标签: javascript image firefox greasemonkey base64

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

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

10 个答案:

答案 0 :(得分:389)

注意:仅当图片来自与页面相同的域,或者具有crossOrigin="anonymous"属性且服务器支持CORS时才有效。它也不会给你原始文件,而是一个重新编码的版本。如果您需要的结果与原始结果相同,请参阅Kaiido's answer


您需要创建具有正确尺寸的canvas元素,并使用drawImage函数复制图像数据。然后,您可以使用toDataURL函数来获取数据:具有base-64编码图像的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格式的图像不适用于Firefox的旧版本(大约3.5),因此如果您想支持它,则需要检查兼容性。如果不支持编码,则默认为“image / png”。

答案 1 :(得分:71)

此函数接受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")

答案 2 :(得分:42)

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

在画布上绘制时,传递的图像未经压缩+全部预乘 导出时,使用不同的算法对其进行未压缩或重新压缩,并且不成倍增加。

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

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

然后您可以使用FileReader将其作为ArrayBuffer或dataURL读取。

&#13;
&#13;
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
  });
&#13;
<img id="myImage" src="https://dl.dropboxusercontent.com/s/4e90e48s5vtmfbd/aaa.png" crossOrigin="anonymous">
<img id="result">
&#13;
&#13;
&#13;

答案 3 :(得分:23)

除了马修的回答之外,我想说image.width和image.height会返回图片的显示尺寸(并在将图片绘制到画布时裁剪图像)

使用naturalWidth和naturalHeight代替,它使用实际尺寸的图片。

请参阅http://www.whatwg.org/specs/web-apps/current-work/multipage/edits.html#dom-img-naturalwidth

答案 4 :(得分:15)

使用fetch的更现代版本的kaiido答案将是:

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)

使用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)

shiv / shim / sham

如果您的图片已经加载(或未加载),此“工具”可能会派上用场:

Object.defineProperty
(
    HTMLImageElement.prototype,'toDataURL',
    {enumerable:false,configurable:false,writable:false,value:function(m,q)
    {
        let c=document.createElement('canvas');
        c.width=this.naturalWidth; c.height=this.naturalHeight;
        c.getContext('2d').drawImage(this,0,0); return c.toDataURL(m,q);
    }}
);

..但是为什么?

这具有使用“已加载”图像数据的优点,因此不需要额外的请求。另外,它可以让最终用户(像您这样的程序员)决定 CORS 和/或mime-typequality-或者-您可以按照下面的说明忽略这些参数/参数 MDN 规范here

如果已加载此JS(在需要时),则转换为dataURL的过程很简单:

示例

HTML
<img src="/yo.jpg" onload="console.log(this.toDataURL('image/jpeg'))">
JS
console.log(document.getElementById("someImgID").toDataURL());

GPU指纹

如果您担心位的“准确性”,则可以根据@Kaiido的答案提供的方法来更改此工具,使其适合您的需求。

答案 7 :(得分:0)

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

答案 8 :(得分:0)

这就是您需要阅读的所有内容。

https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsBinaryString

mysql> WITH cte AS (
    -> SELECT
    -> ID,
    -> name,
    -> ROW_NUMBER() OVER (
    -> PARTITION BY
    -> name
    -> ORDER BY
    -> name
    -> ) row_num
    -> FROM
    -> discord.t1
    -> )
    -> DELETE FROM cte
    -> WHERE row_num >1;
ERROR 1288 (HY000): The target table cte of the DELETE is not updatable

答案 9 :(得分:-1)

在HTML5中最好使用此:

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