PIL und print und "Buß- und Bettag" (Anfänger)

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
uwe58
User
Beiträge: 4
Registriert: Mittwoch 18. November 2009, 08:58

Wir haben in Sachsen heute den "Buß-und Bettag". Dass ist jedoch nicht das Problem sondern:
Wenn ich in meinem Script

Code: Alles auswählen

print "Buß-und Bettag"
ausgebe ist alles in Ordnung. Wenn ich jedoch mit PIL

Code: Alles auswählen

draw.text((x,y),"Buß- und Bettag")
ausgebe wird dass "ß" mit einem falschen Code ausgegeben.

Was kann ich tun?

Linux - Kubuntu 9.10 - Python 2.6.4
Zuletzt geändert von uwe58 am Mittwoch 18. November 2009, 14:41, insgesamt 1-mal geändert.
Benutzeravatar
Masaru
User
Beiträge: 425
Registriert: Mittwoch 4. August 2004, 22:17

Hallo auch,

zwei Dinge musst Du tun:
1.) eine Schriftart verwenden, welche das entsprechende Zeichen beinhaltet
2.) der Schriftart mitgeben, dass vom encoding Unicode verwendet wird

Ich habe das ganze hier mal auf meiner Windows Kiste mit PIL 1.1.6 und Python 2.6.4 nachgestellt:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import Image
import ImageDraw
import ImageFont
import codecs

# Neues Image anlegen und ImageDraw Objekt damit erzeugen.
img = Image.new("RGB", (640, 200))
draw = ImageDraw.Draw(img)

# ImageFont mittels 'arial.ttf' der Windows Fonts (k.a. was Du da unter Linux laden könntest, aber da wird Dir bestimmt etwas einfallen)
font_arial_16_unic = ImageFont.truetype(r'C:\WINDOWS\Fonts\arial.ttf', 16, encoding='unic')

# Nun Deinen Text in das Image mit der so eben erzeugten Schrift schreiben und zum testen anzeigen lassen.
# Wichtig hierbei ist, dass ich dieses Script in UTF-8 abgespeichert habe, folglich der String erst einmal wieder in Unicode decodiert werden muss!
draw.text((5, 5), codecs.decode("Buß- und Bettag", 'UTF-8'), font=font_arial_16_unic)
img.show()
:!: Speichere dieses Python-Script unbedingt in UTF-8 mit Deinem Editor ab, oder passe entsprechend die MagicLine & den Decode Funktionsparameter an.

Weiterhin viel Erfolg,
>>Masaru<<
uwe58
User
Beiträge: 4
Registriert: Mittwoch 18. November 2009, 08:58

wenn ich den Text vor der Ausgabe so vorbehandle

Code: Alles auswählen

text=codecs.decode(text, 'UTF-8')
Danke für die schnelle Hilfe.
Uwe
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Masaru hat geschrieben:

Code: Alles auswählen

# Wichtig hierbei ist, dass ich dieses Script in UTF-8 abgespeichert habe, folglich der String erst einmal wieder in Unicode decodiert werden muss!
draw.text((5, 5), codecs.decode("Buß- und Bettag", 'UTF-8'), font=font_arial_16_unic)
Das ist "etwas" umständlich. u"Buß- und Bettag" tät es auch, und man muss sich bei Angabe des Encodings nicht wiederholen.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Benutzeravatar
Masaru
User
Beiträge: 425
Registriert: Mittwoch 4. August 2004, 22:17

Mhm ... wo er recht hat ...
uwe58
User
Beiträge: 4
Registriert: Mittwoch 18. November 2009, 08:58

Warum liefert das einen Fehler?

Code: Alles auswählen

#! /usr/bin/python
# -*- coding: UTF-8 -*-

def sFeiertag():
    """Liefert die Bezeichnung des Feiertags oder einen Leerstring"""
    s = u"Buß-und Bettag"
    return(s)

if __name__ == '__main__':
    s = sFeiertag()
    print s

Traceback (most recent call last):
  File "test_01.py", line 12, in <module>
    print s
UnicodeEncodeError: 'ascii' codec can't encode character u'\xdf' in position 2: ordinal not in range(128)
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Weil du versuchst Unicode auszugeben. Vor der Ausgabe von Unicode musst du es enkodieren, ansonste versucht Python das selbst - wobei es als Codec ASCII hernimmt, was natürlich fehlschlägt.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
uwe58
User
Beiträge: 4
Registriert: Mittwoch 18. November 2009, 08:58

Und wie mache ich es nun richtig?

In meinem Programm lese ich Daten aus einer Windows-Ini-Datei ein, also ANSI-Code.

Im Programm selbst lege ich die Feiertage fest, also UTF-8 oder Unicode.

Die Strings werden sowohl auf die Konsole mit print als auch auf PIL mit draw.text() ausgegeben.

Welche Kodierung soll ich benutzen?
BlackJack

@uwe58: Die Kodierung, die von dem jeweiligen Ausgabeprogramm erwartet wird. Bei ``print`` ist das allerdings schwierig, weil man das normalerweise nicht weiss. Ich persönlich nehme da in der Regel UTF-8, weil das alles kodieren kann. Kann natürlich dazu führen, dass die Ausgaben nicht richtig angezeigt werden, wenn das Programm, das für die Anzeige verantwortlich ist, etwas anderes als UTF-8 erwartet. Für den Fall würde ich die Ausgabekodierung für den Anwender einstellbar machen. Achtung: Dann muss man auch damit rechnen, das sich etwas nicht kodieren lässt, und diese Fälle entsprechend behandeln.
Antworten