JavaScript kullanarak bir görüntüyü Base64 dizesine nasıl dönüştürebilirim?


Yanıtlar:


182

HTML5'i <canvas>bunun için kullanabilirsiniz :

Bir tuval oluşturun, resminizi içine yükleyin ve ardından toDataURL()Base64 temsilini almak için kullanın (aslında bir data:URL'dir, ancak Base64 kodlu görüntüyü içerir).


3
Does toDataURLgibi geri aramaları üzerinde vermek kontrolünü done/fail/alwaysXHR'nin için olduğu gibi?
Jeroen

2 veya daha fazla tuvali tek bir PNG olarak çıkarabilir miyiz?
techie_28

140
Lütfen bir jsbin yapabilir veya en azından buraya bir kod yazabilir misiniz?
vsync

9
CORS ihlali durumunda bu yaklaşım başarısız olur. Bunun dışında, bu çözüm soruyu ele almalıdır.
Revanth Kumar

İşte bunun için npm paketi
user3517175

851

Aralarından seçim yapabileceğiniz birden fazla yaklaşım vardır:

1. Yaklaşım: FileReader

Görüntüyü XMLHttpRequest aracılığıyla blob olarak yükleyin ve bir dataURL'ye dönüştürmek için FileReader API'sını kullanın :

function toDataURL(url, callback) {
  var xhr = new XMLHttpRequest();
  xhr.onload = function() {
    var reader = new FileReader();
    reader.onloadend = function() {
      callback(reader.result);
    }
    reader.readAsDataURL(xhr.response);
  };
  xhr.open('GET', url);
  xhr.responseType = 'blob';
  xhr.send();
}

toDataURL('https://www.gravatar.com/avatar/d50c83cc0c6523b4d3f6085295c953e0', function(dataUrl) {
  console.log('RESULT:', dataUrl)
})

Bu kod örneği WHATWG getirme API'sı kullanılarak da uygulanabilir :

const toDataURL = url => fetch(url)
  .then(response => response.blob())
  .then(blob => new Promise((resolve, reject) => {
    const reader = new FileReader()
    reader.onloadend = () => resolve(reader.result)
    reader.onerror = reject
    reader.readAsDataURL(blob)
  }))


toDataURL('https://www.gravatar.com/avatar/d50c83cc0c6523b4d3f6085295c953e0')
  .then(dataUrl => {
    console.log('RESULT:', dataUrl)
  })

Bu yaklaşımlar:

  • tarayıcı desteğinde eksiklik
  • daha iyi sıkıştırma
  • diğer dosya türleri için de çalışır

Tarayıcı Desteği:


2. Yaklaşım: Tuval

Görüntüyü bir Görüntü Nesnesine yükleyin, korumasız bir tuval üzerine boyayın ve tuvali tekrar dataURL'ye dönüştürün.

function toDataURL(src, callback, outputFormat) {
  var img = new Image();
  img.crossOrigin = 'Anonymous';
  img.onload = function() {
    var canvas = document.createElement('CANVAS');
    var ctx = canvas.getContext('2d');
    var dataURL;
    canvas.height = this.naturalHeight;
    canvas.width = this.naturalWidth;
    ctx.drawImage(this, 0, 0);
    dataURL = canvas.toDataURL(outputFormat);
    callback(dataURL);
  };
  img.src = src;
  if (img.complete || img.complete === undefined) {
    img.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
    img.src = src;
  }
}

toDataURL(
  'https://www.gravatar.com/avatar/d50c83cc0c6523b4d3f6085295c953e0',
  function(dataUrl) {
    console.log('RESULT:', dataUrl)
  }
)

Detayda

Desteklenen giriş formatları:

image/png, image/jpeg, image/jpg, image/gif, image/bmp, image/tiff, image/x-icon, image/svg+xml, image/webp,image/xxx

Desteklenen çıktı biçimleri:

image/png, image/jpeg, image/webp(Krom)

Tarayıcı Desteği:


3. Yaklaşım: Yerel dosya sisteminden görüntüler

Kullanıcı dosya sisteminden görüntüleri dönüştürmek istiyorsanız, farklı bir yaklaşım izlemeniz gerekir. FileReader API'sını kullanın :

function encodeImageFileAsURL(element) {
  var file = element.files[0];
  var reader = new FileReader();
  reader.onloadend = function() {
    console.log('RESULT', reader.result)
  }
  reader.readAsDataURL(file);
}
<input type="file" onchange="encodeImageFileAsURL(this)" />


56
Benim için krom çalışmıyor:Image from origin **** has been blocked from loading by Cross-Origin Resource Sharing policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://fiddle.jshell.net' is therefore not allowed access.
DickieBoy

5
Bunun başkalarını açması durumunda, bu rutin, döndürdüğü dizede "data: image / jpg; base64" başlığını içerir, bu yüzden eklemenize gerek yoktur.
Chris Rae

1
Warnin2: bir şey içerikle uğraşır. yol boyunca bir yerde, en azından bazı görüntülerde firefox 35'de benim için olan verilerin bozulmasına / değiştirilmesine (belki de çok fazla olmasa da), base64 php'nin aynı şekilde oluşturduğu base64'ten farklı görüntüsü.
hanshenrik

1
Evet bu doğru. Görüntüyü gerçekten bir tuval Öğesine ( developer.mozilla.org/en-US/docs/Web/API/… ) çektiğimiz ve daha sonra bir dataURL'ye ( developer.mozilla.org/en- ABD / dokümanlar / Web / API / HTMLCanvasElement /… ).
HaNdTriX

1
Yaklaşım: FileReader (2) Canvas'a yaklaşmaktan daha hızlı çalışır. Büyük fotoğraflar üzerinde test edildi. Umarım bazıları için faydalı olacaktır.
Max

83

Bu snippet, dizenizi, resminizi ve hatta video dosyanızı Base64 dize verilerine dönüştürebilir.

<input id="inputFileToLoad" type="file" onchange="encodeImageFileAsURL();" />
<div id="imgTest"></div>
<script type='text/javascript'>
  function encodeImageFileAsURL() {

    var filesSelected = document.getElementById("inputFileToLoad").files;
    if (filesSelected.length > 0) {
      var fileToLoad = filesSelected[0];

      var fileReader = new FileReader();

      fileReader.onload = function(fileLoadedEvent) {
        var srcData = fileLoadedEvent.target.result; // <--- data: base64

        var newImage = document.createElement('img');
        newImage.src = srcData;

        document.getElementById("imgTest").innerHTML = newImage.outerHTML;
        alert("Converted Base64 version is " + document.getElementById("imgTest").innerHTML);
        console.log("Converted Base64 version is " + document.getElementById("imgTest").innerHTML);
      }
      fileReader.readAsDataURL(fileToLoad);
    }
  }
</script>


3
Sadece harika değil, aynı zamanda etki alanları arası orijin problemini de atlıyor! Bununla, kullanıcıların bir URL'den kendi resimlerini veya resimlerini sağlamalarına izin verebilirsiniz (Windows bunu kendi başına getireceğinden), tuval üzerine çizebilir ve .toDataURL () vb. Çok teşekkürler!
ElDoRado1239

Merhaba, bu etki alanları arası sorunlarla karşılaşmadan uzak bir url'den yüklenen bir resme nasıl uygulanabilir? Thanks
guthik

Bu bazen Chrome 78.0.3904.97'de çalışır, ancak diğer zamanlarda sekmeyi kilitler.
Dshiz

28

Temel olarak, resminiz

<img id='Img1' src='someurl'>

o zaman şu şekilde dönüştürebilirsiniz

var c = document.createElement('canvas');
var img = document.getElementById('Img1');
c.height = img.naturalHeight;
c.width = img.naturalWidth;
var ctx = c.getContext('2d');

ctx.drawImage(img, 0, 0, c.width, c.height);
var base64String = c.toDataURL();

5
Ne yazık ki bu yalnızca yerel görüntüler için işe yarayacaktır, uzak bir görüntü kullanmayı denerseniz (web'den bir tane seçerseniz) bunu (firefox) konsoluna yazar: 'SecurityError: İşlem güvensizdir'.
user2677034

1
Diğer resimler üzerinde çalışabilir, ancak bu sitenin CORS ayarlarına bağlıdır ve şu şekilde belirtilmelidir<img id='Img1' src='someurl' crossorigin='anonymous'>
Mike

Firefox'ta bu güvenliği geçici olarak devre dışı bırakabilirsiniz. "
About

21

İşte yaptığım şey:

// Author James Harrington 2014
function base64(file, callback){
  var coolFile = {};
  function readerOnload(e){
    var base64 = btoa(e.target.result);
    coolFile.base64 = base64;
    callback(coolFile)
  };

  var reader = new FileReader();
  reader.onload = readerOnload;

  var file = file[0].files[0];
  coolFile.filetype = file.type;
  coolFile.size = file.size;
  coolFile.filename = file.name;
  reader.readAsBinaryString(file);
}

Ve işte böyle kullanıyorsun

base64( $('input[type="file"]'), function(data){
  console.log(data.base64)
})

6
btoa nedir? :)
Alexander Mills


14

Bunu yapmanın en güvenli ve güvenilir yolunun kullanmak olduğunu gördüm FileReader().

Gösteri: Image to Base64

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
  </head>
  <body>
    <input id="myinput" type="file" onchange="encode();" />
    <div id="dummy">
    </div>
    <div>
      <textarea style="width:100%;height:500px;" id="txt">
      </textarea>
    </div>
    <script>
      function encode() {
        var selectedfile = document.getElementById("myinput").files;
        if (selectedfile.length > 0) {
          var imageFile = selectedfile[0];
          var fileReader = new FileReader();
          fileReader.onload = function(fileLoadedEvent) {
            var srcData = fileLoadedEvent.target.result;
            var newImage = document.createElement('img');
            newImage.src = srcData;
            document.getElementById("dummy").innerHTML = newImage.outerHTML;
            document.getElementById("txt").value = document.getElementById("dummy").innerHTML;
          }
          fileReader.readAsDataURL(imageFile);
        }
      }
    </script>
  </body>
</html>

6

Bir dosya nesneniz varsa, bu basit işlev çalışır:

function getBase64 (file, callback) {

    const reader = new FileReader();

    reader.addEventListener('load', () => callback(reader.result));

    reader.readAsDataURL(file);
}

Kullanım örneği:

getBase64(fileObjectFromInput, function(base64Data){
    console.log("Base64 of file is", base64Data); // Here you can have your code which uses Base64 for its operation, // file to Base64 by oneshubh
});



4

Bu kodu deneyin:

Bir dosya yükleme değişikliği olayı için şu işlevi çağırın:

$("#fileproof").on('change', function () {
    readImage($(this)).done(function (base64Data) { $('#<%=hfimgbs64.ClientID%>').val(base64Data); });
});

function readImage(inputElement) {
    var deferred = $.Deferred();

    var files = inputElement.get(0).files;

    if (files && files[0]) {
        var fr = new FileReader();
        fr.onload = function (e) {
            deferred.resolve(e.target.result);
        };
        fr.readAsDataURL(files[0]);
    } else {
        deferred.resolve(undefined);
    }

    return deferred.promise();
}

Base64 verilerini kullanmak için gizli saklayın.


1
Merhaba Ravi! Göreceli olarak yeni olduğunu görüyorum. Orijinal poster özellikle jQuery, lodash ve benzeri bir kütüphane çözümü istemedikçe, herkesin çıplak minimumları, bu durumda düz javascript'i kullanarak cevap vermesi daha iyidir. Hala jQuery ile katkıda bulunmak istiyorsanız, lütfen girişinizde bol miktarda açık olun :)
Carles Alcolea

3
uploadProfile(e) {

    let file = e.target.files[0];
    let reader = new FileReader();

    reader.onloadend = function() {
        console.log('RESULT', reader.result)
    }
    reader.readAsDataURL(file);
}

0

Dojo Toolkit kullanıyorsanız, Base64'e kodlama veya kod çözme için doğrudan bir yol sunar.

Bunu dene:

Bir bayt dizisini dojox.encoding.base64 kullanarak kodlamak için:

var str = dojox.encoding.base64.encode(myByteArray);

Base64 kodlu bir dizenin kodunu çözmek için:

var bytes = dojox.encoding.base64.decode(str);

2
@DownVoter - Sevgili, negatif bir şeyi işaretliyorsanız hatayı belirtmek daha iyi. böylece biri gelişebilir. Bildiğim kadarıyla ben de bir JavaScript kütüphanesinde dojo anlıyorum o zaman dojo kullanmak için izin verilirse, kesinlikle bu yaklaşımı kullanabilirsiniz.
Vikash Pandey
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.