Accueil > > > COMPACTEUR D'IMAGES JPEG PAR LOT
COMPACTEUR D'IMAGES JPEG PAR LOT
Information sur la source
Description
CompactImages v.2.1 (Compacteur d'images Jpeg par lot) Lassé d'appeler une à une avec Gimp toutes mes photos jpeg pour en réduire le poids,j'ai écrit ce programme qui lit et réécrit tous les fichier Jpeg (ou jpg) d'un répertoire donné. Cette version est une amélioration de la précédente avec les caractéristiques suivantes : Mémorisation du répertoire précédemment ouvert dans la même session, Réglage possible du taux de compression sur toute la plage autorisée en Jpeg, Possibilité de demander une sauvegarde des originaux avant compression, Visualisation multiple des images par un simple clic dans la liste, Affichage de la barre de progression du traitement, Possibilité d'interrompre le traitement à tout moment, Liste des images non traitées (images protégées ou en erreur) en fin de traitement, Affichage automatique du nom de répertoire de sauvegarde des originaux, Affichage du nombre et du poids total des images avant et après traitement Ce programme est écrit en python avec Tkinter et PIL ; il est compatible avec la compilation py2exe sous windows et c'est sous cette forme compilée que je le distribue à mes amis windowsiens. J'espère qu'il vous sera aussi utile que pour moi. Yves Le Chevalier
Source
- #Compacteur images JPEG v.2.1
- # -*- coding: utf-8 -*-
- from Tkinter import *
- from winsound import *
- from PIL import Image, ImageTk
- import glob
- import os
- import tkFileDialog
- import string
- import Tix
- import shutil
- import tkMessageBox
-
- global repert, dirinit, nbfich, tailaff, taux, chtaux, indsauv
- taux = 85
- dirinit = ''
- indsauv='N'
-
- def Exploration() :
- global repert, dirinit, nbfich,tailaff, tailrepe
- list1.delete(0,END)
- nbfich=0
- lab2.configure(text='')
- lab3.configure(text='')
- lab4.configure(text='')
- lab5.configure(text='')
- lab6.configure(text='')
- lab7.configure(text='')
- lab8.configure(text='')
- lab9.configure(text='')
- button1.config(bg='SlateGray2',text='',state=DISABLED,relief=FLAT)
- repert=tkFileDialog.askdirectory(title='Choisir le répertoire à traiter',initialdir=dirinit)
- dirinit=repert
- repert=repert+'\\*.*'
- for fichier in glob.glob(repert):
- file, ext = os.path.splitext(fichier)
- tailfich = os.path.getsize(fichier)
- tailfiaff = tailfich/1024
- chaine='%4d'%tailfiaff+' Ko ^ '+fichier
- if ext=='.jpg' or ext=='.JPG' or ext=='.jpeg' or ext=='.JPEG' :
- list1.insert(END,chaine)
- nbfich=nbfich+1
- Taille_Repert()
- tailrepe = tailaff
- if nbfich > 0 :
- lab2.configure(text='Taille cumulée des images = '+tailaff)
- lab3.configure(text='Nombre d''\'images = '+str(nbfich))
- button1.config(bg='yellow',text='Valider',state=NORMAL,relief=RAISED)
- list1.select_set(0)
- list1.bind('<ButtonRelease>',Affiche_image1)
-
- def Affiche_image1(e) :
- if nbfich > 0 :
- index = map(int,list1.curselection())[0]
- fichima = string.strip(list1.get(index))
- nom=''
- ind=0
- i=0
- while i< len(fichima) :
- if ind==1 :
- nom=nom+fichima[i]
- if fichima[i]=='^' :
- ind=1
- i=i+1
- i=i+1
- im=Image.open(nom)
- im.load()
- im.thumbnail((300,300),Image.ANTIALIAS)
- fenaff = Toplevel()
- if im.size[0] < 100 :
- larim=100
- else : larim=im.size[0]
- if im.size[1] < 20 :
- hauim=20
- else : hauim=im.size[1]
- fenaff.geometry(str(larim)+"x"+str(hauim))
- fenaff.resizable(width=False, height=False)
- fenaff.config(bg='lightgrey')
- canaff = Canvas(fenaff,width=im.size[0],height=im.size[1])
- canaff.pack()
- nombase = os.path.basename(nom)
- fenaff.title(nombase)
- vignette = ImageTk.PhotoImage(im)
- canaff.create_image(0,0,anchor=NW,image=vignette)
- canaff.monimage = vignette
- canaff.configure()
- boeff.config(text="Fermer vues",bg='DarkOliveGreen3', fg='white',state=NORMAL,relief=RAISED)
-
- def Arreter_validation() :
- global ifin3,nbok
- ifin3=1
- lab8.configure(text='Traitement interrompu : '+str(nbok)+' images traitées.')
-
- def Validation() :
- global dirinit, repert, nbfich, ficherr, tailaff, tailrep, tailrepe,ifin3,nbok,indsauv,isav
- ifin3=0
- fen3=Tix.Tk()
- geo1=fen1.winfo_geometry()
- geox=fen1.winfo_rootx()
- geoy=fen1.winfo_rooty()
- fen3.geometry("400x120+"+str(geox+55)+"+"+str(geoy+190))
- fen3.title(repert)
- labb=Label(fen3,text='Progression du compactage', fg='blue', font=('Arial', 10))
- labb.pack(side=TOP)
- meter=Tix.Meter(fen3,value=0.)
- meter.pack()
- labf=Label(fen3,text='', fg='black', font=('Arial',9))
- labf.pack(side=BOTTOM)
- Bfin3=Button(fen3,text="Arrêter",bg='pink',fg='blue', command=lambda : Arreter_validation())
- Bfin3.pack(side=BOTTOM,pady=10)
- nberr=0
- nbok = 0
- ficherr=[] # liste des fichiers en erreur écriture
- if indsauv=='O':
- isav=1
- while os.path.isdir(dirinit+'/Originaux'+str(isav)+'/') :
- isav=isav+1
- os.mkdir(dirinit+'/Originaux'+str(isav)+'/')
- if repert <> '' and nbfich>0 :
- lab4.configure(text='Traitement en cours.......Patience, merci.')
- fram5.update_idletasks()
- i=0
- for fichier in glob.glob(repert):
- file, ext = os.path.splitext(fichier)
- if ext=='.jpg' or ext=='.JPG' or ext=='.jpeg' or ext=='.JPEG' :
- if ifin3==1 :
- break
- i=i+1
- meter.config(value=float(i)/nbfich)
- meter.update()
- labf.configure(text=file)
- im=Image.open(fichier)
- chem,fich=os.path.split(fichier)
- if indsauv=='O' :
- shutil.copy(fichier,chem+'/Originaux'+str(isav)+'/'+fich)
- try :
- im.save(file+'.jpg',quality=taux)
- nbok = nbok+1
- except IOError :
- nberr = nberr+1
- ficherr.append(file)
- button1.config(text="",bg='SlateGray2',state=DISABLED,relief=FLAT)
- lab4.configure(text='Résultat du traitement :')
- Taille_Repert()
- if nbok==0 :
- lab5.configure(text=' Aucune image traitée')
- elif tailaff == tailrepe :
- lab5.configure(text=' Ce dossier est déjà compacté')
- else :
- lab5.configure(text=str(nbok)+' image(s) analysée(s)')
- lab6.configure(text='Nouvelle taille cumulée des images = '+tailaff)
- if indsauv=='O':
- lab9.configure(text='Originaux dans : '+dirinit+'/Originaux'+str(isav))
- nbfich=0
- if nberr>0 :
- Beep(800,100)
- lab7.configure(text=str(nberr)+' erreur(s)')
- Trt_Erreur(nberr,ficherr)
- repert=''
- list1.delete(0,END)
- fen3.destroy()
-
- def Taille_Repert() :
- global repert, tailaff, tailrep
- tailrep=0
- for fichier in glob.glob(repert) :
- file, ext = os.path.splitext(fichier)
- tailfich = os.path.getsize(fichier)
- if ext=='.jpg' or ext=='.JPG' or ext=='.jpeg' or ext=='.JPEG' :
- tailrep=tailrep+tailfich
- tailrep1 = tailrep/1024/1024.0
- tailaff = '%.2f' % tailrep1 +' Mo'
-
- def Trt_Erreur(nberr,ficherr) :
- fen2=Toplevel()
- geo1=fen1.winfo_geometry()
- geox=fen1.winfo_rootx()
- geoy=fen1.winfo_rooty()
- fen2.geometry("400x350+"+str(geox+55)+"+"+str(geoy+170))
- fen2.title("CompactImages : Erreurs de traitement")
- labf2=Label(fen2,text=str(nberr)+' images ne pouvant être traitées \n (Images peut-être en lecture seule)', fg='blue', font=('Arial', 9))
- labf2.pack(side=TOP,pady=10)
- fram4=Frame(fen2,borderwidth=0)
- scrollf2 =Scrollbar(fram4,orient=VERTICAL)
- listf2 = Listbox(fram4,bg='yellow',width=60,height=15,selectmode='single', yscrollcommand=scrollf2.set)
- scrollf2.config(command = listf2.yview)
- scrollf2.pack(side=LEFT,fill=Y)
- listf2.pack(side=LEFT)
- fram4.pack()
- bouf2=Button(fen2,text="Fermer",bg='brown',fg='white', command=fen2.destroy)
- bouf2.pack(side=BOTTOM,pady=10)
- for x in ficherr :
- listf2.insert(END,x)
- fen2.grab_set()
- fen2.wait_window()
-
- def Affich_Infos() :
- feninf = Toplevel()
- feninf.config(bg='SlateGray4')
- geo1=fen1.winfo_geometry()
- geox=fen1.winfo_rootx()
- geoy=fen1.winfo_rooty()
- feninf.geometry("350x390+"+str(geox+75)+"+"+str(geoy+160))
- feninf.title("À propos de CompactImages")
- labinf=Label(feninf,bg='SlateGray4', fg='white',width=50,font=('Arial', 9),
- text= "\nCompactImages v.2.1\n\n"
- "Programme écrit en Python / Tkinter \n"
- "et distribué sous licence GNU GPL.\n\n"
- "© 2008 Yves Le Chevalier\n\n"
- "Ce programme comprime toutes les images JPG (jpeg)\n"
- "d'un répertoire donné, sans modifier leurs dimensions.\n"
- "Il ne comprime pas les images protégées (en lecture seule).\n\n"
- "Le niveau de compression est réglé à 85 par défaut, mais\n"
- "peut être modifié sur toute la plage de compression Jpeg.\n\n"
- "La sauvegarde est facultative et provoque la création d'un\n"
- "sous-répertoire '''Originaux1'''. Si vous exécutez un second\n"
- "traitement sur le même répertoire, la sauvegarde se fait alors\n"
- "dans un sous-répertoire '''Originaux2''', puis la troisième fois\n"
- " dans un sous-répertoire '''Originaux3''' et ainsi de suite. \n"
- "Toutes les images analysées sont alors sauvegardées. \n"
- "Attention : Par défaut, la sauvegarde n'est pas activée.")
- labinf.pack(pady=5)
- bouf3=Button(feninf, text="Fermer", command=feninf.destroy,bg="orange", fg='brown')
- bouf3.pack(side=BOTTOM,pady=10)
- feninf.grab_set()
- feninf.wait_window()
-
- def Modif_Taux() :
- global can2, fentau, choixtau
- fentau = Toplevel()
- fentau.config(bg='SlateGray3')
- geo1=fen1.winfo_geometry()
- geox=fen1.winfo_rootx()
- geoy=fen1.winfo_rooty()
- fentau.geometry("350x330+"+str(geox+75)+"+"+str(geoy+170))
- fentau.title("Taux de compression")
- labtau=Label(fentau,bg='SlateGray3', fg='black',width=50,font=('Arial', 9),
- text= "\nModification du taux de compression\n\n"
- "ATTENTION : le niveau de compression Jpeg varie de 1 à 100 \n"
- "1 = compression maximale ; 100= aucune compression.\n\n"
- "La compression optimale se situe vers 85 (valeur par défaut).\n\n"
- "Vous pouvez changer le niveau de compression, sachant que\n"
- "si vous comprimez trop, vous perdez de la qualité et si vous ne \n"
- "comprimez pas assez, vous ne gagnez pas en volume.\n"
- "Il vaut mieux rester dans une plage de 75 à 90\n")
- labtau.pack(pady=0)
- can2 = Canvas(fentau, width=200, height=50, bg='SlateGray3')
- can2.pack(pady=20)
- curs= Scale(can2, from_=1, to=100, length=150, sliderlength=7,
- resolution=1, showvalue=1, orient=HORIZONTAL,
- label="Réglage du niveau :",command=choix_taux,font=('Arial', 8),bg='SlateGray3',fg='blue')
- curs.set (85)
- curs.pack(side=TOP)
- boutau=Button(can2, text="OK", command=set_taux,font=('Arial', 8),bg="orange", fg='brown')
- boutau.pack(side=BOTTOM)
- fentau.grab_set()
- fentau.wait_window()
-
- def choix_taux(valcurs) :
- global chtaux
- chtaux=float(valcurs)
- if chtaux < 75 or chtaux > 90 :
- fentau.config(bg='red')
- else : fentau.config(bg='green')
-
- def set_taux() :
- global chtaux, taux
- taux=int(chtaux)
- if taux < 75 or taux > 90 :
- boutau.config(text ="Niveau "+'% d' %taux,bg='red',fg='black')
- Beep(800,100)
- else : boutau.config(text ="Niveau "+'% d' %taux,bg='green',fg='black')
- if taux <> 85 :
- lab3a.configure(text='ATTENTION : Niveau compression à '+str(taux))
- else : lab3a.configure(text='')
- can2.destroy()
- fentau.destroy()
-
- def quitter_prog() :
- global fenqui
- fenqui=Toplevel()
- fenqui.config(bg='yellow',bd=3,relief='groove')
- geo1=fen1.winfo_geometry()
- geox=fen1.winfo_rootx()
- geoy=fen1.winfo_rooty()
- fenqui.geometry("200x60+"+str(geox+160)+"+"+str(geoy+350))
- fenqui.resizable(width=False, height=False)
- fenqui.overrideredirect(1)
- labqui=Label(fenqui,bg='yellow',fg='black',font=('Arial', 11),text="Quitter CompactImage ?")
- labqui.place(x=17,y=1)
- repon=StringVar()
- bououi=Button(fenqui,text="Oui", bg='pink', fg='black',command=confir_quitter)
- bounon=Button(fenqui,text="Non", bg='pink', fg='black',command=continu_prog)
- bououi.place(x=40,y=25)
- bounon.place(x=120,y=25)
- fenqui.grab_set()
-
- def confir_quitter() :
- fen1.destroy()
-
- def continu_prog() :
- global fenqui
- fenqui.destroy()
-
- def sauvegarde() :
- global indsauv
- if indsauv =='N' :
- indsauv='O'
- labsau1.configure(text='Avec sauvegarde',fg='black')
- bosav.config(text='Sans',bg='SeaGreen4', fg='white')
- else :
- indsauv='N'
- labsau1.configure(text='Sans sauvegarde',fg='grey50')
- bosav.config(text='Avec',bg='firebrick4', fg='white')
-
- def effacer_vues() :
- for widget in fen1.winfo_children():
- if isinstance(widget,Toplevel):
- widget.destroy()
- boeff.config(text="",bg='SlateGray2',state=DISABLED,relief=FLAT)
-
- def close_window() :
- if tkMessageBox.askokcancel :
- quitter_prog()
-
- # main
- fen1 = Tk(className=" CompactImages v_2,1")
- fen1.protocol("WM_DELETE_WINDOW", close_window)
- fen1.tk_setPalette(background = 'SlateGray2')
- fen1.geometry("500x800+550+100")
- fen1.resizable(width=False, height=False)
- can1 = Canvas(fen1, width=20, height=20, bg='lightgrey')
- signat=PhotoImage(file='YLC.gif')
- sign=can1.create_image(12,12, image=signat)
- can1.pack(side=BOTTOM,anchor=E)
-
- fram1=Frame(fen1,borderwidth=0)
- button2 = Button(fram1, text = 'Répertoire',bg='snow', command = Exploration)
- button2.grid(row=0,column=0,pady=20)
- boutau=Button(fram1,text=" Niveau "+'% d' %taux, bg='green', fg='black',command=Modif_Taux)
- boutau.grid(row=0,column=1,padx=30)
- bouinf=Button(fram1,text="Information", bg="seagreen4", fg='yellow',command=Affich_Infos)
- bouinf.grid(row=0,column=2,padx=30)
- bouf1=Button(fram1,text="Quitter", command=quitter_prog,bg='salmon', fg='black')
- bouf1.grid(row=0,column=3)
- labsau1=Label(fram1,text='Sans sauvegarde', fg='grey50', font=('Arial',11))
- labsau1.grid(row=1,column=0)
- bosav=Button(fram1,text="Avec", command=sauvegarde,bg='firebrick4', fg='white')
- bosav.grid(row=1,column=1)
- boeff=Button(fram1,text="",command=effacer_vues,state=DISABLED,relief=FLAT)
- boeff.grid(row=1,column=3)
- fram1.pack(side=TOP)
-
- fram2=Frame(fen1,borderwidth=0)
- labbid1=Label(fram2,text='')
- labbid1.pack(side=TOP)
- lab1=Label(fram2,text='Liste des images (Jpg ou Jpeg) à comprimer', fg='blue', font=('Arial', 12))
- lab1.pack()
- lab1b=Label(fram2,text='(Cliquer sur une ligne pour voir l''image)', fg='black', font=('Arial', 9))
- lab1b.pack()
- scrolly =Scrollbar(fram2,orient=VERTICAL)
- list1 = Listbox(fram2,bg="SlateGray1",width=70,height=31,selectmode='single', yscrollcommand=scrolly.set)
- scrolly.config(command = list1.yview)
- scrolly.pack(side=LEFT,fill=Y)
- list1.pack()
- fram2.pack()
-
- fram3=Frame(fen1)
- lab3=Label(fram3,fg='blue',font=('Arial', 9))
- lab3.grid(row=0,column=1,padx=5)
- lab2=Label(fram3,fg='blue',font=('Arial', 9))
- lab2.grid(row=0,column=0,padx=15)
- lab3a=Label(fram3,fg='red',font=('Arial', 9))
- lab3a.grid(row=1,column=0,padx=5)
- button1 = Button(fram3, text = '', command = Validation,state=DISABLED,relief=FLAT)
- button1.grid(row=1,column=1,padx=35,pady=5)
- fram3.pack()
-
- fram5=Frame(fen1)
- lab4=Label(fram5,fg='black', font=('Arial', 10))
- lab4.grid(row=0,column=0,pady=5)
- lab5=Label(fram5,fg='blue', font=('Arial', 9))
- lab5.grid(row=0,column=1,sticky=W)
- lab6=Label(fram5,fg='blue', font=('Arial', 9))
- lab6.grid(row=1,column=0)
- lab7=Label(fram5,fg='red', font=('Arial', 9))
- lab7.grid(row=1,column=1)
- lab8=Label(fram5,fg='red', font=('Arial', 10))
- lab8.grid(row=2,column=0,sticky=W)
- lab9=Label(fram5,fg='black', font=('Arial', 9))
- lab9.grid(row=3,column=0)
- fram5.pack()
-
- fen1.mainloop()
-
#Compacteur images JPEG v.2.1
# -*- coding: utf-8 -*-
from Tkinter import *
from winsound import *
from PIL import Image, ImageTk
import glob
import os
import tkFileDialog
import string
import Tix
import shutil
import tkMessageBox
global repert, dirinit, nbfich, tailaff, taux, chtaux, indsauv
taux = 85
dirinit = ''
indsauv='N'
def Exploration() :
global repert, dirinit, nbfich,tailaff, tailrepe
list1.delete(0,END)
nbfich=0
lab2.configure(text='')
lab3.configure(text='')
lab4.configure(text='')
lab5.configure(text='')
lab6.configure(text='')
lab7.configure(text='')
lab8.configure(text='')
lab9.configure(text='')
button1.config(bg='SlateGray2',text='',state=DISABLED,relief=FLAT)
repert=tkFileDialog.askdirectory(title='Choisir le répertoire à traiter',initialdir=dirinit)
dirinit=repert
repert=repert+'\\*.*'
for fichier in glob.glob(repert):
file, ext = os.path.splitext(fichier)
tailfich = os.path.getsize(fichier)
tailfiaff = tailfich/1024
chaine='%4d'%tailfiaff+' Ko ^ '+fichier
if ext=='.jpg' or ext=='.JPG' or ext=='.jpeg' or ext=='.JPEG' :
list1.insert(END,chaine)
nbfich=nbfich+1
Taille_Repert()
tailrepe = tailaff
if nbfich > 0 :
lab2.configure(text='Taille cumulée des images = '+tailaff)
lab3.configure(text='Nombre d''\'images = '+str(nbfich))
button1.config(bg='yellow',text='Valider',state=NORMAL,relief=RAISED)
list1.select_set(0)
list1.bind('<ButtonRelease>',Affiche_image1)
def Affiche_image1(e) :
if nbfich > 0 :
index = map(int,list1.curselection())[0]
fichima = string.strip(list1.get(index))
nom=''
ind=0
i=0
while i< len(fichima) :
if ind==1 :
nom=nom+fichima[i]
if fichima[i]=='^' :
ind=1
i=i+1
i=i+1
im=Image.open(nom)
im.load()
im.thumbnail((300,300),Image.ANTIALIAS)
fenaff = Toplevel()
if im.size[0] < 100 :
larim=100
else : larim=im.size[0]
if im.size[1] < 20 :
hauim=20
else : hauim=im.size[1]
fenaff.geometry(str(larim)+"x"+str(hauim))
fenaff.resizable(width=False, height=False)
fenaff.config(bg='lightgrey')
canaff = Canvas(fenaff,width=im.size[0],height=im.size[1])
canaff.pack()
nombase = os.path.basename(nom)
fenaff.title(nombase)
vignette = ImageTk.PhotoImage(im)
canaff.create_image(0,0,anchor=NW,image=vignette)
canaff.monimage = vignette
canaff.configure()
boeff.config(text="Fermer vues",bg='DarkOliveGreen3', fg='white',state=NORMAL,relief=RAISED)
def Arreter_validation() :
global ifin3,nbok
ifin3=1
lab8.configure(text='Traitement interrompu : '+str(nbok)+' images traitées.')
def Validation() :
global dirinit, repert, nbfich, ficherr, tailaff, tailrep, tailrepe,ifin3,nbok,indsauv,isav
ifin3=0
fen3=Tix.Tk()
geo1=fen1.winfo_geometry()
geox=fen1.winfo_rootx()
geoy=fen1.winfo_rooty()
fen3.geometry("400x120+"+str(geox+55)+"+"+str(geoy+190))
fen3.title(repert)
labb=Label(fen3,text='Progression du compactage', fg='blue', font=('Arial', 10))
labb.pack(side=TOP)
meter=Tix.Meter(fen3,value=0.)
meter.pack()
labf=Label(fen3,text='', fg='black', font=('Arial',9))
labf.pack(side=BOTTOM)
Bfin3=Button(fen3,text="Arrêter",bg='pink',fg='blue', command=lambda : Arreter_validation())
Bfin3.pack(side=BOTTOM,pady=10)
nberr=0
nbok = 0
ficherr=[] # liste des fichiers en erreur écriture
if indsauv=='O':
isav=1
while os.path.isdir(dirinit+'/Originaux'+str(isav)+'/') :
isav=isav+1
os.mkdir(dirinit+'/Originaux'+str(isav)+'/')
if repert <> '' and nbfich>0 :
lab4.configure(text='Traitement en cours.......Patience, merci.')
fram5.update_idletasks()
i=0
for fichier in glob.glob(repert):
file, ext = os.path.splitext(fichier)
if ext=='.jpg' or ext=='.JPG' or ext=='.jpeg' or ext=='.JPEG' :
if ifin3==1 :
break
i=i+1
meter.config(value=float(i)/nbfich)
meter.update()
labf.configure(text=file)
im=Image.open(fichier)
chem,fich=os.path.split(fichier)
if indsauv=='O' :
shutil.copy(fichier,chem+'/Originaux'+str(isav)+'/'+fich)
try :
im.save(file+'.jpg',quality=taux)
nbok = nbok+1
except IOError :
nberr = nberr+1
ficherr.append(file)
button1.config(text="",bg='SlateGray2',state=DISABLED,relief=FLAT)
lab4.configure(text='Résultat du traitement :')
Taille_Repert()
if nbok==0 :
lab5.configure(text=' Aucune image traitée')
elif tailaff == tailrepe :
lab5.configure(text=' Ce dossier est déjà compacté')
else :
lab5.configure(text=str(nbok)+' image(s) analysée(s)')
lab6.configure(text='Nouvelle taille cumulée des images = '+tailaff)
if indsauv=='O':
lab9.configure(text='Originaux dans : '+dirinit+'/Originaux'+str(isav))
nbfich=0
if nberr>0 :
Beep(800,100)
lab7.configure(text=str(nberr)+' erreur(s)')
Trt_Erreur(nberr,ficherr)
repert=''
list1.delete(0,END)
fen3.destroy()
def Taille_Repert() :
global repert, tailaff, tailrep
tailrep=0
for fichier in glob.glob(repert) :
file, ext = os.path.splitext(fichier)
tailfich = os.path.getsize(fichier)
if ext=='.jpg' or ext=='.JPG' or ext=='.jpeg' or ext=='.JPEG' :
tailrep=tailrep+tailfich
tailrep1 = tailrep/1024/1024.0
tailaff = '%.2f' % tailrep1 +' Mo'
def Trt_Erreur(nberr,ficherr) :
fen2=Toplevel()
geo1=fen1.winfo_geometry()
geox=fen1.winfo_rootx()
geoy=fen1.winfo_rooty()
fen2.geometry("400x350+"+str(geox+55)+"+"+str(geoy+170))
fen2.title("CompactImages : Erreurs de traitement")
labf2=Label(fen2,text=str(nberr)+' images ne pouvant être traitées \n (Images peut-être en lecture seule)', fg='blue', font=('Arial', 9))
labf2.pack(side=TOP,pady=10)
fram4=Frame(fen2,borderwidth=0)
scrollf2 =Scrollbar(fram4,orient=VERTICAL)
listf2 = Listbox(fram4,bg='yellow',width=60,height=15,selectmode='single', yscrollcommand=scrollf2.set)
scrollf2.config(command = listf2.yview)
scrollf2.pack(side=LEFT,fill=Y)
listf2.pack(side=LEFT)
fram4.pack()
bouf2=Button(fen2,text="Fermer",bg='brown',fg='white', command=fen2.destroy)
bouf2.pack(side=BOTTOM,pady=10)
for x in ficherr :
listf2.insert(END,x)
fen2.grab_set()
fen2.wait_window()
def Affich_Infos() :
feninf = Toplevel()
feninf.config(bg='SlateGray4')
geo1=fen1.winfo_geometry()
geox=fen1.winfo_rootx()
geoy=fen1.winfo_rooty()
feninf.geometry("350x390+"+str(geox+75)+"+"+str(geoy+160))
feninf.title("À propos de CompactImages")
labinf=Label(feninf,bg='SlateGray4', fg='white',width=50,font=('Arial', 9),
text= "\nCompactImages v.2.1\n\n"
"Programme écrit en Python / Tkinter \n"
"et distribué sous licence GNU GPL.\n\n"
"© 2008 Yves Le Chevalier\n\n"
"Ce programme comprime toutes les images JPG (jpeg)\n"
"d'un répertoire donné, sans modifier leurs dimensions.\n"
"Il ne comprime pas les images protégées (en lecture seule).\n\n"
"Le niveau de compression est réglé à 85 par défaut, mais\n"
"peut être modifié sur toute la plage de compression Jpeg.\n\n"
"La sauvegarde est facultative et provoque la création d'un\n"
"sous-répertoire '''Originaux1'''. Si vous exécutez un second\n"
"traitement sur le même répertoire, la sauvegarde se fait alors\n"
"dans un sous-répertoire '''Originaux2''', puis la troisième fois\n"
" dans un sous-répertoire '''Originaux3''' et ainsi de suite. \n"
"Toutes les images analysées sont alors sauvegardées. \n"
"Attention : Par défaut, la sauvegarde n'est pas activée.")
labinf.pack(pady=5)
bouf3=Button(feninf, text="Fermer", command=feninf.destroy,bg="orange", fg='brown')
bouf3.pack(side=BOTTOM,pady=10)
feninf.grab_set()
feninf.wait_window()
def Modif_Taux() :
global can2, fentau, choixtau
fentau = Toplevel()
fentau.config(bg='SlateGray3')
geo1=fen1.winfo_geometry()
geox=fen1.winfo_rootx()
geoy=fen1.winfo_rooty()
fentau.geometry("350x330+"+str(geox+75)+"+"+str(geoy+170))
fentau.title("Taux de compression")
labtau=Label(fentau,bg='SlateGray3', fg='black',width=50,font=('Arial', 9),
text= "\nModification du taux de compression\n\n"
"ATTENTION : le niveau de compression Jpeg varie de 1 à 100 \n"
"1 = compression maximale ; 100= aucune compression.\n\n"
"La compression optimale se situe vers 85 (valeur par défaut).\n\n"
"Vous pouvez changer le niveau de compression, sachant que\n"
"si vous comprimez trop, vous perdez de la qualité et si vous ne \n"
"comprimez pas assez, vous ne gagnez pas en volume.\n"
"Il vaut mieux rester dans une plage de 75 à 90\n")
labtau.pack(pady=0)
can2 = Canvas(fentau, width=200, height=50, bg='SlateGray3')
can2.pack(pady=20)
curs= Scale(can2, from_=1, to=100, length=150, sliderlength=7,
resolution=1, showvalue=1, orient=HORIZONTAL,
label="Réglage du niveau :",command=choix_taux,font=('Arial', 8),bg='SlateGray3',fg='blue')
curs.set (85)
curs.pack(side=TOP)
boutau=Button(can2, text="OK", command=set_taux,font=('Arial', 8),bg="orange", fg='brown')
boutau.pack(side=BOTTOM)
fentau.grab_set()
fentau.wait_window()
def choix_taux(valcurs) :
global chtaux
chtaux=float(valcurs)
if chtaux < 75 or chtaux > 90 :
fentau.config(bg='red')
else : fentau.config(bg='green')
def set_taux() :
global chtaux, taux
taux=int(chtaux)
if taux < 75 or taux > 90 :
boutau.config(text ="Niveau "+'% d' %taux,bg='red',fg='black')
Beep(800,100)
else : boutau.config(text ="Niveau "+'% d' %taux,bg='green',fg='black')
if taux <> 85 :
lab3a.configure(text='ATTENTION : Niveau compression à '+str(taux))
else : lab3a.configure(text='')
can2.destroy()
fentau.destroy()
def quitter_prog() :
global fenqui
fenqui=Toplevel()
fenqui.config(bg='yellow',bd=3,relief='groove')
geo1=fen1.winfo_geometry()
geox=fen1.winfo_rootx()
geoy=fen1.winfo_rooty()
fenqui.geometry("200x60+"+str(geox+160)+"+"+str(geoy+350))
fenqui.resizable(width=False, height=False)
fenqui.overrideredirect(1)
labqui=Label(fenqui,bg='yellow',fg='black',font=('Arial', 11),text="Quitter CompactImage ?")
labqui.place(x=17,y=1)
repon=StringVar()
bououi=Button(fenqui,text="Oui", bg='pink', fg='black',command=confir_quitter)
bounon=Button(fenqui,text="Non", bg='pink', fg='black',command=continu_prog)
bououi.place(x=40,y=25)
bounon.place(x=120,y=25)
fenqui.grab_set()
def confir_quitter() :
fen1.destroy()
def continu_prog() :
global fenqui
fenqui.destroy()
def sauvegarde() :
global indsauv
if indsauv =='N' :
indsauv='O'
labsau1.configure(text='Avec sauvegarde',fg='black')
bosav.config(text='Sans',bg='SeaGreen4', fg='white')
else :
indsauv='N'
labsau1.configure(text='Sans sauvegarde',fg='grey50')
bosav.config(text='Avec',bg='firebrick4', fg='white')
def effacer_vues() :
for widget in fen1.winfo_children():
if isinstance(widget,Toplevel):
widget.destroy()
boeff.config(text="",bg='SlateGray2',state=DISABLED,relief=FLAT)
def close_window() :
if tkMessageBox.askokcancel :
quitter_prog()
# main
fen1 = Tk(className=" CompactImages v_2,1")
fen1.protocol("WM_DELETE_WINDOW", close_window)
fen1.tk_setPalette(background = 'SlateGray2')
fen1.geometry("500x800+550+100")
fen1.resizable(width=False, height=False)
can1 = Canvas(fen1, width=20, height=20, bg='lightgrey')
signat=PhotoImage(file='YLC.gif')
sign=can1.create_image(12,12, image=signat)
can1.pack(side=BOTTOM,anchor=E)
fram1=Frame(fen1,borderwidth=0)
button2 = Button(fram1, text = 'Répertoire',bg='snow', command = Exploration)
button2.grid(row=0,column=0,pady=20)
boutau=Button(fram1,text=" Niveau "+'% d' %taux, bg='green', fg='black',command=Modif_Taux)
boutau.grid(row=0,column=1,padx=30)
bouinf=Button(fram1,text="Information", bg="seagreen4", fg='yellow',command=Affich_Infos)
bouinf.grid(row=0,column=2,padx=30)
bouf1=Button(fram1,text="Quitter", command=quitter_prog,bg='salmon', fg='black')
bouf1.grid(row=0,column=3)
labsau1=Label(fram1,text='Sans sauvegarde', fg='grey50', font=('Arial',11))
labsau1.grid(row=1,column=0)
bosav=Button(fram1,text="Avec", command=sauvegarde,bg='firebrick4', fg='white')
bosav.grid(row=1,column=1)
boeff=Button(fram1,text="",command=effacer_vues,state=DISABLED,relief=FLAT)
boeff.grid(row=1,column=3)
fram1.pack(side=TOP)
fram2=Frame(fen1,borderwidth=0)
labbid1=Label(fram2,text='')
labbid1.pack(side=TOP)
lab1=Label(fram2,text='Liste des images (Jpg ou Jpeg) à comprimer', fg='blue', font=('Arial', 12))
lab1.pack()
lab1b=Label(fram2,text='(Cliquer sur une ligne pour voir l''image)', fg='black', font=('Arial', 9))
lab1b.pack()
scrolly =Scrollbar(fram2,orient=VERTICAL)
list1 = Listbox(fram2,bg="SlateGray1",width=70,height=31,selectmode='single', yscrollcommand=scrolly.set)
scrolly.config(command = list1.yview)
scrolly.pack(side=LEFT,fill=Y)
list1.pack()
fram2.pack()
fram3=Frame(fen1)
lab3=Label(fram3,fg='blue',font=('Arial', 9))
lab3.grid(row=0,column=1,padx=5)
lab2=Label(fram3,fg='blue',font=('Arial', 9))
lab2.grid(row=0,column=0,padx=15)
lab3a=Label(fram3,fg='red',font=('Arial', 9))
lab3a.grid(row=1,column=0,padx=5)
button1 = Button(fram3, text = '', command = Validation,state=DISABLED,relief=FLAT)
button1.grid(row=1,column=1,padx=35,pady=5)
fram3.pack()
fram5=Frame(fen1)
lab4=Label(fram5,fg='black', font=('Arial', 10))
lab4.grid(row=0,column=0,pady=5)
lab5=Label(fram5,fg='blue', font=('Arial', 9))
lab5.grid(row=0,column=1,sticky=W)
lab6=Label(fram5,fg='blue', font=('Arial', 9))
lab6.grid(row=1,column=0)
lab7=Label(fram5,fg='red', font=('Arial', 9))
lab7.grid(row=1,column=1)
lab8=Label(fram5,fg='red', font=('Arial', 10))
lab8.grid(row=2,column=0,sticky=W)
lab9=Label(fram5,fg='black', font=('Arial', 9))
lab9.grid(row=3,column=0)
fram5.pack()
fen1.mainloop()
Conclusion
C'est à vous de la donner ; moi, je trouve ça très pratique.
Historique
- 11 décembre 2007 19:18:01 :
- En travaillant sur des répertoire de plusieurs centaines de photos, je trouvais le temps long et ne savais pas où le traitement en était rendu.
J'ai donc ajouté une barre de progression (avec TIX).
Attention à la compile sous windows avec py2exe, il manque les DLL Tix dans python 2.5 à récupérer à cette adresse: http://python.developpez.com/faq/?page=TkinterPrerequis
(Merci à Guillaume Duriaud)
Il faut aussi modifier le setup.py : voir à cette adresse:
http://www.py2exe.org/index.cgi/TixSetup
- 15 novembre 2008 10:44:14 :
- Nouvelle version améliorée
- 21 novembre 2008 16:49:14 :
- J'avais oublié de joindre l'image YLC.gif à mon Zip.
C'est fait.
- 28 novembre 2008 09:54:23 :
- Juste une petite adaptation des dimensions des fenêtres d'affichage des fignettes aux images affichées.
- 28 novembre 2008 09:58:22 :
- Amélioration de la dimension de la fenêtre des vignettes aux images affichées. (fonction Affiche_image1)
Sources du même auteur
Sources de la même categorie
Commentaires et avis
Discussions en rapport avec ce code source dans le forum
wxpython : afficher et effacer des images [ par steede ]
Bonjour,J'ai besoin dans mon application d'affiicher des images et de les remplacer par d'autres en fonction des clics de la souris.Je sais les affich
erreurs video [ par ktamine ]
bonjour étudiante en arts plastiques, je travaille autour de l’esthétique de l’erreur et des données corrompues (d’image
Compression de fichier :Winzip et 7zip [ par HCD ]
Bonjour à tousCe qui suit s'adresse aux administrateurs du site.Lorsque l'on ajoute une nouvelle source sur le site, le fichier compressé doir comport
affichage des images sur python [ par amina22 ]
salut,je sais qu'on peut afficher les images .gif avec python mais je veux savoir si on peut afficher les images(jpeg,jpg,..) et les vidéos si oui et
Cacher une image [ par akkuciha ]
Bonjour à tous, Le but de mon application est de trouver l'image "Question" parmis les images "réponses" possibles.J'ai une zone d'image faite avec gl
Canvas, scrollbar et images [ par linkid ]
Bonjour,Je suis en train de faire une petite application en python et j'ai un petit problème avec les Canvas... (j'utilise Tkinter pour l'interface)(1
Problème avec draw.text du module PIL [ par MasterID ]
probleme avec pil [ par Logindejapris ]
Bonjour, Je voudrais récupérer la couleur d'un pixel sur mon bureau. A priori il n'y as pas d'autre possibilité que de faire un snapshoot et d'analy
|
Derniers Blogs
[MIX10] KEYNOTE DEUXIèME JOURNéE - INTERNET EXPLORER 9, HTML5, VISUAL STUDIO 2010, ODATA[MIX10] KEYNOTE DEUXIèME JOURNéE - INTERNET EXPLORER 9, HTML5, VISUAL STUDIO 2010, ODATA par cyril
Le deuxième keynote du mix fut très riche en contenu. Internet Explorer 9 Juste un après le lancement de Internet Explorer 8, Microsoft a dévoilé les nouveautés de Internet Explorer 9. Désormais, IE supportera HTML5, SVG et CSS3. L'élément ...
Cliquez pour lire la suite de l'article par cyril CERTIFICATIONS BETA .NET 4CERTIFICATIONS BETA .NET 4 par KooKiz
Les inscriptions pour les certifications beta .NET 4 ont commencé. L'inscription est offerte pour les examens suivants : - 71-511, TS: Windows Applications Development with Microsoft .NET Framework 4 - 71-515, TS: Web Applications Development with...
Cliquez pour lire la suite de l'article par KooKiz [MIX 2010] - MICROSOFT TRANSLATOR TECHNOLOGY PREVIEW V2[MIX 2010] - MICROSOFT TRANSLATOR TECHNOLOGY PREVIEW V2 par redo
J'imagine que la plupart d'entre vous connaissent bien et utilisent le service de traduction de Google, mais connaissez-vous celui de Microsoft . Microsoft Translator ? Effectivement, Microsoft nous annoncé le lancement version 2 de la Technologie Preview...
Cliquez pour lire la suite de l'article par redo LANCEMENT EN PREVIEW DE CYCLONE LORS DES TECHDAYS 2010!LANCEMENT EN PREVIEW DE CYCLONE LORS DES TECHDAYS 2010! par MPOWARE
Toutes les vidéos de ce lancement sont en ligne!
Partie I - Intro
http://www.youtube.com/watch?v=LkQzTQ8T6CA
Partie II - Démo 1
http://www.youtube.com/watch?v=drAhYQ7lqvo
Partie III - Démo 2
http://www.youtube.com/watch?v=c8KM_1Gqybc...
Cliquez pour lire la suite de l'article par MPOWARE [WP7] JE NE VEUX PAS D'UN NOUVEL IPHONE[WP7] JE NE VEUX PAS D'UN NOUVEL IPHONE par FREMYCOMPANY
Je pense qu'ils ont besoin d'une piqure de rappel chez Microsoft : c'est bien gentil d'avoir une interface jolie, mais si c'est pour avoir un truc qui ne convainct pas dedans, c'est peine perdue.
---->
Système ouvert ----> Fermé ?
P...
Cliquez pour lire la suite de l'article par FREMYCOMPANY
Logiciels
Xilisoft Convertisseur Vidéo Ultimate (5.1.39.0305)XILISOFT CONVERTISSEUR VIDéO ULTIMATE (5.1.39.0305)Xilisoft Convertisseur Vidéo Ultimate est un outil puissant de conversion vidéo, facile à utilise... Cliquez pour télécharger Xilisoft Convertisseur Vidéo Ultimate Xilisoft DVD Ripper Ultimate (5.0.64.0304)XILISOFT DVD RIPPER ULTIMATE (5.0.64.0304)Xilisoft DVD Ripper Ultimate est un logiciel excellent pour copier et convertir DVD vers presque ... Cliquez pour télécharger Xilisoft DVD Ripper Ultimate Rigs of Rods (63.3)RIGS OF RODS (63.3)c'est un jeu de multi-simulation camions,autobus voitures, avions, bateaux, hélicoptère avec défo... Cliquez pour télécharger Rigs of Rods Konvertor (4.00)KONVERTOR (4.00)Le logiciel est un gestionnaire multimedia affichant, jouant et convertissant plus de 2000 format... Cliquez pour télécharger Konvertor
|