我正在尝试绘制toDataUrl()
画布,并提供base64
数据。我想将其存储为png
。我可以从base64获取转换后的二进制数据,但我无法使用NodeJs服务将其写入文件。
如果我将base64数据直接写入文件,可以写入所有数据,但它不能是png
对吗?我想存储要存储的二进制数据。怎么做?
代码段:
var strData = this.drawingCanvas.getContext().canvas.toDataURL();
var data = strData.replace(/^data:image\/\w+;base64,/, "");
var imgData = this.decode(data); // decode(data) is DEFINED BELOW
this.call({filePath:'<path>/image.png', data: imgData},
{method:"writeFile"});`
`utf8decode : function (utftext) {
var string = "";
var i = 0;
var c = c1 = c2 = 0;
while ( i < utftext.length ) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
}
else if((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i+1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
}
else {
c2 = utftext.charCodeAt(i+1);
c3 = utftext.charCodeAt(i+2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
},`
`_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
decode : function (input) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = this._keyStr.indexOf(input.charAt(i++));
enc2 = this._keyStr.indexOf(input.charAt(i++));
enc3 = this._keyStr.indexOf(input.charAt(i++));
enc4 = this._keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
output = this.utf8decode(output);
return output;
},`
/**************************************************
wRITEfILEaaSSISTANT.JS
***************************************************/
var WriteFileAssistant = function(){};
WriteFileAssistant.prototype.run = function(future, subscription) {
var fs = IMPORTS.require('fs');
var filePath = this.controller.args.filePath;
var f = subscription.get();
f.result = {reply: data};
var fd = fs.openSync('<path>/image.png', 'a+');
//var data = fs.writeSync(fd, g, null, encoding='utf8');
//this.controller.args.data - Image data (binary)
var buff = new Buffer(this.controller.args.data, 'binary');
//tried also with 'base64'
fs.write(fd, buff, 0, buff.length, 0, function(err,written){
});
var f = subscription.get();
f.result = {reply: data};
答案 0 :(得分:9)
你使事情变得比他们需要的更难。节点Buffer对象将base64作为输入,并为您完成所有解码。
您可以从base64字符串中删除数据:image ...部分,并将该数据传递给WriteFileAssistant。
var strData = this.drawingCanvas.getContext().canvas.toDataURL();
var imgData = strData.replace(/^data:image\/\w+;base64,/, "");
this.call(
{
filePath:'/media/internal/Collage/image.png',
data: imgData
},
{
method:"writeFile"
}
);
WriteFileAssistant只需要获取base64字符串并将其作为参数传递给Buffer构造函数。此外,在openSync调用上使用'a +'也会破坏事情。
var WriteFileAssistant = function(){};
WriteFileAssistant.prototype.run = function(future, subscription) {
var fs = IMPORTS.require('fs');
var filePath = this.controller.args.filePath;
var fd = fs.openSync('<path>/image.png', 'w');
var buff = new Buffer(this.controller.args.data, 'base64');
fs.write(fd, buff, 0, buff.length, 0, function(err,written){
});
}
Buffer接受一个字符串和一个编码,然后它使用编码值将字符串处理成一系列字节,所以当你告诉它字符串是base64时,它将为你解码base64并创建正确的解码要写入文件的字节数组。