Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Image 如何将base64编码的映像保存到磁盘?_Image_Node.js_Base64_Binaryfiles - Fatal编程技术网

Image 如何将base64编码的映像保存到磁盘?

Image 如何将base64编码的映像保存到磁盘?,image,node.js,base64,binaryfiles,Image,Node.js,Base64,Binaryfiles,我的Express应用程序正在从浏览器接收base64编码的PNG(使用toDataURL()从画布生成),并将其写入文件。但该文件不是有效的图像文件,“file”实用程序只是将其标识为“data” 更新 我找到了这个。我想你忘了用+替换空格,如链接所示 我从中选取了这个圆圈作为样本,它看起来像: 接下来我把它接了回去: data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAAAAACPAi4CAAAAB3RJTUUH1QEHDxEhO

我的Express应用程序正在从浏览器接收base64编码的PNG(使用toDataURL()从画布生成),并将其写入文件。但该文件不是有效的图像文件,“file”实用程序只是将其标识为“data”

更新 我找到了这个。我想你忘了用
+
替换
空格,如链接所示

我从中选取了这个圆圈作为样本,它看起来像:

接下来我把它接了回去:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAAAAACPAi4CAAAAB3RJTUUH1QEHDxEhOnxCRgAAAAlwSFlzAAAK8AAACvABQqw0mAAAAXBJREFUeNrtV0FywzAIxJ3+K/pZyctKXqamji0htEik9qEHc3JkWC2LRPCS6Zh9HIy/AP4FwKf75iHEr6eU6Mt1WzIOFjFL7IFkYBx3zWBVkkeXAUCXwl1tvz2qdBLfJrzK7ixNUmVdTIAB8PMtxHgAsFNNkoExRKA+HocriOQAiC+1kShhACwSRGAEwPP96zYIoE8Pmph9qEWWKcCWRAfA/mkfJ0F6dSoA8KW3CRhn3ZHcW2is9VOsAgoqHblncAsyaCgcbqpUZQnWoGTcp/AnuwCoOUjhIvCvN59UBeoPZ/AYyLm3cWVAjxhpqREVaP0974iVwH51d4AVNaSC8TRNNYDQEFdlzDW9ob10YlvGQm0mQ+elSpcCCBtDgQD7cDFojdx7NIeHJkqi96cOGNkfZOroZsHtlPYoR7TOp3Vmfa5+49uoSSRyjfvc0A1kLx4KC6sNSeDieD1AWhrJLe0y+uy7b9GjP83l+m68AJ72AwSRPN5g7uwUAAAAAElFTkSuQmCC
将此字符串保存到我在代码中读取的
base64

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
});
我得到了一个圆圈,但有趣的是文件大小已经改变:)

结束 当你们读回图片时,我想你们需要设置标题

以PHP页面为例:

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

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

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

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

我认为您正在转换的数据比您需要的要多一些。使用正确的编码创建缓冲区后,只需将缓冲区写入文件

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

require("fs").writeFile("out.png", base64Data, 'base64', function(err) {
  console.log(err);
});
新缓冲区(…,'base64')通过将输入解释为base64编码字符串,将输入字符串转换为缓冲区,缓冲区只是一个字节数组。然后您可以将该字节数组写入文件

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

require("fs").writeFile("out.png", base64Data, 'base64', function(err) {
  console.log(err);
});
更新
正如注释中提到的,
req.rawBody
不再是一件事。如果您使用的是
express
/
connect
,则应使用
bodyParser()
中间件并使用
req.body
,如果使用标准节点执行此操作,则需要聚合传入的
数据
事件
缓冲区
对象,并在
结束
回调中执行此图像数据解析。

这是我的完整解决方案,它将读取任何base64图像格式,并将其以正确格式保存在数据库中:

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

base64图像转换为文件并另存为随机id或名称的简单方法

// 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

我还必须保存Base64编码的图像,这些图像是数据URL的一部分,因此我最终制作了一个小型npm模块,以防我(或其他人)将来需要再次这样做。它叫

简单地说,它获取一个带有Base64编码图像的数据URL,并将图像保存到您的文件系统中。它可以同步或异步保存。它还有两个助手函数,一个用于获取图像的文件扩展名,另一个用于将Base64编码与
数据:
方案前缀分离

下面是一个例子:

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
});
安装它:
npm i ba64-S
。回购在GitHub上:


另外,我后来意识到ba64可能是该模块的一个坏名字,因为人们可能认为它可以进行Base64编码和解码,但事实并非如此(有很多模块已经这样做了)。哦,很好。

将带有base64字符串的文件转换为png图像

4种变体,有效

var{promisify}=require('util');
var fs=要求(“fs”);
var readFile=promisify(fs.readFile)
var writeFile=promisify(fs.writeFile)
异步函数运行(){
//变式1
var d=等待读取文件('./1.txt',utf8')
等待写入文件(“./1.png”,d,“base64”)
//变式2
var d=等待读取文件('./2.txt',utf8')
var dd=新缓冲区(d,‘base64’)
等待写入文件(“./2.png”,dd)
//变式3
var d=await readFile('./3.txt')
等待writeFile(“./3.png”、d.toString('utf8')、'base64')
//变式4
var d=等待读取文件('./4.txt')
var dd=新缓冲区(d.toString('utf8'),'base64')
等待写入文件(“./4.png”,dd)
}
run();

下面的函数保存文件,只需传递base64文件,它返回文件名并将其保存在DB中

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

这对我来说是简单而完美的

从图像到base64字符串

let buff = fs.readFileSync('stack-abuse-logo.png');
let base64data = buff.toString('base64');
从base64字符串到图像

let buff = new Buffer(data, 'base64');
fs.writeFileSync('stack-abuse-logo-out.png', buff);

您可以使用第三方库,如或

  • base64 img
  • base64到图像

  • 谢谢Alfred,但是在这个最小的测试用例中,我不会从服务器返回任何内容。我只是将文件写入服务器上的磁盘,而文件本身似乎不是有效的映像。我相当肯定base64是正确的,但将其写成二进制文件时似乎有问题。对不起,我误解了问题:$。我会再试一次。谢谢你的更新,但是空间替换对我来说不起作用,实际上在我应用Logan的解决方案时也没有必要。作为参考,画布在我的测试用例中非常简单:var context=canvas.getContext('2d');context.fillStyle=“#f89”;context.fillRect(50,50100100);好吧,因为当我这么做的时候,我得到了图像,但至少你的问题已经解决了:Pinteresing,不知道为什么toString(“二进制”)没有在你的案例中弄糟它。无论如何,空格不应该自然出现在base64中,因此替换应该是没有意义的。这就是我提供的例子。(在阅读MIME规范后,我尝试了一个手动插入换行符的变体,该规范要求换行符不超过72个字符,主要是出于偏执……结果证明,只要删除toString(“二进制”)就可以使用或不使用换行符。)我更新了答案,我认为这是您首先需要的;)显然这不是您要求的,但是(在我的例子中)我意识到最好的方法就是将整个编码字符串存储到我的数据库中(您总是可以使用
    加载它)。只是一个选项,考虑其他人使用这个线程作为参考。此外,在您的示例中的WrreFiFLE参数中有一个轻微的键入:“BuffReDATA”->“DATABUFFER”。code>req.rawBody
    包含编码为数据URL的请求数据:。所以你必须去掉开头部分,只保存base64数据。这是非常好的东西,谢谢!对于那些在将来发现这一点的人来说,rawBody不再是req的属性。您必须使用express body解析器中间件来获取data.var base64Data=req.rawBody.split(',')[1]@notgiorgi最好提出一个新问题,并提供足够的细节来重现您的问题,并链接到
    let buff = fs.readFileSync('stack-abuse-logo.png');
    let base64data = buff.toString('base64');
    
    let buff = new Buffer(data, 'base64');
    fs.writeFileSync('stack-abuse-logo-out.png', buff);
    
    const base64Img = require('base64-img');
    
    const data = 'data:image/png;base64,...';
    const destpath = 'dir/to/save/image';
    const filename = 'some-filename';
    
    base64Img.img(data, destpath, filename, (err, filepath) => {}); // Asynchronous using
    
    const filepath = base64Img.imgSync(data, destpath, filename); // Synchronous using
    
    const base64ToImage = require('base64-to-image');
    
    const base64Str = 'data:image/png;base64,...';
    const path = 'dir/to/save/image/'; // Add trailing slash
    const optionalObj = { fileName: 'some-filename', type: 'png' };
    
    const { imageType, fileName } = base64ToImage(base64Str, path, optionalObj); // Only synchronous using