Stilfrage

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.
Benutzeravatar
Mr_Snede
User
Beiträge: 387
Registriert: Sonntag 8. Februar 2004, 16:02
Wohnort: D-Dorf, Bo

Beitragvon Mr_Snede » Samstag 12. Februar 2005, 00:36

Wie benutze ich mit optparse Listen als Parameter/Defaultwert?
Wenn ich bei [1] type="string" angebe meckert der Interpreter:

Code: Alles auswählen

TypeError: cannot concatenate 'str' and 'list' objects

Was ich ja nachvollziehen kann da ja eine Liste kein String ist sondern in diesem Fall nur Strings enthält.

Einen String wie etwa "jpg-png-..." zu benutzen und den dann wieder in eine Liste aufzusplitten kann doch nicht der einzige Weg sein.

cu Sebastian


Code: Alles auswählen

#!/usr/bin/python
# -*- encoding: latin-1 -*-

import sys, os, Image, optparse, string

def parse_options():

# ... gekürzt

    # create parser object
    parser = optparse.OptionParser()

# ... gekürzt

    parser.add_option("-p", "--pic_list",
        action="store",
        type="??????", # <----------------------- [1]
        dest="pic_list",
        default = ["jpg", "jpeg", "jp2", "png", "gif", "bmp", "tiff"],
        help = "Image format that will be processed \n --> default = jpg, jpeg, jp2, png, gif, bmp, tiff")


# ... gekürzt

def main():
    #Optionen und Argumente parsen
    (options, args) = parse_options()

    every_image_in_folder(options.pic_search_directory, options.thumb_height, options.pic_list)



if __name__ == '__main__':
    main()
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Samstag 12. Februar 2005, 11:43

Wie wärs denn damit?

Code: Alles auswählen

#!/usr/bin/python
# -*- encoding: latin-1 -*-

import sys, os, optparse

def parse_options():
    parser = optparse.OptionParser()

    parser.add_option("-p", "--pic_list",
        action="store",
        type="string", # <----------------------- [1]
        dest="pic_list",
        default = "jpg, jpeg, jp2, png, gif, bmp, tiff",
        help = "Image format that will be processed \n --> default = jpg, jpeg, jp2, png, gif, bmp, tiff")
    (options, args) = parser.parse_args()
    options.pic_list = options.pic_list.split(',')
    print options.pic_list

def main():
    parse_options()

if __name__ == '__main__':
    main()


Wer gibt denn schon eine Liste wie ['png', 'psd', 'xbm', 'xpm', 'svg'] als commandline Parameter an? da ist es doch besser png,psd,xbm,xpm zu nehmen.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
Mr_Snede
User
Beiträge: 387
Registriert: Sonntag 8. Februar 2004, 16:02
Wohnort: D-Dorf, Bo

Beitragvon Mr_Snede » Samstag 12. Februar 2005, 18:18

Dank an Leonidas und den anderen.
Mittlerweile habe ich alle geplanten Funktionen implementiert, jetzt muss ich noch etwas testen und dann werde ich mal dazu eine kleine GUI zu bauen.

os.listdi() gibt ja auch Ordner aus. Daraus ein Thumbnail zu machen ist ja etwas unsinnig. Deswegen habe ich mir folgendes[1] ausgedacht um die Ordner zu überspringen:

Code: Alles auswählen

for this_file in os.listdir(input_folder):
        if os.path.isfile(os.path.join(input_folder, this_file)) == 1:
        ...
        else:
            print "\n! " + os.path.join(input_folder, this_file) + " is a folder not a file"

Ist das eine übliche Vorgehensweise? Wenn nein wie währt ihr das angegangen?
Habt ihr sonst noch Anmerkungen vielleicht in Hinblick auf's kommende GUI?

Cu Sebastian

Hier mal die aktuellste Version:

Code: Alles auswählen

#!/usr/bin/python
# -*- encoding: latin-1 -*-

import sys, os, Image, optparse, string


__version__ = "0.0.5"



def parse_options():
    """
    parses and returns commandline options
    """
    #define usage-text
    usage = "\n    %prog [thumb_height] \n\n" + \
            "    Description: \n" + \
            "    Generates a thumbnail for every pic in a folder \n" + \
            "    by Sebastian Koch 2004 "
    version = "%prog " + __version__

    # create parser object
    parser = optparse.OptionParser(usage = usage, version = version)

    parser.add_option("-y", "--thumb_height",
        action="store", type="int", dest="thumb_height", default = 100,
        help = "(in pixel) used to calculate thumb_width by aspectratio of inputpic --> default = 100")


    parser.add_option("-p", "--pic_list",
        action = "store", type = "string", dest = "pic_list", default = "jpg,jpeg,jp2,png,gif,bmp,tiff",
        help = "Image format that will be processed --> default = jpg, jpeg, jp2, png, gif, bmp, tiff")

    parser.add_option("-d", "--directory",
        action="store", type="string", dest="pic_search_directory", default = os.getcwd(),
        help = "Path where the pictures lay to be 'thumbnaild' --> default = current working directory")


    #parse options
    (options, args) = parser.parse_args()

    options.pic_list = options.pic_list.split(',')
    #print options.pic_list

    if len(sys.argv) <=1:
        print "Running without Arguments by using following defaults:"
        print "-->Thumb_heigt = 100,  pic_list = jpg, jpeg, jp2, png, gif, bmp, tiff"
        print "--> pic_search_directory = ", os.getcwd(), "\n"
        print "For help run: ", sys.argv[0], "-h or --help \n\n"
    else:
        #print "height used for thumbgenerating: ", options.thumb_height
        print "For help run: ", sys.argv[0], "-h or --help \n\n"

    return (options, args)



def create_thumb(file_full_path, thumb_height):
    """ creates a thumb of a pic by a given height with original aspectratio
        Paramters:
            file_full_path = path/to/file.ext
            thumb_height =  (in pixel) used to calculate thumb_width by aspectratio of inputpic
    """
    no_extension = os.path.splitext(file_full_path)[0]

    im = Image.open(file_full_path)
    original_width, original_height = im.size
    thumb_width = thumb_height * original_width / original_height
    im.thumbnail((thumb_width, thumb_height), Image.ANTIALIAS)
    im.save(no_extension + "-thumb.jpg", "JPEG")

    print "\n" + "-"*10 + " Thumb created:"
    print "height x width: " +"[Original:", original_height, "x", original_width, "] -" + " [Thumb:", thumb_height, "x", thumb_width,  "]"
    print "--> " + no_extension+ "-thumb.jpg "



def every_image_in_folder(input_folder, thumb_height, pic_list):
    """ walks through a given folder and calls create_thumb() for every image
        Paramters:
            inputfolder = folder with original pics
            thumb_height = used to call create_thumb()
    """
    for this_file in os.listdir(input_folder):
        if os.path.isfile(os.path.join(input_folder, this_file)) == 1: <------------------------------------[1]
            if string.lower(os.path.splitext(this_file)[1][1:]) in pic_list:
                create_thumb(os.path.join(input_folder, this_file), thumb_height)
            else:
                print "! " + this_file + " is not a pic! Or not defined in the pic_list"
        else:
            print "\n! " + os.path.join(input_folder, this_file) + " is a folder not a file"



def main():
    #parse options and arguments
    (options, args) = parse_options()

    every_image_in_folder(options.pic_search_directory, options.thumb_height, options.pic_list)



if __name__ == '__main__':
    main()
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Samstag 12. Februar 2005, 21:45

Mr_Snede hat geschrieben:os.listdi() gibt ja auch Ordner aus. Daraus ein Thumbnail zu machen ist ja etwas unsinnig. Deswegen habe ich mir folgendes[1] ausgedacht um die Ordner zu überspringen:

Code: Alles auswählen

for this_file in os.listdir(input_folder):
        if os.path.isfile(os.path.join(input_folder, this_file)) == 1:
        ...
        else:
            print "\n! " + os.path.join(input_folder, this_file) + " is a folder not a file"

Ist das eine übliche Vorgehensweise? Wenn nein wie währt ihr das angegangen?

Da gabs doch auch was von python-forum.de! Gute Codes, gute Besserung... ähhh Diskussion.

Mr_Snede hat geschrieben:Habt ihr sonst noch Anmerkungen vielleicht in Hinblick auf's kommende GUI?

Ja. Bitte keine Qt GUI, die wird dann alle Windows'ler ausschließen (zumindest bis Qt4, aber ob PyQt mitzieht ist unbekannt).
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
Mr_Snede
User
Beiträge: 387
Registriert: Sonntag 8. Februar 2004, 16:02
Wohnort: D-Dorf, Bo

Beitragvon Mr_Snede » Samstag 12. Februar 2005, 22:13

Ja. Bitte keine Qt GUI, die wird dann alle Windows'ler ausschließen (zumindest bis Qt4, aber ob PyQt mitzieht ist unbekannt).

Ich werde auch QT ausprobieren (wie alle anderen auch für die ich Bindings via apt-get bekomme ) default wird aber tk.

Da gabs doch auch was von python-forum.de! Gute Codes, gute Besserung... ähhh Diskussion.

Das ist mir nu aber peinlich, da habe ich letztens noch reingeschaut.

cu Sebastian
Benutzeravatar
Mr_Snede
User
Beiträge: 387
Registriert: Sonntag 8. Februar 2004, 16:02
Wohnort: D-Dorf, Bo

Beitragvon Mr_Snede » Mittwoch 16. Februar 2005, 19:42

Nun habe ich mir ein kleines GUI zusammengebastelt.
Leider bekomme ich eine Fehlermeldung, wenn den "los" Button betätige:

Code: Alles auswählen

Traceback (most recent call last):
  File "/usr/lib/python2.3/lib-tk/Tkinter.py", line 1345, in __call__
    return self.func(*args)
  File "tk-ni2t.py", line 110, in create_them
    every_image_in_folder(pic_dir, thumb_height, pic_list)
  File "tk-ni2t.py", line 69, in every_image_in_folder
    create_thumb(os.path.join(input_folder, this_file), thumb_height)
  File "tk-ni2t.py", line 87, in create_thumb
    im = Image.open(file_full_path)
AttributeError: class Image has no attribute 'open'


Mit dieser Fehlermeldung kann ich nicht viel anfangen.
Meine einziger Ansatz gienge in die Richtung der Gültigkeit von Namensräumen.

zum schnelleren Einsteigen:
Button "los" (Zeile:147) ruft create_them() (Zeile:108) auf
create_them() ruft every_image_in_folder() (Zeile:60) auf
every_image_in_folder() ruft create_thumb() (Zeile:78)

Ich glaube, ich werde den gesamten Programmablauf noch einmal überdenken, das ist mir alles etwas zu kompliziert.

Code: Alles auswählen

#!/usr/bin/python
# -*- encoding: latin-1 -*-

import sys, os, Image, string, optparse
from Tkinter import *
import tkFileDialog


__version__ = "0.0.6"


#----------------------------------------------------------
def parse_options():
    """
    parses and returns commandline options
    """
    #define usage-text
    usage = "\n    %prog [thumb_height] \n\n" + \
            "    Description: \n" + \
            "    Generates a thumbnail for every pic in a folder \n" + \
            "    by Sebastian Koch 2004 "
    version = "%prog " + __version__

    # create parser object
    parser = optparse.OptionParser(usage = usage, version = version)

    parser.add_option("-y", "--thumb_height",
        action="store", type="int", dest="thumb_height", default = 100,
        help = "(in pixel) used to calculate thumb_width by aspectratio of inputpic --> default = 100")


    parser.add_option("-p", "--pic_list",
        action = "store", type = "string", dest = "pic_list", default = "jpg,jpeg,jp2,png,gif,bmp,tiff",
        help = "Image format that will be processed --> default = jpg, jpeg, jp2, png, gif, bmp, tiff")

    parser.add_option("-d", "--directory",
        action="store", type="string", dest="pic_dir", default = os.getcwd(),
        help = "Path where the pictures lay to be 'thumbnaild' --> default = current working directory")


    #parse options
    (options, args) = parser.parse_args()
    #string of pic types "jpg, png, ..." -> list of pic types ['jpg', 'png', ...]
    options.pic_list = options.pic_list.split(',')


    if len(sys.argv) <=1:
        print "Running without Arguments by using following defaults:"
        print "-->Thumb_heigt = 100,  pic_list = jpg, jpeg, jp2, png, gif, bmp, tiff"
        print "--> pic_dir = ", os.getcwd(), "\n"
        print "For help run: ", sys.argv[0], "-h or --help \n\n"
    else:
        #print "height used for thumbgenerating: ", options.thumb_height
        print "For help run: ", sys.argv[0], "-h or --help \n\n"

    return (options, args)


#----------------------------------------------------------
def every_image_in_folder(input_folder, thumb_height, pic_list):
    """ walks through a given folder and calls create_thumb() for every image
        Paramters:
            inputfolder = folder with original pics
            thumb_height = used to call create_thumb()
    """
    for this_file in os.listdir(input_folder):
        if os.path.isfile(os.path.join(input_folder, this_file)) == 1:
            if string.lower(os.path.splitext(this_file)[1][1:]) in pic_list:
                create_thumb(os.path.join(input_folder, this_file), thumb_height)
            else:
                print "! " + this_file + " is not a pic! Or not defined in the pic_list"
        else:
            print "\n! " + os.path.join(input_folder, this_file) + " is a folder not a file"



#----------------------------------------------------------
def create_thumb(file_full_path, thumb_height):
    """ creates a thumb of a pic by a given height with original aspectratio
        Paramters:
            file_full_path = path/to/file.ext
            thumb_height =  (in pixel) used to calculate thumb_width by aspectratio of inputpic
    """
    no_extension = os.path.splitext(file_full_path)[0]
    print "file_full_path:" , file_full_path

    im = Image.open(file_full_path)
    original_width, original_height = im.size
    thumb_width = thumb_height * original_width / original_height
    im.thumbnail((thumb_width, thumb_height), Image.ANTIALIAS)
    im.save(no_extension + "-thumb.jpg", "JPEG")

    print "\n" + "-"*10 + " Thumb created:"
    print "height x width: " +"[Original:", original_height, "x", original_width, "] -" + " [Thumb:", thumb_height, "x", thumb_width,  "]"
    print "--> " + no_extension+ "-thumb.jpg "



#----------------------------------------------------------
def tk_gui(pic_dir, thumb_height, pic_list):
    """
    creates a Tkinter GUI
    """
    def open_it():
        pic_dir = tkFileDialog.askdirectory()
        btn_pic_dir["text"] = pic_dir

    def create_them():
        #print "pic_dir: ", pic_dir, "\n" + "thumb_height: ", thumb_height, "\n" + "pic_list: ", pic_list
        every_image_in_folder(pic_dir, thumb_height, pic_list)

    master = Tk()


    # ---- widget creation
    lbl_pic_dir = Label(master, text = "Picture Directory:")
    lbl_thumb_height = Label(master, text="Thumb height:")
    btn_ende = Button(master, text = "Quit")

    btn_pic_dir = Button(master, text = "Picture Directory")
    entry_thumb_height = Entry(master)
    btn_los = Button(master, text = "Los")


    # ---- basic placement
    lbl_pic_dir.grid(row = 0, column = 0, sticky = "w")
    lbl_thumb_height.grid(row=1, column = 0, sticky = "w")
    btn_ende.grid(row = 2, column = 0, sticky = "w")

    btn_pic_dir.grid(row = 0, column = 1, sticky = "ew")
    entry_thumb_height.grid(row = 1, column = 1, sticky = "ew")
    btn_los.grid(row = 2, column = 1, sticky = "e")


    # ---- enhanced widget settings (style + Funktions)
    master.title("tk-images2thumbs")
    master.columnconfigure(1, weight=1)

    lbl_pic_dir.config(underline = 0)
    lbl_thumb_height.config(underline = 0)
    btn_ende.config(relief = GROOVE, fg = "#B00000", command = master.destroy, underline = 0) #B00000 = red

    btn_pic_dir.config(relief = SUNKEN, text = pic_dir, command = open_it, bg = "white")
    entry_thumb_height.config(bg = "white")
    entry_thumb_height.insert(0, thumb_height)
    btn_los.config(relief = GROOVE, fg = "#007500", underline = 0)#007500 = green
    btn_los.config(command = create_them)


    master.mainloop()


#----------------------------------------------------------
def main():
    #parse options and arguments
    (options, args) = parse_options()

    tk_gui(options.pic_dir, options.thumb_height, options.pic_list)



if __name__ == '__main__':
    main()
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

Beitragvon mawe » Mittwoch 16. Februar 2005, 22:00

Hi!

Ich muss gestehen, dass ich mich mit Image nicht wirklich auskenne, aber gehört das nicht so:

Code: Alles auswählen

im = Image(file_full_path)
im.open()


Gruß, mawe
BlackJack

Beitragvon BlackJack » Mittwoch 16. Februar 2005, 23:57

Das Problem ist hier

Code: Alles auswählen

import ..., Image, ...
from Tkinter import *


Es gibt ein 'Tkinter.Image' das Du in der zweiten Zeile unter dem Namen 'Image' importierst. Womit man mal wieder ein schönes Beispiel dafür hat, das/warum 'from ... import *' schlecht ist.

Bei Tkinter holt man sich damit mal eben ca. 170 Namen in das Modul.
Benutzeravatar
Mr_Snede
User
Beiträge: 387
Registriert: Sonntag 8. Februar 2004, 16:02
Wohnort: D-Dorf, Bo

Beitragvon Mr_Snede » Donnerstag 17. Februar 2005, 00:13

Hallo mawe,
die Thumbnailerzeugung basiert auf einem Beispielcode (Create JPEG Thumbnails) aus dem PIL Handbuch.

Während der Arbeit an der Commandline Version hat die Prozedur create_thumb() noch funktioniert - nur will sie seit meiner Implementation des GUI nicht mehr so wie ich...

Ich werde aber mal den ...
Ich lese gerade BlackJack' Post in der Vorschau - also doch ein Problem mit dem Namenraum.
Das werde ich direkt mal ausprobieren

danke euch

<edit>... heute wird das nix mehr, mein Bett ruft</edit>
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Donnerstag 17. Februar 2005, 13:38

* imports sind nunmal evil, das würde ich keinem empfehlen, aber besonders Tkinter Programmierer tun sowas. In wx hatte das damals noch sinn, da alle Namen davor ein wx hatten, aber nun ist das unnötig, da jetzt alles im wx Namespace liegt.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

Beitragvon mawe » Donnerstag 17. Februar 2005, 13:48

Hi!

Also ich muss zugeben, dass ich bei Tkinter meistens auch * importiere. Bis auf Image (das ich noch nie benutzt habe) glaube ich nicht, dass es da wirklich zu Nameskonflikten kommt.
BTW: reichts bei Mr_Snede's Problem nicht einfach, wenn man

Code: Alles auswählen

from Tkinter import *
import Image

schreibt?

Gruß, mawe
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Donnerstag 17. Februar 2005, 13:50

Denke schon. Nur was, wenn du Tkinter.Image brauchst?
wieso nicht ein

Code: Alles auswählen

import Tkinter as tk
# oder
import Tkinter as t

Das löst duch dir Probleme elegant und man muss uch nicht so drastisch viel mehr schreiben.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
Mr_Snede
User
Beiträge: 387
Registriert: Sonntag 8. Februar 2004, 16:02
Wohnort: D-Dorf, Bo

Beitragvon Mr_Snede » Donnerstag 17. Februar 2005, 15:20

@ mawe
habe deinen Vorschlag erfolgreich getestet - danke.(nachdem ich geschnallt habe, daß es um die Reihenfolge gieng.)

Ich denke ich werde dem Vorschlag von Leonidas folgen und die Importanweisung für Tkinter mit "as" versehen.
Diese Idee habe ich schon gestern abend in einem alten Thread gefunden und mir direkt notiert.

Dabei habe ich auch festgestellt, dass nicht nur hier im Forum sondern auch in nahezu allen anderen Beispielen Tkinter mit:

Code: Alles auswählen

from Tkinter import *
importiert wird.

Wenn ich schon bei meinem doch recht einfachen Programm auf Überschneidungen in den Namensbereichen komme - warum haben alle anderen nicht dieses Problem?

Aber ich bin glücklich, denn ob der Fehlermeldung habe ich zumindest in die richtige Richtung gedacht.

cu Sebastian
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Donnerstag 17. Februar 2005, 15:51

Mr_Snede hat geschrieben:Wenn ich schon bei meinem doch recht einfachen Programm auf Überschneidungen in den Namensbereichen komme - warum haben alle anderen nicht dieses Problem?

Haben sie auch, wissen es nur noch nicht.
Und dann wundern sie sich, warum es irgendwann irgendetwas nicht geht. Aber wie wir beide festgestellt haben, tun tie meisten Tkinter'ler * imports nehmen, weil das etwas bequemer zu tippen ist.

Es gibt auch einige, die wissen sowas und wissen auch wie man es umgehen kann, gell mawe? 8)
My god, it's full of CARs! | Leonidasvoice vs Modvoice
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

Beitragvon mawe » Donnerstag 17. Februar 2005, 15:59

Hi!

Mr_Snede hat geschrieben:Wenn ich schon bei meinem doch recht einfachen Programm auf Überschneidungen in den Namensbereichen komme - warum haben alle anderen nicht dieses Problem?

Der Grund ist wahrscheinlich, dass bei Tkinter die Gefahr von Überschneidungen eigentlich sehr gering ist. Es gibt nicht viele Module die Buttons, Labels, usw. haben. Und wenn doch (andere GUIs), dann verwendet man sie eh nicht zusammen mit Tkinter :wink:. Das mit Image ist eigentlich die einzige Überschneidung die mir bis jetzt (und auch erst seit jetzt) bekannt ist.

Leonidas hat geschrieben:Es gibt auch einige, die wissen sowas und wissen auch wie man es umgehen kann, gell mawe?

Ich werte das mal als Kompliment :) Aber wie ich oben schon geschrieben habe, die Gefahren dabei sind nicht wirklich groß (vor allem wenn man den Tkinter-Import immer als erstes schreibt :wink:)
BTW: Kennst Du (oder sonst jemand) noch Überschneidungen ausser Image?

Gruß, mawe

Wer ist online?

Mitglieder in diesem Forum: __deets__, Bing [Bot]