Текст в PNG на App Engine (Python) - PullRequest
       10

Текст в PNG на App Engine (Python)

24 голосов
/ 12 марта 2010

Примечание: я кросс-пост из группы App Engine, потому что я не получил там ответов. Как часть моего сайта о Японии, у меня есть функция, где пользователь может получить большой PNG для использования в качестве фона рабочего стола, который показывает пользователя имя по-японски. После переключения хостинга моего сайта полностью на приложение Двигатель, я удалил эту особенность, потому что я не мог найти способ визуализации текста в PNG с помощью API изображения.

Другими словами, как бы вы вывели строку Юникода на верх изображения известных размеров (например, 1024x768), чтобы текст будет как можно больше по горизонтали и по центру вертикально? Есть ли способ сделать это с помощью App Engine, или есть какой-то внешний сервис помимо App Engine, который мог бы сделать это проще для мне, что вы могли бы порекомендовать (кроме запуска ImageMagick самостоятельно сервер)?

Ответы [ 4 ]

29 голосов
/ 12 марта 2010

Решение № 1. Библиотека изображений Pure Python.

Вы можете попробовать связать PyPNG с вашим приложением. PyPNG - это чистая библиотека Python для создания изображений PNG. Это зависит от модуля zlib, который разрешен в AppEngine, поэтому PyPNG должен работать в AppEngine. Просто используйте объекты StringIO вместо файлов и записывайте в них данные PNG.

Пример бесстыдной адаптации PyPNG, как сделать растровое изображение PNG:

import png
from StringIO import StringIO

# bitmap data
s = ['110010010011',
     '101011010100',
     '110010110101',
     '100010010011']
s = map(lambda x: map(int, x), s)

f = StringIO()
w = png.Writer(len(s[0]), len(s), greyscale=True, bitdepth=1)
w.write(f, s)

# binary PNG data
print f.getvalue()

Я подозреваю, что неоптимальная производительность, но, насколько я знаю, нет другого способа генерировать изображения на GAE.

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

Чтобы отобразить текст ASCII с помощью PyPNG, взгляните на скрипт texttopng .

Итак, ограничения:

  • Возможно, медленно (необходимо проверить)
  • Обращаться к растеризации глифа

Решение № 2. Вне-сайт рендеринга текста в изображения.

Google AppEngine не предоставляет инструментов для отображения текста в виде растровых изображений, но в Google Charts. При правильном выборе параметров схема контурный текст просто отображает простой текст в изображения PNG.

Например, http://chart.apis.google.com/chart?chst=d_text_outline&chld=000000|32|h|FFFFFF|_|Render text to image|with Google Charts.|Some Unicode too:|Здра́вствуйте|こんにちは|नमस्ते|你好|שלו производит это:

text-to-image on Google Charts

Ограничения:

  • Вы не можете создавать изображения размером более 300000 пикселей
  • Настройки стиля и шрифта ограничены
  • Некоторые сценарии Unicode недоступны
  • Только на белом фоне
9 голосов
/ 13 марта 2010

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

PyBMP

PyBMP - это библиотека на чистом python, которая может выполнять простую визуализацию текста. Оттуда вы можете использовать библиотеку изображений Google, чтобы объединить полученное растровое изображение с другими вашими изображениями. Ниже приведен пример кода. Недостатком является то, что в библиотеке отсутствуют более приятные функции, такие как сглаживание и точный контроль над шрифтами, поэтому текст, который она отображает, выглядит немного дурацким. Он также может или не может хорошо обрабатывать Unicode.

# Create the image
text_img = bmp.BitMap(300,35,bmp.Color.WHITE)
# bmpfont_Tw_Cen_MT_30 is a generated file using PyBMP's tool
text_img.setFont(bmpfont_Tw_Cen_MT_30.font_data)
text_img.setPenColor( bmp.Color.BLACK )
text_img.drawText(name, 0, 0)

После этого вы можете использовать функцию Google composite на text_img.getBitmap(), как и любое другое изображение.

Внешняя обработка изображений

Если текст недостаточно хорош (это было не для моего проекта), альтернативное решение состоит в том, чтобы настроить внешний сервер в службе, такой как Rackspace, исключительно для обработки изображений. Настройте обработчик HTTP, который выполняет обработку изображений с помощью PIL, а затем возвращает получившееся изображение. Оттуда вы можете либо

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

Не красиво, но оно выполняет свою работу.

3 голосов
/ 11 апреля 2012

Уже слишком поздно, но я искал то же самое.Мне удалось нарисовать Unicode-строку (здесь Devanagari) на изображение и сохранить его в виде файла .png, выполнив следующие действия:

# -*- coding: utf-8 -*-
import Image, ImageDraw, ImageFont

img = Image.new('L', (16,16), 255)
draw = ImageDraw.Draw(img)
text_to_draw = unicode('क','utf-8')
font = ImageFont.truetype('Path/to/font/file',12)
draw.text((2,2), text_to_draw, font = font)
del draw

img.save('image.png')

PS получил помощь от других сообщений на stackoverflow

3 голосов
/ 12 марта 2010

[Стоп: Как следует из комментария, этот ответ не работает в Googe App Engine.]

Библиотека изображений Python ( PIL ) может выполнить это.

Вы можете загрузить изображение, нарисовать на нем текст Unicode с помощью функции ImageDraw.text ().

Возможно, вам потребуется несколько раз вызвать ImageDraw.textsize () с разными размерами шрифта, чтобы найти самый большой шрифт, который вам подойдет.

Наконец, вы можете сохранить изображение .png в файл (или отправить его обратно).

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

(Правильно ли я ответил на ваш вопрос? Я не знаю, есть ли PIL в Google App Engine.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...