最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Convert a base64 to a file in Javascript - Stack Overflow

programmeradmin4浏览0评论

The goal is to transform a base64 string into a sendable jpg file, I cant use the html input type file but i have to serve in the same format. I am bit lost with file generation. (I am on a client side mobile app).

This is what i have:

 file = "data:image/jpg;base64,#{imageData}"

imageData is the base64 string

There is a way to transform this into a valid file?

The goal is to transform a base64 string into a sendable jpg file, I cant use the html input type file but i have to serve in the same format. I am bit lost with file generation. (I am on a client side mobile app).

This is what i have:

 file = "data:image/jpg;base64,#{imageData}"

imageData is the base64 string

There is a way to transform this into a valid file?

Share Improve this question edited Mar 23, 2014 at 10:59 Imnl asked Mar 23, 2014 at 10:32 ImnlImnl 4561 gold badge6 silver badges18 bronze badges 2
  • The first and last sentences of your question differ. (jpg vs html file) Perhaps you should consider editing your question, such that it is no longer ambiguous. That said, I've used the fileWriter object in the past when working with Chrome. (No idea if other browsers support it now) html5rocks./en/tutorials/file/filesystem – enhzflep Commented Mar 23, 2014 at 10:49
  • Edited, i think is no longer ambiguous. I have read that article before but i havent found the way to turn a string into a file instance. Thanks for your response. – Imnl Commented Mar 23, 2014 at 11:08
Add a ment  | 

1 Answer 1

Reset to default 3

Disclaimer: Produces an invalid result (close, but invalid)

I've done the reverse earlier last week - that is, load an image as binary data (to get around the requirement to run file from localhost).

In it, I:

  • loaded the file
  • base64 converted it
  • added a pre-amble to the base64 string
  • set the constructed string to be the src of an img element

This worked just fine. Upon reading your question, I tried to simply reverse the process. I was however, unsuccessfull somewhere. The data is extracted from the image correctly, then somewhere afterwards (I think in the call to atob that un-encodes it) the data is messed-up.

The saved files are an unexpected size, have an added char before "%PNG" and have some missing data in the middle of the file. I'm rather perplexed at this point, to be honest.

Anyhow, here's the code I've tried:

1. Code to read a file and stuff the data into an element

// fileVar is an object as returned by <input type='file'>
// imgElem is an <img> element - (doesn't need to be added to the DOM)
function loadImgFromFile(fileVar, imgElem)
{
    var fileReader = new FileReader();
    fileReader.onload = onFileLoaded;
    fileReader.readAsBinaryString(fileVar);
    function onFileLoaded(fileLoadedEvent)
    {
        var result,data;
        data = fileLoadedEvent.target.result;
        result = "data:";
        result += fileVar.type;
        result += ";base64,";
        result += btoa(data);
        imgElem.src = result;
    }
}

2. Attempt to grab data from an image/canvas and force the download of it using a programmer-supplied filename.

<!doctype html>
<html>
<head>
<script>
function byId(e){return document.getElementById(e)}
function newEl(tag){return document.createElement(tag)}
window.addEventListener('load', onPageLoaded, false);

function onPageLoaded(evt)
{
    var imgElem = byId('srcImg');
    imgElem.onload = function(){saveImgAsFile( byId('srcImg'), "myImage.png" );};

        // simple result of canvas.toDataURL() called on a 5x5 pixel image of a '+'
    imgElem.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHklEQVQIW2NkQID/QCYjiAsmoABFEMRBAThVYmgHAAhoBQWHhfyYAAAAAElFTkSuQmCC"; 

    // use the below line instead of the one above, if you wish to assign an actual image file, rather than the result of call to canvas.toDataURL()
    // the base64 string allows me to keep it all in the one file, also, to run if opened via a double-click, rather than having to run from localhost
//  imgElem.src = "img/1x1.png";
}

function saveImgAsFile(imgElem, fileName)
{
    // get a base64 encoded string from an image element
    var srcElem = imgElem;
    var dstCanvas = newEl('canvas');
    dstCanvas.width = srcElem.naturalWidth;
    dstCanvas.height = srcElem.naturalHeight;
    var ctx = dstCanvas.getContext('2d');
    ctx.drawImage(srcElem,0,0);
    var imgSrcStr = dstCanvas.toDataURL();

    // extract the image type
    var colonPos = imgSrcStr.indexOf(":");
    var semiColonPos = imgSrcStr.indexOf(";");
    var imgType = imgSrcStr.slice(colonPos+1, semiColonPos);
    console.log("image type: " + imgType);

    // extract the image data
    var maPos = imgSrcStr.indexOf(',');
    var base64ImgString = imgSrcStr.slice(maPos + 1);
    console.log("Data: " + base64ImgString);

    // holds the data that is actually written to disk for this image
    //** I think the error occurs during this step **//
    var unencodedImage = atob(base64ImgString);

    var imgFileAsBlob = new Blob( [unencodedImage], {type: imgType} );
    var fileNameToUse = fileName;

    var downloadLink = newEl('a');
    downloadLink.download = fileNameToUse;
    downloadLink.innerHTML = "Download File";
    if (window.webkitURL != null)
    {
        // Chrome allows the link to be clicked
        // without actually adding it to the DOM.
        downloadLink.href = window.webkitURL.createObjectURL(imgFileAsBlob);
    }
    else
    {
        // Firefox requires the link to be added to the DOM
        // before it can be clicked.
        downloadLink.href = window.URL.createObjectURL(imgFileAsBlob);
        downloadLink.onclick = destroyClickedElement;
        downloadLink.style.display = "none";
        document.body.appendChild(downloadLink);
    }
    downloadLink.click();
}

/*

function saveTextAsFile()
{
    var textToWrite = "This is just some random content";
    var textFileAsBlob = new Blob([textToWrite], {type:'text/plain'})
    var fileNameToSaveAs = "myFile.txt";

    var downloadLink = document.createElement("a");
    downloadLink.download = fileNameToSaveAs;
    downloadLink.innerHTML = "Download File";
    if (window.webkitURL != null)
    {
        // Chrome allows the link to be clicked
        // without actually adding it to the DOM.
        downloadLink.href = window.webkitURL.createObjectURL(textFileAsBlob);
    }
    else
    {
        // Firefox requires the link to be added to the DOM
        // before it can be clicked.
        downloadLink.href = window.URL.createObjectURL(textFileAsBlob);
        downloadLink.onclick = destroyClickedElement;
        downloadLink.style.display = "none";
        document.body.appendChild(downloadLink);
    }
    downloadLink.click();
}
*/
function destroyClickedElement(event)
{
    document.body.removeChild(event.target);
}
</script>
</head>
<body>
    <img id='srcImg'/>
</body>
</html>
发布评论

评论列表(0)

  1. 暂无评论