var fs= require('fs')

var imageFile = dataUrl.replace(/^data:image/\w+;base64,/, "");

var imageBuffer = new Buffer(imageFile,'base64');

fs.writeFileSync('./ap.png',imageBuffer);

目前流行的“你画我猜”应用,你有没有想过使用HTML5来实现过?那么不可避免的需要解决canvas保存图片到硬盘或mongodb之类的数据库。本文主要介绍使用nodejs将html5 canvas base64编码图片保存为文件,同时提供两种解决方案。

html5 canvas属于客户端API,没有权限去保存图片到硬盘,只有canvas . toDataURL()这一个接口可导出画布的base64编码,以提供给服务端进行处理保存,据我所知.net和php都有方法或类来进行简单的处理保存。nodejs呢?是的,没错!nodejs同样有能力来保存base64编码的图片。

解决方案一:

使用new Buffer来创建对应编码的缓冲,通过fs模块将Buffer写成一个文件。

优点:简单易用,无需其它模块的支持。

缺点:不能对图片的尺寸,水印,压缩,格式等进行处理。

注意点:

1、new Buffer接收到base64编码,不能带data:URL,而使用canvas . toDataURL()导出的base64编码会带data:URL,所以需要先过滤掉

类似这样的一段“data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0”

需过滤成:“iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0”

2、’binary’ – 一种只使用每个字符前8个字节将原始的二进制数据编码进字符串的方式。这个方式已经废弃,应当尽量使用buffer 对象。这个编码将会在未来的node 中删除。

看到有人把base64声明的Buffer再转换成binary,这个是完全没必要的。

3、生成的图片有size变化,但是打开后是一个无效的图像,这个看本文的第三点。

使用express搭建的/upload (POST)上传保存接口,完成代码如下:

var express = require('express');

var fs = require("fs");

var app = module.exports = express();

//配置

app.configure(function(){

app.use(express.bodyParser());

app.use(express.methodOverride());

app.use(express.cookieParser('keyboard cat'));

app.use(express.session());

app.use(app.router);

app.use(express.static(__dirname + '/up')); //静态文件目录

app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));

});

//保存base64图片POST方法

app.post('/upload', function(req, res){

//接收前台POST过来的base64

var imgData = req.body.imgData;

//过滤data:URL

var base64Data = imgData.replace(/^data:image/\w+;base64,/, "");

var dataBuffer = new Buffer(base64Data, 'base64');

fs.writeFile("out.png", dataBuffer, function(err) {

if(err){

res.send(err);

}else{

res.send("保存成功!");

}

});

});

if (!module.parent) {

app.listen(8000);

console.log('Express started on port 8000');

}

解决方案二:

使用node-canvas模块进行图片处理和保存。

(node-canvas安装见我的另一篇博文:http://www.2fz1.com/?p=246)

优点:能对图片像html5 canvas一样进行处理,尺寸调整、水印、图片反转色、格式转换

缺点:需安装模块支持、当base64编码有误不能解析成图片时会报错并停止nodejs服务。

注意点:canvas透明背景,默认为黑色;使用base64给img.src赋值时,需带上data:URL

使用express搭建的/upload (POST)上传保存接口,完成代码如下:

var Canvas = require('canvas'); //需安装canvas模块

var express = require('express');

var fs = require("fs");

var app = module.exports = express();

//配置

app.configure(function(){

app.use(express.bodyParser());

app.use(express.methodOverride());

app.use(express.cookieParser('keyboard cat'));

app.use(express.session());

app.use(app.router);

app.use(express.static(__dirname + '/up')); //静态文件目录

app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));

});

app.post('/upload', function(req, res){

var base64Data = req.body.imgData;

var img = new Canvas.Image;

img.onload = function(){
var w = img.width;
var h = img.height;
var canvas = new Canvas(w, h);
var ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0); var out = fs.createWriteStream(__dirname + '/crop.jpg');
var stream = canvas.createJPEGStream({
bufsize : 2048,
quality : 80
}); stream.on('data', function(chunk){
out.write(chunk);
}); stream.on('end', function(){
out.end();
res.send("上传成功!");
});
} img.onerror = function(err){
res.send(err);
} img.src = base64Data;

});

if (!module.parent) {

app.listen(8000);

console.log('Express started on port 3000');

}

容易出现的错误(base64编码中,不容忽视的“+”号)

1、如果canvas没有任何像素,则返回值为:“data:,”,这是最短的data:URL,代码中最好做一下保护。

2、使用解决方案一实现图片保存,生成的图片有size,但是打开后却是不能识别的无效图像。

使用解决方案二实现图片保存,nodejs直接报错,并且服务挂掉。

原因:

这个问题,花了我很长时间才找到原因,根本原因是base64编码,使用express接收POST值后,base64编码字符串中的“+”号被替换成空格了,引起编码出错,img.src = base64Data;直接把nodejs服务挂掉。如果你出现类似问题,请console.log(base64Data);看字符串是否有空格。

解决办法:

将空格替换回“+”号

var base64Data = imgData.replace(/\s/g,"+");

base64 convert to file的更多相关文章

  1. csharp: datagridview Convert csv file

    /// <summary> /// 保存文件 /// 涂聚文 /// 2014-08-29 /// Geovin Du /// </summary> /// <param ...

  2. 图片base64格式转为file文件类型上传方法

    日常使用文件上传方式,都是通过input type='file'的文件选择框进行文件上传.但是会通过其他交互方式等到图片的base64格式进行上传.具体情况如下示意: 在项目开发中,需要进行照片采集, ...

  3. 将图片base64格式转换为file对象并读取(两种方式读取)

    两种方式读取,一种URL.createObjectURL,另一种fileReader   var base64 = ` data:image/jpeg;base64,/9j/4AAQSkZJRgABA ...

  4. 将base64转成File文件对象

    function dataURLtoFile(dataurl, filename) { //将base64转换为文件        var arr = dataurl.split(','),      ...

  5. js中将文件的base64转换成file并上传到服务器

    ** * @param base64Codes * 图片的base64编码 */ function sumitImageFile(base64Codes){ var form=document.for ...

  6. [转](SQL Server) Convert a File from utf-8 to ANSI (such as Windows-1252)

    本文转自:https://example-code.com/sql/charset_convert_file_from_utf8_to_ansi.asp CREATE PROCEDURE Chilka ...

  7. WPF 基础 - 图片与 base64

    1. base64 转图片 将 base64 转成 byte[] 将 byte[] 作为内存流保存到一个 BitmapImage 实例的流的源 把 BitmapImage 作为目标图片的 Source ...

  8. js,JQ 图片转换base64 base64转换为file对象,blob对象

    //将图片转换为Base64 function getImgToBase64(url,callback){ var canvas = document.createElement('canvas'), ...

  9. file上传图片,base64转换、压缩图片、预览图片、将图片旋转到正确的角度

    /** * 将base64转换为文件对象 * (即用文件上传输入框上传文件得到的对象) * @param {String} base64 base64字符串 */ function convertBa ...

随机推荐

  1. 2015年辽宁省赛Interesting Tree

    题目描述 Recently, Miss Huang want to receive a Tree as her birthday gift! (What a interesting person!)  ...

  2. Android Studio 单元测试

    在功能测试有时要通过Log来验证,每次编译都需要时间,对于一些功能测试可以用Android Studio自带的单元测试功能进行调试: 在新建项目时,Android studio就已经集成了二个单元测试 ...

  3. ubuntu完全卸载nginx

    删除nginx连带配置文件 sudo apt-get purge nginx # Removes everything. 卸载不再需要的nginx依赖程序 sudo apt-get autoremov ...

  4. 【POJ 3243】Clever Y 拓展BSGS

    调了一周,我真制杖,,, 各种初始化没有设为1,,,我当时到底在想什么??? 拓展BSGS,这是zky学长讲课的课件截屏: 是不是简单易懂.PS:聪哥说“拓展BSGS是偏题,省选不会考,信我没错”,那 ...

  5. 网络流HDU 2883

    建图           源点  ->     每个人  ->           每段时间      ->      汇点 时间要离散化一下 分成一些时间段 权           ...

  6. Javaweb容器的四种作用域

    几乎所有web应用容器都提供了四种类似Map的结构:application session request page,Jsp或者Servlet通过向着这四个对象放入数据,从而实现Jsp和Servlet ...

  7. SurfaceView, TextureView, SurfaceTexture等的区别

    SurfaceView, GLSurfaceView, SurfaceTexture以及TextureView是Android当中名字比较绕,关系又比较密切的几个类.本文基于Android 5.0(L ...

  8. 【BZOJ-1391】order 最小割 + 最大全闭合图

    1391: [Ceoi2008]order Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1334  Solved: 405[Submit][Statu ...

  9. BZOJ3295 [Cqoi2011]动态逆序对

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转 ...

  10. android录音相关

    android的麦克风在现在的生活中发挥着很大的作用,打电话,视频聊天,语音识别等等. android sdk的api里提供了很方便的调用方法,下面写一个小的DEMO. 五个按钮:开始录音,停止,播放 ...