Tekst do PNG na silniku aplikacji (Python)

Uwaga: jestem Cross-posting to z grupy App Engine, ponieważ nie mam odpowiedzi tam.

Jako część mojej strony o Japonii, mam funkcję, gdzie użytkownik może Pobierz duży PNG do użycia jako tło pulpitu, które pokazuje użytkownika imię po japońsku. Po przełączeniu mojej strony hosting całkowicie na aplikację Silnika, usunąłem tę szczególną funkcję, ponieważ nie mogłem znaleźć żadnego sposób renderowania tekstu do PNG za pomocą interfejsu API obrazu.

Innymi słowy, jak byś wyprowadzanie ciągu unicode na Góra obrazu o znanych wymiarach (np. 1024x768), tak aby tekst będzie jak największy poziomo i wyśrodkowany pionowo? Czy jest jakiś sposób, aby to zrobić jest App Engine, czy jest jakiś serwis zewnętrzny oprócz silnika aplikacji, który mógłby ułatwić mnie, że można polecić (poza uruchomieniem ImageMagick na własną serwer)?

Author: Bemmu, 2010-03-12

4 answers

Rozwiązanie # 1. Pure Python image library.

Możesz spróbować połączyć PyPNG ze swoją aplikacją. PyPNG jest czystą biblioteką Pythona do tworzenia obrazów PNG. To zależy od modułu zlib, który jest dozwolony na AppEngine, więc PyPNG powinien działać na AppEngine. Wystarczy użyć obiektów StringIO zamiast plików i zapisać do nich dane PNG.

Bezwstydnie dostosowując przykład PyPNG jak zrobić bitmapowy obraz 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()

Podejrzewam nieoptymalną wydajność, ale z tego co wiem, nie ma inny sposób generowania obrazów na GAE.

I nadal musisz dowiedzieć się, jak rasteryzować tekst, aby uzyskać dane Bitmapowe. Najprostszym sposobem, prawdopodobnie, jest trzymanie bitmap wszystkich symboli wokół (zasadniczo przy użyciu czcionki bitmapowej).

Aby renderować tekst ASCII za pomocą PyPNG, spójrz na skrypt texttopng .

Więc ograniczenia to:

  • prawdopodobnie wolno (trzeba sprawdzić)
  • Rasteryzacja glifów ma być adresowana

Rozwiązanie # 2. Renderowanie tekstu na obraz.

Google AppEngine nie zapewnia narzędzi do renderowania tekstu jako obrazów rastrowych, ale wykresy Google tak. Przy odpowiednim doborze parametrów Wykres kontur tekstu renderuje zwykły tekst na obrazy PNG.

Na przykład, 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:|Здра́вствуйте|こんにちは|नमस्ते|你好|שלו tworzy to:

tekst-obraz na wykresach Google

Ograniczenia:

  • nie można wygenerować obrazów większych niż 300000 pikseli
  • modyfikacje stylów i czcionek są ograniczone
  • niektóre skrypty Unicode nie są dostępne
  • tylko białe tło
 29
Author: sastanin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-08 14:22:31

Natknąłem się na ten sam problem z pisaniem tekstu do obrazu. Problem polega na tym, że wszelkie biblioteki obrazowania używane w google app engine muszą być czystym Pythonem, co wyklucza PIL.

PyBMP

PyBMP jest czystą biblioteką Pythona, która może wykonywać proste renderowanie tekstu. Stamtąd możesz użyć biblioteki obrazowania google, aby złożyć wynikową bitmapę na innych zdjęciach. Poniżej znajduje się przykładowy kod. Minusem jest to, że biblioteka nie ma ładniejszych funkcji, takich jak antyaliasing i dobra kontrola nad czcionkami, więc tekst, który renderuje, wygląda trochę gównianie. Może również dobrze obsługiwać 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)

Po tym możesz użyć funkcji google composite na text_img.getBitmap(), Jak każdy inny obraz.

Zewnętrzne Przetwarzanie Obrazu

Jeśli tekst nie jest wystarczająco dobry (nie był to mój projekt), alternatywnym rozwiązaniem jest skonfigurowanie zewnętrznego serwera na usłudze takiej jak Rackspace wyłącznie do przetwarzania obrazów. Skonfiguruj funkcję obsługi HTTP, która wykonuje Twój obraz przetwarzanie za pomocą PIL, a następnie zwraca wynikowy obraz. Stamtąd możesz albo

  • prześlij wynik bezpośrednio na serwer hostujący pliki statyczne (jak s3) lub
  • [18]} uzyskaj wynik wygenerowanego obrazu tekstowego za pomocą biblioteki urlfetch silnika aplikacji i wykonaj resztę kompozycji w silniku aplikacji
Nie jest ładna, ale robi swoje.
 9
Author: Derek Dahmer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-12 23:28:49

[Stop naciśnij: jak sugeruje komentarz-ta odpowiedź nie działa w Googe App Engine.]

Biblioteka obrazowania Pythona ( PIL) może tego dokonać.

Możesz załadować obraz, narysować na nim tekst Unicode za pomocą ImageDraw.funkcja text ().

Być może będziesz musiał zadzwonić do ImageDraw.textsize () kilka razy z różnymi rozmiarami czcionek, aby znaleźć największą czcionkę, która będzie pasować.

Wreszcie możesz zapisać .obraz png do pliku (lub podać go z powrotem bezpośrednio).

Testuj z dużymi obrazami, jeśli uruchamiasz je z kontekstu serwera www, aby upewnić się, że możesz przydzielić wystarczającą ilość pamięci do przetwarzania dużych plików PNG.

(czy odpowiedziałem odpowiednio na twoje pytanie? Nie wiem czy PIL jest opcją z poziomu Google App Engine.)

 3
Author: Oddthinking,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-12 09:55:52

Trochę za późno, ale Szukałem tego samego. Udało mi się narysować ciąg unicode (tutaj Devanagari) na obrazku i zapisać go jako '.plik png ' wykonując następujące czynności:

# -*- 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')

P. S. otrzymałem pomoc z innych postów na stackoverflow

 3
Author: user1327133,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-11 16:32:19