web-dev-qa-db-ger.com

NodeJS: Speichern eines base64-codierten Images auf der Festplatte

Meine Express-App empfängt ein Base64-kodiertes PNG-Format vom Browser (generiert aus der Zeichenfläche mit toDataURL ()) und schreibt es in eine Datei. Die Datei ist jedoch keine gültige Bilddatei, und das Dienstprogramm "Datei" identifiziert sie einfach als "Daten".

var body = req.rawBody,
  base64Data = body.replace(/^data:image\/png;base64,/,""),
  binaryData = new Buffer(base64Data, 'base64').toString('binary');

require("fs").writeFile("out.png", binaryData, "binary", function(err) {
  console.log(err); // writes out file without error, but it's not a valid image
});
117
mahemoff

Ich denke, Sie konvertieren die Daten etwas mehr als Sie benötigen. Wenn Sie den Puffer mit der richtigen Kodierung erstellt haben, müssen Sie nur den Puffer in die Datei schreiben.

var base64Data = req.rawBody.replace(/^data:image\/png;base64,/, "");

require("fs").writeFile("out.png", base64Data, 'base64', function(err) {
  console.log(err);
});

neuer Puffer (..., 'base64') konvertiert die Eingabezeichenfolge in einen Puffer, der nur ein Array von Bytes ist, indem er die Eingabe als Base64-kodierte Zeichenfolge interpretiert. Dann können Sie dieses Byte-Array einfach in die Datei schreiben.

Aktualisieren

Wie in den Kommentaren erwähnt, ist req.rawBody keine Sache mehr. Wenn Sie express/connect verwenden, sollten Sie die bodyParser()-Middleware und req.body verwenden. Wenn Sie dies unter Verwendung des Standardknotens tun, müssen Sie die eingehenden data-Ereignis Buffer-Objekte zusammenfassen und diese Bilddaten im Callback end analysieren.

246
loganfsmyth

dies ist meine vollständige Lösung, die jedes base64-Bildformat lesen und im richtigen Format in der Datenbank speichern kann:

    // Save base64 image to disk
    try
    {
        // Decoding base-64 image
        // Source: http://stackoverflow.com/questions/20267939/nodejs-write-base64-image-file
        function decodeBase64Image(dataString) 
        {
          var matches = dataString.match(/^data:([A-Za-z-+\/]+);base64,(.+)$/);
          var response = {};

          if (matches.length !== 3) 
          {
            return new Error('Invalid input string');
          }

          response.type = matches[1];
          response.data = new Buffer(matches[2], 'base64');

          return response;
        }

        // Regular expression for image type:
        // This regular image extracts the "jpeg" from "image/jpeg"
        var imageTypeRegularExpression      = /\/(.*?)$/;      

        // Generate random string
        var crypto                          = require('crypto');
        var seed                            = crypto.randomBytes(20);
        var uniqueSHA1String                = crypto
                                               .createHash('sha1')
                                                .update(seed)
                                                 .digest('hex');

        var base64Data = 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAZABkAAD/4Q3zaHR0cDovL25zLmFkb2JlLmN...';

        var imageBuffer                      = decodeBase64Image(base64Data);
        var userUploadedFeedMessagesLocation = '../img/upload/feed/';

        var uniqueRandomImageName            = 'image-' + uniqueSHA1String;
        // This variable is actually an array which has 5 values,
        // The [1] value is the real image extension
        var imageTypeDetected                = imageBuffer
                                                .type
                                                 .match(imageTypeRegularExpression);

        var userUploadedImagePath            = userUploadedFeedMessagesLocation + 
                                               uniqueRandomImageName +
                                               '.' + 
                                               imageTypeDetected[1];

        // Save decoded binary image to disk
        try
        {
        require('fs').writeFile(userUploadedImagePath, imageBuffer.data,  
                                function() 
                                {
                                  console.log('DEBUG - feed:message: Saved to disk image attached by user:', userUploadedImagePath);
                                });
        }
        catch(error)
        {
            console.log('ERROR:', error);
        }

    }
    catch(error)
    {
        console.log('ERROR:', error);
    }
18
Placeholder

AKTUALISIEREN

Ich habe diesen interessanten Link gefunden, wie Sie Ihr Problem in PHP lösen können. Ich denke, Sie haben vergessen, space durch +es zu ersetzen, wie im Link angegeben.

Ich habe diesen Kreis aus http://images-mediawiki-sites.thefullwiki.org/04/1/7/5/6204600836255205.png als Beispiel genommen, das wie folgt aussieht:

http://images-mediawiki-sites.thefullwiki.org/04/1/7/5/6204600836255205.png

Als Nächstes habe ich es durch http://www.greywyvern.com/code/php/binary2base64 durchgespielt, das mich zurückgegeben hat:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAAAAACPAi4CAAAAB3RJTUUH1QEHDxEhOnxCRgAAAAlwSFlzAAAK8AAACvABQqw0mAAAAXBJREFUeNrtV0FywzAIxJ3+K/pZyctKXqamji0htEik9qEHc3JkWC2LRPCS6Zh9HIy/AP4FwKf75iHEr6eU6Mt1WzIOFjFL7IFkYBx3zWBVkkeXAUCXwl1tvz2qdBLfJrzK7ixNUmVdTIAB8PMtxHgAsFNNkoExRKA+HocriOQAiC+1kShhACwSRGAEwPP96zYIoE8Pmph9qEWWKcCWRAfA/mkfJ0F6dSoA8KW3CRhn3ZHcW2is9VOsAgoqHblncAsyaCgcbqpUZQnWoGTcp/AnuwCoOUjhIvCvN59UBeoPZ/AYyLm3cWVAjxhpqREVaP0974iVwH51d4AVNaSC8TRNNYDQEFdlzDW9ob10YlvGQm0mQ+elSpcCCBtDgQD7cDFojdx7NIeHJkqi96cOGNkfZOroZsHtlPYoR7TOp3Vmfa5+49uoSSRyjfvc0A1kLx4KC6sNSeDieD1AWhrJLe0y+uy7b9GjP83l+m68AJ72AwSRPN5g7uwUAAAAAElFTkSuQmCC

diese Zeichenfolge wurde in base64 gespeichert, das ich in meinem Code gelesen habe.

var fs      = require('fs'),
data        = fs.readFileSync('base64', 'utf8'),
base64Data,
binaryData;

base64Data  =   data.replace(/^data:image\/png;base64,/, "");
base64Data  +=  base64Data.replace('+', ' ');
binaryData  =   new Buffer(base64Data, 'base64').toString('binary');

fs.writeFile("out.png", binaryData, "binary", function (err) {
    console.log(err); // writes out file without error, but it's not a valid image
});

Ich bekomme einen Kreis zurück, aber das Komische ist, dass sich die Dateigröße geändert hat:) ...

ENDE

Wenn Sie ein Bild zurücklesen, müssen Sie die Kopfzeilen einrichten

Nehmen Sie zum Beispiel imagepng von der PHP Seite:

<?php
$im = imagecreatefrompng("test.png");

header('Content-Type: image/png');

imagepng($im);
imagedestroy($im);
?>

Ich denke, die zweite Zeile header('Content-Type: image/png'); ist wichtig, ansonsten wird Ihr Bild nicht im Browser angezeigt, sondern dem Browser werden nur ein paar binäre Daten angezeigt.

In Express würden Sie einfach so etwas wie unten verwenden. Ich werde Ihren Gravatar anzeigen, der sich unter http://www.gravatar.com/avatar/cabf735ce7b8b4471ef46ea54f71832d?s=32&d=identicon&r=PG .__ befindet. Wenn Sie curl --head http://www.gravatar.com/avatar/cabf735ce7b8b4471ef46ea54f71832d?s=32&d=identicon&r=PG sind, ist dies eine JPEG-Datei. Ich fordere nur Header an, da curl sonst eine Reihe von Binärdateien (Google Chrome wird sofort heruntergeladen) zur Konsole angezeigt:

curl --head "http://www.gravatar.com/avatar/cabf735ce7b8b4471ef46ea54f71832d?s=32&d=identicon&r=PG"
HTTP/1.1 200 OK
Server: nginx
Date: Wed, 03 Aug 2011 12:11:25 GMT
Content-Type: image/jpeg
Connection: keep-alive
Last-Modified: Mon, 04 Oct 2010 11:54:22 GMT
Content-Disposition: inline; filename="cabf735ce7b8b4471ef46ea54f71832d.jpeg"
Access-Control-Allow-Origin: *
Content-Length: 1258
X-Varnish: 2356636561 2352219240
Via: 1.1 varnish
Expires: Wed, 03 Aug 2011 12:16:25 GMT
Cache-Control: max-age=300
Source-Age: 1482

$ mkdir -p ~/tmp/6922728
$ cd ~/tmp/6922728/
$ touch app.js

app.js

var app = require('express').createServer();

app.get('/', function (req, res) {
    res.contentType('image/jpeg');
    res.sendfile('cabf735ce7b8b4471ef46ea54f71832d?s=32&d=identicon&r=PG');
});

app.get('/binary', function (req, res) {
    res.sendfile('cabf735ce7b8b4471ef46ea54f71832d?s=32&d=identicon&r=PG');
});

app.listen(3000);

$ wget "http://www.gravatar.com/avatar/cabf735ce7b8b4471ef46ea54f71832d?s=32&d=identicon&r=PG"
$ node app.js
15
Alfred

Ich musste auch Base64-kodierte Bilder speichern, die Teil von Daten-URLs sind. Daher habe ich ein kleines npm-Modul erstellt, um dies zu tun, falls ich (oder jemand anderes) es in Zukunft noch einmal tun müsste. Es heißt ba64 .

Einfach ausgedrückt, nimmt es eine Daten-URL mit einem Base64-kodierten Bild und speichert das Bild in Ihrem Dateisystem. Es kann synchron oder asynchron speichern. Es hat auch zwei Hilfsfunktionen, eine zum Abrufen der Dateierweiterung des Images und die andere zum Trennen der Base64-Codierung vom data:-Schema-Präfix.

Hier ist ein Beispiel:

var ba64 = require("ba64"),
    data_url = "data:image/jpeg;base64,[Base64 encoded image goes here]";

// Save the image synchronously.
ba64.writeImageSync("myimage", data_url); // Saves myimage.jpeg.

// Or save the image asynchronously.
ba64.writeImage("myimage", data_url, function(err){
    if (err) throw err;

    console.log("Image saved successfully");

    // do stuff
});

Installieren Sie es: npm i ba64 -S. Repo ist auf GitHub: https://github.com/HarryStevens/ba64 ​​ .

P.S. Später fiel mir ein, dass ba64 wahrscheinlich ein schlechter Name für das Modul ist, da die Leute davon ausgehen können, dass es Base64-Codierung und -Decodierung vornimmt, was aber nicht der Fall ist (es gibt viele Module, die dies bereits tun). Naja.

3
Harry Stevens

base64 image einfach in eine Datei konvertieren und als zufällige ID oder als Namen speichern.

// to create some random id or name for your image name
const imgname = new Date().getTime().toString();

// to declare some path to store your converted image
const path = yourpath.png    

// image takes from body which you uploaded
const imgdata = req.body.image;    

// to convert base64 format into random filename
const base64Data = imgdata.replace(/^data:([A-Za-z-+/]+);base64,/, '');
fs.writeFile(path, base64Data, 'base64', (err) => {
    console.log(err);
});

// assigning converted image into your database
req.body.coverImage = imgname
1
Carlos

Konvertieren von einer Datei mit dem base64-String in ein png-Image.

4 Varianten, die funktioniert.

var {promisify} = require('util');
var fs = require("fs");

var readFile = promisify(fs.readFile)
var writeFile = promisify(fs.writeFile)

async function run () {

  // variant 1
  var d = await readFile('./1.txt', 'utf8')
  await writeFile("./1.png", d, 'base64')

  // variant 2
  var d = await readFile('./2.txt', 'utf8')
  var dd = new Buffer(d, 'base64')
  await writeFile("./2.png", dd)

  // variant 3
  var d = await readFile('./3.txt')
  await writeFile("./3.png", d.toString('utf8'), 'base64')

  // variant 4
  var d = await readFile('./4.txt')
  var dd = new Buffer(d.toString('utf8'), 'base64')
  await writeFile("./4.png", dd)

}

run();
1
Vladimir Buskin

Unter der Funktion zum Speichern von Dateien, übergeben Sie einfach Ihre base64-Datei.

import fs from 'fs';
 const uuid = require('uuid/v1');

/*Download the base64 image in the server and returns the filename and path of image.*/
function saveImage(baseImage) {
    /*path of the folder where your project is saved. (In my case i got it from config file, root path of project).*/
    const uploadPath = "/home/documents/project";
    //path of folder where you want to save the image.
    const localPath = `${uploadPath}/uploads/images/`;
    //Find extension of file
    const ext = baseImage.substring(baseImage.indexOf("/")+1, baseImage.indexOf(";base64"));
    const fileType = baseImage.substring("data:".length,baseImage.indexOf("/"));
    //Forming regex to extract base64 data of file.
    const regex = new RegExp(`^data:${fileType}\/${ext};base64,`, 'gi');
    //Extract base64 data.
    const base64Data = baseImage.replace(regex, "");
    const filename = `${uuid()}.${ext}`;

    //Check that if directory is present or not.
    if(!fs.existsSync(`${uploadPath}/uploads/`)) {
        fs.mkdirSync(`${uploadPath}/uploads/`);
    }
    if (!fs.existsSync(localPath)) {
        fs.mkdirSync(localPath);
    }
    fs.writeFileSync(localPath+filename, base64Data, 'base64');
    return filename;
}

Blockquote

0
Shaik Matheen