【问题标题】:Node.js Unable to Write JPEG Blob sent from Canvas toDataURLNode.js 无法写入从 Canvas 发送到 DataURL 的 JPEG Blob
【发布时间】:2014-11-02 10:46:24
【问题描述】:

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

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

$("#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,但文件仍会生成空白图像。

这是删除生成的 base64 字符串的“data:image/jpeg;base64”部分的 dataURItoBlob 函数:

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 编码写入 Buffer。我知道流式传输数据将是一种更有效的解决方案,但作为新的 Node 开发人员,我目前无法做到这一点。

文件也正在与 writeFileSync 方法同步写入。我也尝试过使用 writeFile 的异步版本,但结果相同!

有趣的是,这段代码在几周前就有效了。现在我回到项目,出现了一个错误!也许节点正在异步执行 JavaScript 乱序执行的所有事情(不太可能)?还是这种方法不稳定,流式传输可能会解决问题?

感谢所有帮助!

【问题讨论】:

    标签: node.js image canvas blob


    【解决方案1】:

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

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

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

    【讨论】:

      猜你喜欢
      • 2014-06-02
      • 2021-05-04
      • 2022-01-08
      • 2012-08-23
      • 2013-05-16
      • 1970-01-01
      • 2018-06-23
      • 1970-01-01
      • 2018-06-11
      相关资源
      最近更新 更多