Node.js无法编写从Canvas发送的JPEG Blob toDataURL

时间:2014-09-09 05:45:47

标签: node.js image canvas blob

我正在向Node.js服务器发送base64编码的JPG字符串,并尝试将图像写入文件。写入的文件没有显示任何像素数据 - 只是一个空白的图像容器。我在想我的Node.js JavaScript中有一个错误,因为从浏览器生成的blob看起来是合适的大小(640x480px图像为8.1KB)。我在本地做所有这些,所以我可以排除互联网问题。

在单击按钮时,通过HTML5的Canvas.toDataURL生成base64字符串:

$("#sendImage").click(function() {

    // Send synchronous request to server
    var xhr = new XMLHttpRequest();

    var blob = dataURItoBlob(renderer.domElement.toDataURL('image/jpeg'));
    xhr.open('POST', 'http://localhost:3000/' + captureFrame, false);
    xhr.send(blob);
});

正如您所看到的,我通过在toDataURL调用中指定'image / jpeg'来发送JPEG。我也尝试省略这个字符串来发送PNG,但文件仍然会产生空白图像。

这是dataURItoBlob函数,用于删除生成的base64字符串的'data:image / jpeg; base64'部分:

function dataURItoBlob(dataURI) {
    var mimetype = dataURI.split(",")[0].split(':')[1].split(';')[0];
    var byteString = atob(dataURI.split(',')[1]);
    var u8a = new Uint8Array(byteString.length);
    for (var i = 0; i < byteString.length; i++) {
          u8a[i] = byteString.charCodeAt(i);
    }
    return new Blob([u8a.buffer], { type: mimetype });
}

作为此函数的替代方法,我还尝试了JavaScript split()方法,如下所示:

blob = blob.split('data:image/jpeg;base64,');

但是会出现同样的结果。

这是我的Node.js服务器 - 它创建一个缓冲区并用来自请求的字符串块填充它:

var port = 3000;
var http = require('http');
var fs = require('fs');

http.createServer(function(req, res) {
res.writeHead(200, {
    'Access-Control-Allow-Origin': '*',
    'Access-Control-Allow-Headers': 'Content-Type, X-Requested-With'
});
if (req.method === 'OPTIONS') {
    // Handle OPTIONS requests to work with jQuery and other libs that
    // cause preflighted CORS requests.
    res.end();
    return;
}

// Get capture frame from URL
var idx = req.url.split('/').pop();

// Create filename string
var filename = '/home/user/' + ('0000' + idx).slice(-5) + '.jpg';

// Create new buffer to write string chunks.
var img = new Buffer('');

req.on('data', function(chunk) {
    img = Buffer.concat([img, chunk]);
});

req.on('end', function() {

    // Write JPEG file to filesystem (writes blank image)
    var f = fs.writeFileSync(filename, img);
    console.log('Wrote ' + filename);
    res.end();
});

}).listen(port, '127.0.0.1');
console.log('Server running at http://127.0.0.1:' + port + '/');

上面的代码显示正在使用默认的utf8编码将块写入缓冲区。我知道流式传输数据将是一个更有效的解决方案,但我目前无法做到这一点是一个新的Node开发人员。

该文件也与 writeFileSync 方法同步编写。我也尝试过使用 writeFile 的asynchronouse版本,但结果相同!

有趣的是,这段代码几周前已经运行了。现在我回到项目中,出现了一个错误!也许节点正在异步执行JavaScript的所有事情(不太可能)?或者这种方法是不稳定的,流媒体可能会解决这个问题?

感谢所有帮助!

1 个答案:

答案 0 :(得分:0)

在实例化Three.js WebGL渲染器时,解决方案似乎传递了 preserverDrawingBuffer 标志:

renderer = new THREE.WebGLRenderer({ antialias: true, preserveDrawingBuffer  : true });

该解决方案与Node无关,但我会为具有类似设置并遇到相同问题的任何人保留解决方案。