Hur kan jag konvertera en bild till en Base64-sträng med JavaScript?
Jag behöver konvertera min bild till en Base64-sträng så att jag kan skicka min bild till en server.
Finns det någon JavaScript-fil för detta? Annars, hur kan jag konvertera det?
Svar #1
Det finns flera tillvägagångssätt som du kan välja mellan:
1. Tillvägagångssätt: FileReader
Ladda bilden som blob via XMLHttpRequest och använd FileReader API (readAsDataURL()) för att konvertera den till en dataURL:
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)
})Det här kodexemplet kan också implementeras med WHATWG fetch API:
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)
})Dessa tillvägagångssätt:
- ha bättre kompression
- fungerar även för andra filtyper
Webbläsarstöd:
- http://caniuse.com/#feat=filereader
- http://caniuse.com/#feat=fetch
Tips: För att konvertera lokala filer kan du använda live-server. När den har startats i mappen som innehåller bilden du vill omvandla, öppna URL:en i webbläsaren och använd utvecklarkonsolen för att konvertera bilden till base 64.
2. Metod: Canvas (för äldre webbläsare)
Ladda bilden till ett bildobjekt, måla den på en icke-förorenad canvas och konvertera sedan canvasen tillbaka till en dataURL.
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)
}
)I detalj
Stödda indataformat:
image/png, image/jpeg, image/jpg, image/gif, image/bmp, image/tiff, image/x-icon, image/svg+xml, image/webp, image/xxx
Stödda utdataformat:
image/png, image/jpeg, image/webp(chrome)
Webbläsarstöd:
- http://caniuse.com/#feat=canvas
Internet Explorer 10 (Internet Explorer 10 fungerar bara med bilder från samma ursprung)
3. Tillvägagångssätt: Bilder från det lokala filsystemet
Om du vill konvertera bilder från användarens filsystem behöver du ta ett annat tillvägagångssätt. Använd FileReader API:
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)" />Svar #2
Du kan använda HTML5 <canvas> för det:
Skapa en canvas, ladda din bild i den och använd sedan toDataURL() för att få Base64-representationen (egentligen är det en data:-URL, men den innehåller den Base64-kodade bilden).
Svar #3
Detta utdrag kan konvertera din sträng, bild och till och med videofil till Base64-strängdata.
<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>Svar #4
I princip, om din bild är
<img id='Img1' src='someurl'>
då kan du konvertera det som
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();
Svar #5
Här är vad jag gjorde:
// 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);
}
Och här är hur du använder det
base64( $('input[type="file"]'), function(data){
console.log(data.base64)
})
Svar #6
Jag upptäckte att det säkraste och mest pålitliga sättet att göra det är att använda FileReader().
Demo: Bild till 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>
UPPDATERING: samma kod med kommentarer för @AnniekJ:s begäran:
<!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() {
// Get the file objects that was selected by the user from myinput - a file picker control
var selectedfile = document.getElementById("myinput").files;
// Check that the user actually selected file/s from the "file picker" control
// Note - selectedfile is an array, hence we check it`s length, when length of the array
// is bigger than 0 than it means the array containes file objects
if (selectedfile.length > 0) {
// Set the first file object inside the array to this variable
// Note: if multiple files are selected we can iterate over all of the selectedfile array using a for loop - BUT in order to not make this example complicated we only take the first file object that was selected
var imageFile = selectedfile[0];
// Set a filereader object to asynchronously read the contents of files (or raw data buffers) stored on the user's computer, using File or Blob objects to specify the file or data to read.
var fileReader = new FileReader();
// We declare an event of the fileReader class (onload event) and we register an anonimous function that will be executed when the event is raised. it is "trick" we preapare in order for the onload event to be raised after the last line of this code will be executed (fileReader.readAsDataURL(imageFile);) - please read about events in javascript if you are not familiar with "Events"
fileReader.onload = function(fileLoadedEvent) {
// AT THIS STAGE THE EVENT WAS RAISED
// Here we are getting the file contents - basiccaly the base64 mapping
var srcData = fileLoadedEvent.target.result;
// We create an image html element dinamically in order to display the image
var newImage = document.createElement('img');
// We set the source of the image we created
newImage.src = srcData;
// ANOTHER TRICK TO EXTRACT THE BASE64 STRING
// We set the outer html of the new image to the div element
document.getElementById("dummy").innerHTML = newImage.outerHTML;
// Then we take the inner html of the div and we have the base64 string
document.getElementById("txt").value = document.getElementById("dummy").innerHTML;
}
// This line will raise the fileReader.onload event - note we are passing the file object here as an argument to the function of the event
fileReader.readAsDataURL(imageFile);
}
}
</script>
</body>
</html>
Svar #7
Om du har ett filobjekt kommer denna enkla funktion att fungera:
function getBase64 (file, callback) {
const reader = new FileReader();
reader.addEventListener('load', () => callback(reader.result));
reader.readAsDataURL(file);
}
Exempel på användning:
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
});
