所以我想做的是从网址流式传输图片,使用graphicsmagick处理它并将其上传到s3。我只是不让它工作。
将处理后的图像流式传输到本地磁盘(使用fs.createWriteStream)可以正常工作。
当我缓冲我的流时,s3中的最终图像至少具有预期的大小(kb-wise),但我无法打开该图像。
这就是我目前的进步:
var request = require('request');
var gm = require("gm");
var AWS = require('aws-sdk');
var mime = require('mime');
var s3 = new AWS.S3();
gm(request('http://www.some-domain.com/some-image.jpg'), "my-image.jpg")
.resize("100^", "100^")
.stream(function(err, stdout, stderr) {
var str = '';
stdout.on('data', function(data) {
str += data;
});
stdout.on('end', function(data) {
var data = {
Bucket: "my-bucket",
Key: "my-image.jpg",
Body: new Buffer(str, 'binary'), // thats where im probably wrong
ContentType: mime.lookup("my-image.jpg")
};
s3.client.putObject(data, function(err, res) {
console.log("done");
});
});
});
我确实尝试过创建一个filewritestream和filereadstream之类的东西,但我认为应该有一些更清洁的解决方案来解决这个问题......
编辑:我尝试的第一件事就是将Body设置为stdout(来自@AndyD的建议答案):var data = {
Bucket: "my-bucket",
Key: "my-image.jpg",
Body: stdout,
ContentType: mime.lookup("my-image.jpg")
};
但是会返回以下错误:
Cannot determine length of [object Object]'
EDIT2:
完整的错误:
{ [Error: Cannot determine length of [object Object]]
message: 'Cannot determine length of [object Object]',
object:
{ _handle:
{ writeQueueSize: 0,
owner: [Circular],
onread: [Function: onread] },
_pendingWriteReqs: 0,
_flags: 0,
_connectQueueSize: 0,
destroyed: false,
errorEmitted: false,
bytesRead: 0,
_bytesDispatched: 0,
allowHalfOpen: undefined,
writable: false,
readable: true,
_paused: false,
_events: { close: [Function], error: [Function: handlerr] } },
name: 'Error' }
答案 0 :(得分:13)
您不需要自己读取流(在您的情况下,您似乎是从二进制转换为字符串并返回由于var str =''然后附加数据,这是一个二进制缓冲区等...
尝试让putObject管道流如下:
gm(request('http://www.some-domain.com/some-image.jpg'), "my-image.jpg")
.resize("100^", "100^")
.stream(function(err, stdout, stderr) {
var data = {
Bucket: "my-bucket",
Key: "my-image.jpg",
Body: stdout
ContentType: mime.lookup("my-image.jpg")
};
s3.client.putObject(data, function(err, res) {
console.log("done");
});
});
});
有关详细信息,请参阅这些release notes。
如果流/管道不起作用,那么这样的东西可能会将所有内容加载到内存中然后上传。在这种情况下,我认为你只限于4Mb。
var buf = new Buffer('');
stdout.on('data', function(data) {
buf = Buffer.concat([buf, data]);
});
stdout.on('end', function(data) {
var data = {
Bucket: "my-bucket",
Key: "my-image.jpg",
Body: buf,
ContentType: mime.lookup("my-image.jpg")
};
s3.client.putObject(data, function(err, res) {
console.log("done");
});
});