Генерация PNG из длинного текста с ограничениями - PullRequest
0 голосов
/ 24 января 2019

Мне нужно, чтобы я мог генерировать прозрачный PNG с очень длинным текстом (скажем, 3000 символов) менее чем за одну секунду.

Мои ограничения:

  • текст должен быть автоматически обернут в соответствии с шириной .png и размером шрифта
  • текст длиной 3000 символов генерируется менее чем за 1 с
  • конвертер может работать с любым шрифтом .ttf
  • конвертер может обрабатывать произвольный размер шрифта, пользовательскую плотность, цвет шрифта, межстрочный интервал, кернинг символов
  • прозрачный фон
  • должен работать на Unix

Я пробовал с Imagemagick с функцией 'caption', как в:

convert -background transparent -font /home/user/fonts/Arial.ttf -density 72 -pointsize 24 -kerning 0 -interline-spacing 0 -size 500x caption:'My very long text ...' output.png

Это работает как брелок для небольших текстов, но текст длиной в 3000 символов сгенерируется за 16 секунд, и я не смог найти способ его оптимизировать. Я пробовал каждый параметр «-quality» от 0 до 100, но безуспешно.

Например, 791 символ с качеством 15 занял 3,45 с. Примерно в то же время от 0 до 100.

convert -background transparent -font Arial.ttf -density 72 -pointsize 24 -size 500x caption:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec malesuada lorem ante, ut venenatis leo venenatis vitae. Phasellus imperdiet volutpat egestas. Nunc lobortis nunc ante, sagittis sagittis ex aliquet sed. Maecenas tempus velit eu leo cursus aliquam. Donec vel purus eget massa lacinia gravida vel vitae elit. Aliquam volutpat ex non purus aliquam, vel faucibus sem molestie. Quisque tincidunt, nulla sed fermentum condimentum, mauris arcu euismod nibh, nec lobortis tortor lorem id quam. Ut pretium lacinia risus id pretium. Suspendisse sit amet dolor ac odio convallis pulvinar vitae ac erat. Nam non congue tellus. Nulla laoreet at justo eget convallis. Phasellus rutrum turpis sed neque vulputate pharetra. Mauris fringilla tincidunt dui, in scelerisque urna sagittis sit amet." -quality 15 /tmp/test.png
quality 15 : 3.4526860713959 s

Он попробовал GraphicksMagick (как упоминалось в этой теме Медленный рендеринг шрифтов в ImageMagick ), но я не смог его скомпилировать с опцией --with-ttf, даже если на моем сервере установлен freefont2). Я упал здесь.

Я также попытался сгенерировать небольшой .svg, содержащий мой текст, и преобразовать его в .png с помощью инструмента rsvg. Это действительно быстрее, но не соответствует моему ограничению автоматической упаковки (для создания самой упаковки потребуется другой фрагмент кода, чего я не хочу).

У меня сокращен таймфрейм, чтобы найти решение, поэтому я не могу самостоятельно протестировать любой другой возможный способ (попробуйте другой способ оптимизировать IM? Node.js с text2png или node-canvas? Маленьким Java-приложением? ...).

Кто-нибудь имел такие ограничения и мог бы мягко дать подсказку о рабочем решении?


Версия ImageMagick

Version: ImageMagick 6.8.9-9 Q16 x86_64 2018-11-11 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2014 ImageMagick Studio LLC
Features: DPC Modules OpenMP
Delegates: bzlib cairo djvu fftw fontconfig freetype jbig jng jpeg lcms lqr ltdl lzma openexr pangocairo png rsvg tiff wmf x xml zlib

Версия GraphicksMagick протестирована

GraphicsMagick 1.3.31 2018-11-17 Q8 http://www.GraphicsMagick.org/
Copyright (C) 2002-2018 GraphicsMagick Group.

Ответы [ 2 ]

0 голосов
/ 24 января 2019

Я пытался с libvips на этом скромном ноутбуке 2015 года, работающем под управлением Ubuntu.Вы должны быть в состоянии найти vips в вашем менеджере пакетов (например, libvips-tools в Debian):

$ time vips text x.png "$(cat lorem.txt)" --width 500
real    0m0.084s
user    0m0.062s
sys 0m0.022s

Генерация:

enter image description here

Где:

$ wc lorem.txt 
   1  483 3122 lorem.txt

Итак, 3121 символов текста в 0,1 с.

Это создание однополосного PNG.Если вы хотите прозрачности, вам нужно сделать сплошное черное изображение, а затем добавить текст в виде альфа-канала, возможно:

vips text x.v "$(cat lorem.txt)" --width 500
vips black x2.v $(vipsheader -f width x.v) $(vipsheader -f height x.v)
vips bandjoin "x2.v x.v" x.png

Что занимает здесь 0,2 с.Или в Python:

import pyvips 

txt = open("lorem.txt", "r").read()
alpha = pyvips.Image.text(txt, width=500)
black = pyvips.Image.black(alpha.width, alpha.height)
ga = black.bandjoin(alpha)
ga.write_to_file("x.png")

Текстовый оператор имеет много опций , поэтому он должен соответствовать вашим ограничениям.

0 голосов
/ 24 января 2019

Кажется, что важным фактором в скорости кодирования PNG является настройка «качество» на тестовом изображении 4000x4000:

No quality: 6.167s
Quality 9:  1.847s
Quality 1:  0.695s
...