[javascript] JavaScript로 이미지 데이터 URL을 가져 오시겠습니까?

일부 이미지가있는 일반 HTML 페이지가 있습니다 (일반 <img />HTML 태그 만). 이미지를 다시 다운로드 할 필요없이 base64로 인코딩 된 내용을 원합니다 (즉, 이미 브라우저에 의해로드되어 있으므로 내용을 원합니다).

Greasemonkey와 Firefox를 사용하여 달성하고 싶습니다.



답변

참고 : 이미지가 페이지와 동일한 도메인에 있거나 crossOrigin="anonymous"속성이 있고 서버가 CORS를 지원하는 경우에만 작동합니다 . 또한 원본 파일이 아니라 다시 인코딩 된 버전을 제공합니다. 결과가 원본과 동일해야하는 경우 Kaiido의 답변을 참조하십시오 .


올바른 치수의 캔버스 요소를 작성하고 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”입니다.


답변

이 함수는 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")


답변

오래지 않아 왔지만 여기에 대한 대답은 전적으로 정확하지 않습니다.

캔버스에 그릴 때 전달 된 이미지는 압축되지 않은 + 모든 미리 곱셈됩니다.
내보낼 때 다른 알고리즘으로 압축 또는 재 압축 된 후 곱하지 않습니다.

이 과정에서 발생하는 모든 브라우저 및 장치에 다른 반올림 오류가 발생합니다
( 캔버스 지문 참조 ).

따라서 이미지 파일의 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">


답변

fetch를 사용하는 최신 Kaikai 답변은 다음과 같습니다.

function toObjectUrl(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

편집 : 주석에서 지적했듯이 실제 DataURL 대신 로컬 시스템의 파일을 가리키는 객체 URL을 반환하므로 사용 사례에 따라 필요하지 않을 수 있습니다.

페치 및 실제 dataURL을 사용하기 위해 다음 답변을 볼 수 있습니다. https://stackoverflow.com/a/50463054/599602


답변

v / 심 / 샴

이미지가 이미로드되었거나로드되지 않은 경우이 “도구”가 유용 할 수 있습니다.

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-type및 / 또는 여기서 MDN 사양에 quality설명 된대로 이러한 인수 / 매개 변수를 생략 할 수 있습니다 .

이 JS를로드 한 경우 (필요할 때 이전) 다음 dataURL과 같이 간단하게 변환 할 수 있습니다.

HTML

<img src="/yo.jpg" onload="console.log(this.toDataURL('image/jpeg'))">

JS

console.log(document.getElementById("someImgID").toDataURL());

GPU 지문

비트의 “정확도”에 관심이있는 경우 @Kaiido의 답변에서 제공 한대로 필요에 맞게이 도구를 변경할 수 있습니다.


답변

onload로드 후 이벤트를 사용 하여 이미지 변환


답변

HTML5에서 이것을 더 잘 사용하십시오 :

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