converter base64 em imagem em javascript / jquery

94

Eu escrevi um código para captura de imagens usando javascript / jquery. Abaixo está o código:

function capture_image(){ 
    alert("capture_image");
    var p = webcam.capture();
    webcam.save();           
    alert("capture complete "+p); //getting true here


     var img = canvas.toDataURL("image");
    var item_image = img.replace(/^data:image\/(png|jpg);base64,/, "") ; 
    alert("item_image"+item_image);
}

O item_image imprime o formato base64, Como converter essa base64 em imagem e como usar esse caminho no cliente javascript.

Estou pesquisando muitos sites no Google, mas não está funcionando e esse código não é adequado para minhas necessidades.

user2996174
fonte
Se você deseja que os dados base64 como uma imagem, você terá que processar a string no lado do servidor e usar o caminho da imagem salva no lado do servidor. Você pode fazer isso usando o método Ajax Post.
Rayon de
Para ressuscitar uma postagem antiga, dê uma olhada aqui: stackoverflow.com/a/19644105
Luke Madhanga

Respostas:

139

Você pode simplesmente criar um Imageobjeto e colocar a base64 como sua src, incluindo a data:image...parte como esta :

var image = new Image();
image.src = 'data:image/png;base64,iVBORw0K...';
document.body.appendChild(image);

É o que eles chamam de "URIs de dados" e aqui está a tabela de compatibilidade para paz interior.

Joseph
fonte
1
Você pode explicar claramente significa que a imagem retorna o elemento html do objeto e como ler como imagem
user2996174
Aqui estou escrevendo img tag <img id = "myImg" src = "d: \\ face.png" border = 1> e estou usando este código document.getElementById ('myImg'). Src = item_image; // <img tag > mas não está funcionando
user2996174
Isso porque seu código removeu a data:image...parte de item_image.
Joseph de
8
Acho que estou procurando a mesma coisa que o OP. Acredito que ele deseja que o URL da imagem aponte para um .png, não para a string codificada em base64 original. Procurando uma conversão em algum lugar lá dentro, se possível.
John
1
@John você teria que salvar, fazer upload e hospedar o arquivo em algum lugar, pois o URI dos dados não tem referência de onde o arquivo veio originalmente.
Gabe O'Leary
18

Este não é exatamente o cenário do OP, mas uma resposta a alguns dos comentadores. É uma solução baseada em Cordova e Angular 1, que deve ser adaptável a outros frameworks como jQuery. Ele fornece um Blob de dados Base64 que você pode armazenar em algum lugar e referenciá-lo do lado do cliente javascript / html.

Ele também responde à pergunta original sobre como obter uma imagem (arquivo) dos dados de Base 64:

A parte importante é a conversão de Base 64 - Binária:

function base64toBlob(base64Data, contentType) {
    contentType = contentType || '';
    var sliceSize = 1024;
    var byteCharacters = atob(base64Data);
    var bytesLength = byteCharacters.length;
    var slicesCount = Math.ceil(bytesLength / sliceSize);
    var byteArrays = new Array(slicesCount);

    for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
        var begin = sliceIndex * sliceSize;
        var end = Math.min(begin + sliceSize, bytesLength);

        var bytes = new Array(end - begin);
        for (var offset = begin, i = 0; offset < end; ++i, ++offset) {
            bytes[i] = byteCharacters[offset].charCodeAt(0);
        }
        byteArrays[sliceIndex] = new Uint8Array(bytes);
    }
    return new Blob(byteArrays, { type: contentType });
}

O fatiamento é necessário para evitar erros de falta de memória.

Funciona com arquivos jpg e pdf (pelo menos foi o que testei). Deve funcionar com outros mimetypes / contenttypes também. Verifique os navegadores e suas versões que você deseja, eles precisam ser compatíveis com Uint8Array, Blob e atob.

Este é o código para gravar o arquivo no armazenamento local do dispositivo com Cordova / Android:

...
window.resolveLocalFileSystemURL(cordova.file.externalDataDirectory, function(dirEntry) {

                    // Setup filename and assume a jpg file
                    var filename = attachment.id + "-" + (attachment.fileName ? attachment.fileName : 'image') + "." + (attachment.fileType ? attachment.fileType : "jpg");
                    dirEntry.getFile(filename, { create: true, exclusive: false }, function(fileEntry) {
                        // attachment.document holds the base 64 data at this moment
                        var binary = base64toBlob(attachment.document, attachment.mimetype);
                        writeFile(fileEntry, binary).then(function() {
                            // Store file url for later reference, base 64 data is no longer required
                            attachment.document = fileEntry.nativeURL;

                        }, function(error) {
                            WL.Logger.error("Error writing local file: " + error);
                            reject(error.code);
                        });

                    }, function(errorCreateFile) {
                        WL.Logger.error("Error creating local file: " + JSON.stringify(errorCreateFile));
                        reject(errorCreateFile.code);
                    });

                }, function(errorCreateFS) {
                    WL.Logger.error("Error getting filesystem: " + errorCreateFS);
                    reject(errorCreateFS.code);
                });
...

Gravando o próprio arquivo:

function writeFile(fileEntry, dataObj) {
    return $q(function(resolve, reject) {
        // Create a FileWriter object for our FileEntry (log.txt).
        fileEntry.createWriter(function(fileWriter) {

            fileWriter.onwriteend = function() {
                WL.Logger.debug(LOG_PREFIX + "Successful file write...");
                resolve();
            };

            fileWriter.onerror = function(e) {
                WL.Logger.error(LOG_PREFIX + "Failed file write: " + e.toString());
                reject(e);
            };

            // If data object is not passed in,
            // create a new Blob instead.
            if (!dataObj) {
                dataObj = new Blob(['missing data'], { type: 'text/plain' });
            }

            fileWriter.write(dataObj);
        });
    })
}

Estou usando as versões mais recentes do Cordova (6.5.0) e dos plug-ins:

Espero que isso coloque todos aqui na direção certa.

Jürgen 'Kashban' Wahlmann
fonte
13

Tem que adicionar isso com base na resposta de @Joseph. Se alguém quiser criar um objeto de imagem:

var image = new Image();
image.onload = function(){
   console.log(image.width); // image is loaded and we have image width 
}
image.src = 'data:image/png;base64,iVBORw0K...';
document.body.appendChild(image);
Jare25
fonte
1
Boa decisão. Se eu fizer isso console.log(image.width);diretamente após definir src, obtenho 0 no primeiro carregamento no Chrome, mas nas recargas de página subsequentes, obtenho a largura real da imagem. Parece que o navegador está armazenando a imagem em cache, mas o primeiro carregamento precisa ser ouvido porque tecnicamente definir src é assíncrono, o que significa que você não pode confiar em ter uma imagem imediatamente após definir src como uma string base64. O código continuará a ser executado em ordem síncrona com uma imagem vazia, a menos que você verifique se ela está carregada corretamente.
Frank
11
var src = "data:image/jpeg;base64,";
src += item_image;
var newImage = document.createElement('img');
newImage.src = src;
newImage.width = newImage.height = "80";
document.querySelector('#imageContainer').innerHTML = newImage.outerHTML;//where to insert your image
MRTC
fonte
1
Esta é a única resposta que realmente funcionou !!!! Agora, como enviar isso como uma solicitação AJAX?
Raz
11

Html

<img id="imgElem"></img>

Js

string baseStr64="/9j/4AAQSkZJRgABAQE...";
imgElem.setAttribute('src', "data:image/jpg;base64," + baseStr64);
Tran Anh Hien
fonte
0

Uma maneira rápida e fácil:

function paintSvgToCanvas(uSvg, uCanvas) {

    var pbx = document.createElement('img');

    pbx.style.width  = uSvg.style.width;
    pbx.style.height = uSvg.style.height;

    pbx.src = 'data:image/svg+xml;base64,' + window.btoa(uSvg.outerHTML);
    uCanvas.getContext('2d').drawImage(pbx, 0, 0);

}
John Haugeland
fonte