首页 \ 问答 \ 如何从服务器请求中保存图像的分区以便以后合并(How to save segements of image in memory from server request for merging later)

如何从服务器请求中保存图像的分区以便以后合并(How to save segements of image in memory from server request for merging later)

我有一个nodejs应用程序,它调用一个返回图像片段的服务器。 我试图将此段保存在缓冲区中,以便稍后将它们合并在一起以生成完整的图像

var req = http.request(options, function(res) {
        var segment = parseInt(res.headers["segment"]);
        res.setEncoding('binary');
        var data = "";

        res.on('data', function(chunk) {
            data += chunk;
        });

        res.on('end', function() {
            images[segment] = (new Buffer(data, 'binary'));
        });
    });

在我获得所有细分后

var totalImage = "";
for (image in images) {
    totalImage += image.toString('binary');
}
fs.writeFile('image.png', totalImage, function(e) {
    console.log('done');
});

我想使用node-pngjs,但我不知道如何将响应二进制文件流式化为png,以便我可以保存像素缓冲区而不是二进制文件本身以供以后使用

我试图做以下事情:

res.pipe(new PNG()).on('parse', function(err, data) {
    buffers[segment] = data;
});

但这会在解析期间导致错误“文件签名无效”


I have a nodejs application that calls a server which returns a fragment of an image. I am trying to save this segment in a buffer so that I can later merge them together to make a full image

var req = http.request(options, function(res) {
        var segment = parseInt(res.headers["segment"]);
        res.setEncoding('binary');
        var data = "";

        res.on('data', function(chunk) {
            data += chunk;
        });

        res.on('end', function() {
            images[segment] = (new Buffer(data, 'binary'));
        });
    });

after I get all the segments

var totalImage = "";
for (image in images) {
    totalImage += image.toString('binary');
}
fs.writeFile('image.png', totalImage, function(e) {
    console.log('done');
});

I want to use node-pngjs but I am not sure how to stream the response binary into png so that I can save the pixel buffer instead of the binary itself for later consumption

I attempted to do the following:

res.pipe(new PNG()).on('parse', function(err, data) {
    buffers[segment] = data;
});

but this lead to an error 'Invalid file signature' during parse

更新时间:2023-02-04 07:02

最满意答案

这里可能存在多个问题,但此代码不正确:

for (image in images) {
    totalImage += image.toString('binary');
}

在该代码中, image是数组的索引(不是数组单元格的内容),所以你要做的就是加上索引0+1+2+3+4 ,依此类推。

绝对不应该使用for/in构造进行迭代,因为它会迭代对象的所有属性,而不仅仅是数组元素。 并且,您没有获取阵列单元格的实际内容,这些内容也可能是images[image] 。 相反,你可以使用:

for (var i = 0; i < images.length; i++) {
    totalImage += images[i].toString('binary');
}

PS我怀疑你也可能有编码问题。 您从http请求获取数据,但它全部进入Buffer对象数组,然后将它们转换为“二进制”字符串并将它们一起添加到字符串变量中。 由于这是二进制数据,看起来你应该只使用Buffer来收集东西,而不是字符串。


在稍微查看nodejs中的Buffers之后,您可以将这些缓冲区组合起来,如下所示:

var totalImage = Buffer.concat(images);

这使所有内容保持二进制缓冲区格式,并且不会出现任何编码问题。 在这里这里找到了这个。


There may well be more than one issue here, but this code is not correct:

for (image in images) {
    totalImage += image.toString('binary');
}

In that code, image is the index into the array (not the contents of the cell of the array) so all you're doing is add up the indexes 0+1+2+3+4 and so on.

Arrays should never for iterated with the for/in construct because that iterates all properties of the object, not just array elements. And, you weren't fetching the actual contents of the array cell which would have been images[image] either. Instead, you could use:

for (var i = 0; i < images.length; i++) {
    totalImage += images[i].toString('binary');
}

P.S. I suspect that you may have encoding issues also. You take the data from the http request, but it all into an array of Buffer objects, then you convert those to a "binary" string and add them together into a string variable. Since this is binary data, it really seems like you should only be using a Buffer to collect stuff, not a string.


After looking into Buffers in nodejs a little more, you can combine your Array of buffers like this:

var totalImage = Buffer.concat(images);

This keeps everything in binary buffer format and wouldn't have any encoding issues. Found this here and here.

相关问答

更多
  • 我不做Android,所以不能向你保证。 但是我使用下面的golang实现来上传文件。 package main import ( "io" "net/http" "os" ) //Display the named template func display(w http.ResponseWriter, tmpl string, data interface{}) { templates.ExecuteTemplate(w, tmpl+".html", data) } ...
  • 这是一个如何实现你所需要的例子: 1) 画一些东西 (从画布教程中取出)