5

使用 nodejs 和 imagemagick 可以重新调整图像大小并将其发送到浏览器。

    var http = require('http'),
        spawn = require('child_process').spawn;

    http.createServer(function(req, res) {

        var image = 'test.jpg';
        var convert = spawn('convert', [image, '-resize', '100x100', '-']);

        convert.stdout.pipe(res);
        convert.stderr.pipe(process.stderr);

    }).listen(8080);

测试图像是从文件系统中读取的,我想更改以便测试图像是二进制字符串。

var image = 'some long binray string representing an image.......';

我的计划是将二进制字符串存储在 Mongodb 中并动态读取它们。

4

3 回答 3

5

看看节点模块node-imagemagick。模块页面上有以下示例,用于调整大小和图像并将其写入文件...

var fs = require('fs');
im.resize({
  srcData: fs.readFileSync('kittens.jpg', 'binary'),
  width:   256
}, function(err, stdout, stderr){
  if (err) throw err
  fs.writeFileSync('kittens-resized.jpg', stdout, 'binary');
  console.log('resized kittens.jpg to fit within 256x256px')
});

您可以更改此代码以执行以下操作...

var mime = require('mime')   // Get mime type based on file extension. use "npm install mime"
  , fs = require('fs')
  , util = require('util')
  , http = require('http')
  , im = require('imagemagick');

http.createServer(function (req, res) {
    var filePath = 'test.jpg';

    fs.stat(filePath, function (err, stat) {
        if (err) { throw err; }

        fs.readFile(filePath, 'binary', function (err, data) {
            if (err) { throw err; }

            im.resize({
                srcData: data,
                width: 256
            }, function (err, stdout, stderr) {
                if (err) { throw err; }

                res.writeHead(200, {
                    'Content-Type': mime.lookup(filePath),
                    'Content-Length': stat.size
                });

                var readStream = fs.createReadStream(filePath);

                return util.pump(readStream, res);
            });
        });
    });
}).listen(8080);

附言。还没有运行上面的代码。很快就会尝试这样做,但它应该让您了解如何异步调整文件大小和流式传输文件。

于 2012-07-22T10:24:06.027 回答
3

由于您使用spawn()的是调用 ImageMagick 命令行convert,因此通常的方法是将中间文件写入临时目录,它们将在使用后立即清理或作为计划/cron 作业进行清理。

如果您想避免写入要转换的文件,可以尝试的一种选择是对图像进行 base64 编码并使用内联格式。这类似于图像在某些 HTML 电子邮件或网页中的编码方式。

 inline:{base64_file|data:base64_data}
 Inline images let you read an image defined in a special base64 encoding.

注意:您可以传递的命令行选项的大小是有限制的。Imagemagick 文档建议 5000 字节。Base64 编码的字符串比原始字符串大(维基百科建议粗略指南大137%),除非您显示缩略图,否则这可能非常有限。

另一个 ImageMagick 格式选项是ephemeral

 ephemeral:{image_file}
 Read and then Delete this image file.

如果你想完全避免 I/O 传递,你需要一个直接集成像 ImageMagick 或 GD 这样的低级库的 Node.js 模块,而不是包装命令行工具。

于 2012-07-23T01:32:40.433 回答
0

你试过什么了?您可以使用 GridFS 存储图像数据并从那里作为流检索.. 这在 C# 中..不确定这是否有帮助..

public static void UploadPhoto(string name)
{
    var server = MongoServer.Create("mongodb://localhost:27017");
    var database = server.GetDatabase("MyDB");
    string fileName = name;
    using (var fs = new FileStream(fileName, FileMode.Open))
    {
        var gridFsInfo = database.GridFS.Upload(fs, fileName);
        var fileId = gridFsInfo.Id;
        //ShowPhoto(filename);
    }
}

public static Stream ShowPhoto(string name)
{
    var server = MongoServer.Create("mongodb://localhost:27017");
    var database = server.GetDatabase("MyDB");
    var file = database.GridFS.FindOne(Query.EQ("filename",name));
    var stream = file.OpenRead())
    var bytes = new byte[stream.Length];
    stream.Read(bytes,0,(int)stream.Length);
    return stream;
}

您现在可以使用 ShowPhoto 返回的流。

于 2012-07-22T10:31:10.757 回答