forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   JavaScript / HTML (http://forum.boolean.name/forumdisplay.php?f=136)
-   -   node.js + imagemagick (http://forum.boolean.name/showthread.php?t=20289)

St_AnGer 05.05.2016 21:56

node.js + imagemagick
 
Добрый вечер, Булчане! :)

Возникла проблема, причём на довольно ровном месте. В своём чатике я решил добавить передачу фоточек и картиночек всяких. Собственно, в этом проблемы не возникло - влоб передаю данные картинки через socket.io или из браузера, или из мобилки. На сервере из сохраняю как то вот так:
Код:

fs.writeFile( __dirname + "/uploads/images/"+filename, msgParsed.text, 'binary', function(err) {
...
});

Filename - имя файла (я его сам генерирую, сразу оговорка - расширения файл не имеет), msgParsed - это распарсеный json с клиента, msgParsed.text - собственно содержимое картинки. Потом на клиенте просто запрашиваю данные этой картинки и вставляю в нужные места (в <img src/> или в UIImage на яблофоне).
В общем? конкретно с этим - проблем нет, всё сохраняется и отображается как надо. Проблема в другом - я решил делать ресайз принимаемых картинок, ибо во первых - нефиг их в мегаразрешениях хранить, во вторых - надо делать превьюшки картинок, чтоб не грузить канал мегаданными.
Ну, думаю, всё фигня, 5 минут и вопрос решён - гугл в руки и вперёд.
Код:

apt-get install Imagemagick
npm install easyimage

Далее берём простейший код и вроде как радуемся данным изображения (baseText - имя файла):
Код:

var easyimage = require('easyimage');
easyimage.info(__dirname + '/uploads/images/'+baseText).then(
    function(file) {
        console.log(file);
    }, function (err) {
        console.log(err);
    }
);

И, казалось бы, вот оно - счастье. Но хрен тут был, имеем ошибку:
Код:

[Error: identify: no decode delegate for this image format `' @ error/constitute.c/ReadImage/501.]
Пол дня рылся, не понял в чём проблема. Ну, думаю, ладно, припишу расширение (файл был png, потому приписал, соответственно, ".png"). Запускаю запрос файла заново - имею ошибку номер 2:
Код:

[Error: identify: improper image header `.../uploads/images/image_8b7cea9f-a80a-4069-a326-273b6ecc8c65.png' @ error/png.c/ReadPNGImage/3930.
И вот тут я понял, что вообще не понял. Файл сохранял по всем канонам гугла - всеми возможными способами. И, если файл сохранить убрав 'binary', и потом проверить, то внутри всё будет вроде как нормально:
Код:

data:image/png;base64,...
Причём эта сохранённая картинка не открывается ни одним просмотрщиком, а в тот единственный раз, когда мне каким-то чудом удалось таки добиться до её данных из ноды (через модуль file-type и какой-то из вариантов сохранения изображения использовал), то мне написало что mime у неё "text/plane". Что я делаю не так? И почему оно отображается в браузере и в UIImage нормально (причём в обеих вариантах - при сохранении как 'binary' и как обычный файл)?

Nerd 06.05.2016 01:18

Ответ: node.js + imagemagick
 
Проверь ручками содержимое сохранённого файла. У нормального png файла в начале должно стоять 0x89 P N G 0x0D.
Либо клиент отправляет не png, либо данные файла по пути обрастают какими-нибудь url-эскейпами.

St_AnGer 06.05.2016 09:44

Ответ: node.js + imagemagick
 
Цитата:

Сообщение от Nerd (Сообщение 305953)
Проверь ручками содержимое сохранённого файла. У нормального png файла в начале должно стоять 0x89 P N G 0x0D.
Либо клиент отправляет не png, либо данные файла по пути обрастают какими-нибудь url-эскейпами.

Проверил. Действительно, я же никаких действий не предпринимал при сохранении, то есть сохранял прям полученную строку вида
Код:

data:image/jpeg;base64,iVBORw0KGgo...
Сейчас убрал лишнее вначале (data:image/jpeg;base64,) и сохранил в файл new Buffer декодировав из base64. Внезапно, всё получилось, спасибо! :)

moka 07.05.2016 15:37

Ответ: node.js + imagemagick
 
Цитата:

no decode delegate for this image format
Это ошибка самого IM, говорит о том что он не знает как с этим форматом работать, по причине отсутствия дополнительных расширений для поддержки данного формата.
Делегаты можно устанавливать отдельно.

Хоть твоя проблема была другой.

Также ты получаешь файл, и затем сохраняешь его - это чертовски не оптимально, т.к. при скачке этот файл храниться всё время в памяти, и лишь потом пишеться на жёсткий. Это не взлетит при большом объеме паралельных закачек.
Заливай файлы через классический FormData используя POST запрос. И на стороне сервера, используя например busboy (имхо, самый збсь парсер файлов), сразу стримь в файл.

По факту, nodejs gm модуль, что юзает тоже IM, умеет также работать с потоками, следственно можно вообще обрабатывать сразу на лету принимаемый файл и сохранять уже обработанные данные.


Часовой пояс GMT +4, время: 09:07.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot