przekonwertować base64 na obraz w javascript / jquery

90

Napisałem kod do przechwytywania obrazu za pomocą javascript / jquery Poniżej znajduje się kod:

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);
}

Item_image drukuje format base64, jak przekonwertować ten base64 na obraz i jak używać tej ścieżki po stronie klienta javascript.

Przeszukuję w Google tak wiele witryn, ale to nie działa, a ten kod nie jest odpowiedni dla moich wymagań.

user2996174
źródło
Jeśli chcesz, aby dane base64 były obrazem, będziesz musiał przetworzyć ciąg po stronie serwera i użyć ścieżki zapisanego obrazu po stronie serwera. Możesz to zrobić za pomocą metody Ajax Post.
Rayon
Aby wskrzesić stary post, zajrzyj tutaj: stackoverflow.com/a/19644105
Luke Madhanga

Odpowiedzi:

128

Możesz po prostu utworzyć Imageobiekt i umieścić base64 jako jego src, łącznie z takądata:image... częścią :

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

Nazywają to „URI danych”, a oto tabela zgodności dla wewnętrznego spokoju.

Józefa
źródło
1
Czy możesz jasno wyjaśnić, czy obraz zwraca element html obiektu i jak czytać jako obraz
user2996174
Tutaj piszę tag img <img id = "myImg" src = "d: \\ face.png" border = 1> i używam tego kodu document.getElementById ('myImg'). Src = item_image; // <img tag > ale to nie działa
user2996174
To dlatego, że twój kod usunął data:image...część z item_image.
Joseph
8
Myślę, że szukam tego samego OP. Wydaje mi się, że chce, aby adres URL obrazu wskazywał na plik .png, a nie oryginalny ciąg zakodowany w base64. Szukasz konwersji gdzieś tam, jeśli to możliwe.
John
1
@John, musiałbyś gdzieś zapisać, przesłać i hostować plik, ponieważ identyfikator URI danych nie ma odniesienia do miejsca, z którego pochodzi plik.
Gabe O'Leary
18

Nie jest to dokładnie scenariusz PO, ale odpowiedź na scenariusze niektórych komentatorów. Jest to rozwiązanie oparte o Cordova i Angular 1, które powinno być przystosowane do innych frameworków, takich jak jQuery. Daje ci Blob z danych Base64, które możesz gdzieś przechowywać i odwoływać się do niego z javascript / html po stronie klienta.

Odpowiada również na oryginalne pytanie, jak uzyskać obraz (plik) z danych Base 64:

Ważną częścią jest Base 64 - konwersja binarna:

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 });
}

Aby uniknąć błędów braku pamięci, wymagane jest cięcie na plasterki.

Działa z plikami jpg i pdf (przynajmniej to testowałem). Powinien działać również z innymi typami MIME / Contenttypes. Sprawdź przeglądarki i ich wersje, do których dążysz, muszą one obsługiwać Uint8Array, Blob i atob.

Oto kod do zapisania pliku w lokalnej pamięci urządzenia za pomocą 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);
                });
...

Pisanie samego pliku:

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);
        });
    })
}

Używam najnowszych wersji Cordova (6.5.0) i wtyczek:

Mam nadzieję, że to skierowało wszystkich tutaj we właściwym kierunku.

Jürgen „Kashban” Wahlmann
źródło
12

Muszę to dodać na podstawie odpowiedzi @ Josepha. Jeśli ktoś chce stworzyć obiekt obrazu:

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
źródło
1
Dobra decyzja. Jeśli robię to console.log(image.width);bezpośrednio po ustawieniu src, to przy pierwszym ładowaniu w Chrome otrzymuję 0, ale przy kolejnych przeładowaniach strony otrzymuję rzeczywistą szerokość obrazu. Wygląda na to, że przeglądarka buforuje obraz, ale to pierwsze ładowanie musi zostać wysłuchane, ponieważ technicznie ustawienie src jest asynchroniczne, co oznacza, że ​​nie można polegać na tym, że obraz będzie miał obraz natychmiast po ustawieniu src na ciąg base64. Kod będzie nadal wykonywał się w kolejności synchronicznej z pustym obrazem, chyba że upewnisz się, że jest poprawnie załadowany.
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
źródło
1
To jedyna odpowiedź, która faktycznie zadziałała !!!! Teraz, jak wysłać to jako żądanie AJAX?
Raz
10

HTML

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

Js

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

Jeden szybki i łatwy sposób:

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
źródło