«Эхо» изображение в Node.js

У меня есть полностью функционирующее приложение PHP, которое я пытаюсь сделать версией Node.js. Это касается обработки фрагментов изображений. Когда он готов отобразить изображение, которое он делает:

// Stream out the image echo self::$tile; 

Как мне сделать что-то подобное в Node.js? Я понимаю, что это широкий вопрос, но я думаю, что моя самая большая проблема заключается в том, что я не понимаю, как PHP «перекликается» с изображением.


Детали:

Я использую AWS для получения изображения. Вызов AWS возвращает буфер. В этот момент времени в Javascript я оставил изображение как буфер.

Сайт заполняет карту с черепичными изображениями, поэтому есть несколько вызовов с изображением, размещенным в определенном месте на странице. Я использую выражение для обработки запросов.

 app.get(/^\/omb\/1.0.0\/(.+)\/(.+)\/(.+)\/(.+)\.[a-zA-Z]*$/, function(req, res){ var MosaicStreamer = require('./models/MosaicStreamer.js'); var ms = new MosaicStreamer; var configs = {library: req.params[0], zoom: req.params[1], column: req.params[2], row: req.params[3]}; ms.handleTile(configs); }); 

handleTile захватывает изображение и в конечном итоге приводит меня туда, где я сейчас. Изображение захватывается следующим образом:

 var aws = new AWS.S3(); var params = { Bucket: this.bucket, Key: this.tileDirectory + this.filepath, Range: 'bytes=' + (this.toffset + 4) + "-" + (this.tsize + this.toffset + 4) }; var ts = this; aws.getObject(params, function(err, data){ if(ts.tile == null){ ts.tile = data.Body; //S3 get object } } 

Я думаю, что вы хотите сделать, это взять URL-адрес, который представляет собой строгое соглашение об именах папок / файлов в вашем S3 Bucket. Предположим, что вы установили клиентское соединение с вашим S3, вы можете использовать метод readFile . Второй аргумент – это imageStream который вы можете передать в response . Как только поток закончится с S3, он автоматически закончит res с клиента, выводя изображение непосредственно клиенту (как вы намереваетесь).

Некоторые коды psuedo:

 app.get(/^\/omb\/1.0.0\/(.+)\/(.+)\/(.+)\/(.+)\.[a-zA-Z]*$/, function(req, res){ var MosaicStreamer = require('./models/MosaicStreamer.js'); var ms = new MosaicStreamer; var configs = {library: req.params[0], zoom: req.params[1], column: req.params[2], row: req.params[3]}; return ms.handleTile(configs, res); //return the handleTile function, add 2nd argument and pass res through }); 

Внутри функции handleTile вы можете сделать вызов для S3

 function handleTile(configs, res){ client.readFile('filename', function(error, imageStream){ imageStream.pipe(res); }); } 

Теперь запросы на такие изображения:

 <img src="/path/to/my/file/that/matches/regexp/expression"/> 

Он будет запрашивать это изображение из ведра S3 и напрямую передавать ресурс клиенту.

Чтобы успешно выполнить изображение, вам необходимо выполнить три шага:

  1. Получить данные изображения (например, в качестве буфера, считываемого через fs.readFile ) или поток (например, через fs.createReadStream

  2. Установите соответствующие заголовки в обработчике веб-запросов с аргументами (req, res) ; что-то вроде

res.writeHead(200, {'Content-Type': 'image/png'});

  1. Напишите файл. Если у вас есть файл в буфере,

    res.end(buf, 'binary');

    Если у вас есть поток через

    read_stream.pipe(res)

Весь код может выглядеть (если вы хотите использовать файл image.jpg из текущего каталога):

 'use strict'; var fs = require('fs'); var http = require('http'); http.createServer(function(req, res) { fs.readFile('image.jpg', function(err, buf) { if (err) { res.writeHead(500); res.end('Cannot access file.'); return; } res.writeHead(200, {'Content-Type': 'image/jpeg'}); res.end(buf, 'binary'); }); }).listen(8002, ''); 

Использование потока, очень простая версия (остерегайтесь: никакой обработки ошибок, с обработкой ошибок она может немного усложниться, в зависимости от того, как вы хотите обрабатывать ошибки, возникающие во время чтения файла)

 'use strict'; var fs = require('fs'); var http = require('http'); http.createServer(function(req, res) { var stream = fs.createReadStream('image.jpg'); // Error handling omitted here res.writeHead(200, {'Content-Type': 'image/jpeg'}); stream.pipe(res); }).listen(8003, ''); 

Код, который использует буфер, легче писать, но означает, что ваш сервер должен хранить весь файл в памяти – например, вы не сможете обслуживать 320-гигапиксельный файл изображения . Вы также начинаете отправлять данные только после того, как у вас есть весь файл.

Использование потока позволяет отправить файл, как только вы его получите, поэтому он будет немного быстрее. Если вы читаете файл или местный быстрый сервер, разница в скорости, вероятно, незначительна. Кроме того, вам понадобится немного памяти. С другой стороны, обработка ошибок сложнее.