Seite 1 von 1

Digitaler Bilderrahmen als Uhr (für Malfaule)

Verfasst: Freitag 10. August 2012, 09:41
von pytobi
Hi,
nachdem ich auf heise online diesen wunderbaren Artikel http://www.heise.de/foto/artikel/Digita ... 23520.html gelesen hatte, kam mir die Idee, das doch auch mal zu versuchen.

Ich kaufte mir schnell bei Ebay für wenig Geld nen kleinen 7Zoll Intenso Bilderrahmen und fing an mit Gimp zu zeichnen. Nach ner halben Stunde war mein erstes Bild fertig und ich hatte keine Lust mehr. Und fing an zu programmieren.

Jetzt ist der Bildergenerator fertig und ich will ihn euch nicht vorenthalten. Ist mehr schnell als elegant programmiert ;). 720 Bilder in 13 Sekunden hört sich viel besser an.

Kurze Beschreibung der Möglichkeiten:
Displaygröße, alle Farben, Schriftart und -größe, Anzeigedauer des Bilderrahmens und natürlich der Text können verändert werden.

Was noch fehlt:
Startzeitwahl für automatisches Einschalten des Rahmens

Wie sieht das aus:
Bild

Und jetzt der Code:

Code: Alles auswählen

# -*- coding: iso-8859-1 -*-
import sys, random
import Image, ImageDraw, ImageFont

class PictureFrameClock:
    #version 0.1
    #author pytobi
    def __init__(self, args):
        #display size
        self.size=(480, 234)
        #display text
        self.text=[[('es ist', '1'), ('wir haben', '2'), ('jetzt ist es', '3')], [('zehn', '10'), ('fünf', '5'), ('zwanzig', '20'), ('viertel', '15')], [('nach', 'n1'), ('vor', 'n2'), ('halb', 'x1')], [('drei', '3'), ('vier', '4'), ('neun', '9'), ('zwölf', '12'), ('eins', '1'), ('zehn', '10')], [('sieben', '7'), ('zwei', '2'), ('acht', '8'), ('sechs', '6'), ('fünf', '5'), ('elf', '11')], [('uhr', '1')]]
        #backgroud color
        self.bg='#000000'
        #active text color
        self.on='#FFFF10'
        #inactive text color
        self.off='#616161'
        #font size
        fsize=30
        #font
        self.myfont=ImageFont.truetype('dejavusans.ttf', fsize)
        #display time
        self.displaytime=1
        #gap between lines
        self.gap=(self.size[1]-len(self.text)*fsize)/(len(self.text)+1)
        #vertical pitch
        self.pitch=self.gap+fsize
        #self.createPic('test')
        self.createClock()
        sys.exit(0)
        
    def createPic(self, fname, minute=0, n=0, x=0, hour=0, u=0, rnum=0):
        #create image
        self.im = Image.new('RGB', self.size, self.bg)
        draw = ImageDraw.Draw(self.im)
        ypos=self.gap
        #create text lines
        for i in range (len(self.text)):
            #compute horizontal gap between words
            str=''
            for entry in self.text[i]:
                str+=entry[0]
            s=draw.textsize(str, font=self.myfont)[0]
            linegap=(self.size[0]-s)/(len(self.text[i])+1)
            xpos=linegap
            #create words
            for j in range(len(self.text[i])):
                #check if word needs to be active or inactive
                if i==0:
                    if self.text[i][j][1]=='%s' % rnum:
                        color=self.on
                    else:
                        color=self.off
                if i==1:
                    if self.text[i][j][1]=='%s' % minute:
                        color=self.on
                    else:
                        color=self.off
                if i==2:
                    if self.text[i][j][1]=='n%s' % n:
                        color=self.on
                    elif self.text[i][j][1]=='x%s' % x:
                        color=self.on
                    else:
                        color=self.off
                if i==3 or i==4:
                    if self.text[i][j][1]=='%s' % hour:
                        color=self.on
                    else:
                        color=self.off
                if i==5:
                    if self.text[i][j][1]=='%s' % u:
                        color=self.on
                    else:
                        color=self.off
                draw.text((xpos, ypos), self.text[i][j][0], font=self.myfont, fill=color)
                xpos+=draw.textsize(self.text[i][j][0], font=self.myfont)[0]+linegap
            ypos+=self.pitch
        #save image
        self.im.save(fname+'.jpg', "JPEG")
        
    def createClock(self):
        #translate clock time into spoken time
        for i in range(12):
            if i==0:
                hour=12
            else:
                hour=i
            for j in range(60):
                if j==0:
                    minute=0
                    n=0
                    x=0
                    if hour==1:
                        u=0
                    else:
                        u=1
                elif j==5:
                    u=0
                    minute=5
                    n=1
                elif j==10:
                    minute=10
                elif j==15:
                    minute=15
                elif j==20:
                    minute=20
                elif j==25:
                    minute=5
                    n=2
                    x=1
                    if hour==12:
                        hour=1
                    else:
                        hour=i+1
                elif j==30:
                    minute=0
                    n=0
                elif j==35:
                    minute=5
                    n=1
                elif j==40:
                    minute=20
                    n=2
                    x=0
                elif j==45:
                    minute=15
                elif j==50:
                    minute=10
                elif j==55:
                    minute=5
                #only needed because displaytime can be smaller than minimum clock time (5 mins)
                if j%5==0:
                    rnum=random.randint(1,3)
                #create new pic
                if j%self.displaytime==0:
                    self.createPic('%02d_%02d' %(i, j), minute, n, x, hour, u, rnum)
                
args = sys.argv[1:]
if __name__ == '__main__': PictureFrameClock(args)
Hoffe es gibt noch mehr irre Bastler!

Re: Digitaler Bilderrahmen als Uhr (für Malfaule)

Verfasst: Freitag 10. August 2012, 17:42
von Hyperion
Also diese ganzen `if...elif...else`-Kaskaden solltest Du doch mal überarbeiten. Bis auf wenige Ausnahmen sieht das doch alles nach Copy&Paste-Programmierung aus.

Und `for i in range (len(self.text)):` ist der typische Anti-Pattern des Listeniterierens... wieso benutzt Du da kein `enumerate()`?

Ansonsten ist die Idee ziemlich kurios und das Ergebnis recht stylisch :-) Wobei ich solchen Bilderrahmen an sich nix abgewinnen kann :-D

Re: Digitaler Bilderrahmen als Uhr (für Malfaule)

Verfasst: Samstag 11. August 2012, 19:58
von darktrym
Mach ich da was falsch? Unter Windows bekomme ich folgenden Fehler zu sehen:
Traceback (most recent call last):
File "pictureframeclock.py", line 141, in <module>
if __name__ == '__main__': PictureFrameClock(args)
File "pictureframeclock.py", line 22, in __init__
self.myfont=ImageFont.truetype('dejavusans.ttf', fsize)
File "C:\python27\lib\site-packages\PIL\ImageFont.py", line 218, in truetype
return FreeTypeFont(filename, size, index, encoding)
File "C:\python27\lib\site-packages\PIL\ImageFont.py", line 134, in __init__
self.font = core.getfont(file, size, index, encoding)
File "C:\python27\lib\site-packages\PIL\ImageFont.py", line 34, in __getattr__
raise ImportError("The _imagingft C module is not installed")
ImportError: The _imagingft C module is not installed

Re: Digitaler Bilderrahmen als Uhr (für Malfaule)

Verfasst: Montag 13. August 2012, 09:48
von pytobi
@darktrym
Ja, es wird eine PIL-Version kompiliert mit libfreetype benötigt. Die gibts zum Beispiel hier: http://www.lfd.uci.edu/~gohlke/pythonlibs/
Die wird benötigt, weil ich sonst keine Truetype Schriften verwenden kann, und die anderen sind nicht skalierbar.

@Hyperion
Du hast recht, besonders schön ist das ganze nicht. Vielleicht komm ich nochmal dazu ein bisschen zu cleanen.
Die enumerate-Funktion kannte ich noch gar nicht, muss ich mir mal anschauen.

Re: Digitaler Bilderrahmen als Uhr (für Malfaule)

Verfasst: Montag 13. August 2012, 20:59
von darktrym
Nur kurz Feedback für die Nachwelt. Diese PIL Versionen sind allesamt ziemlich broken, keine Ahnung was der Typ damit macht.
Ergebnis: Kein Fenster, aber auch kein Werfen einer Exception dafür erfolgreiches Beenden mit Rückgabewert 0.

Re: Digitaler Bilderrahmen als Uhr (für Malfaule)

Verfasst: Montag 13. August 2012, 21:23
von BlackJack
@darktrym: Was meinst Du mit „kein Fenster”? Das Programm erzeugt einen Haufen Bilddateien. Es hat keine GUI. Und es gibt auch keinen Text auf der Konsole aus. Das heisst ein Rückgabewert von 0 ist das einzige was Du neben den Bilddateien erwarten solltest.

Re: Digitaler Bilderrahmen als Uhr (für Malfaule)

Verfasst: Montag 10. September 2012, 21:37
von darktrym
Gut, dann funktioniert das Programm. Ich bin vom Beschreibung ausgegangen, also das ein Viewer integriert ist.