Découpage de bd

Contenu du snippet

Bonjour à tous,
Ce code permet de découper une page de BD en sous-vignettes et d'enregistrer le résultat dans l'ordre de lecture. L'intéret est bien évidemment de pouvoir ensuite lire la BD confortablement soit sur un ordinateur classique, soit sur un PDA.
On choisi donc un répertoire contenant les pages des BD, puis un répertoire cible. On peut également modifier certains paramètre de découpes qui ont des valeur par défault "optimale" (suite aux essais réalisés). Le tout via une jolie interface graphique TKinter.
Remarque :
-Pour modifier les répertoires par défaults, il faut modifier les lignes 344 et 349 ;-)
-Ce code vous semble illisible et mal écrit, c'est normal, c'est un de mes premiers scripts en Python, mais il a le mérite d'être fonctionnel. Il faut noter que la quantité de code de ce type reste faible sur la toile...

Source / Exemple :


import Image
import ImageTk
import os
import Tkinter
import tkFileDialog

def coupe(image_coup,x0,y0,x1,y1):
	"Decoupe une image"
	decoupe=image_coup.crop((x0,y0,x1,y1))
	deltax=x1-x0
	deltay=y1-y0
	image_coup_out=Image.new(image_coup.mode,(deltax,deltay))
	image_coup_out.paste(decoupe,(0,0,deltax,deltay))
	return image_coup_out

def mini(img):
	"ajoute une miniature a une image"
	image_thun=Image.open(repertoire_in+'/'+nom_image_in,'r')
	image_thun.thumbnail((int(image_thun.size[0]*img.size[1]/image_thun.size[1]),img.size[1]))
	img_out=Image.new(img.mode,(img.size[0]+int(image_thun.size[0]*img.size[1]/image_thun.size[1]),img.size[1]))
	img_out.paste(image_thun,(0,0,image_thun.size[0],image_thun.size[1]))
	img_out.paste(img,(int(image_thun.size[0]*img.size[1]/image_thun.size[1]),0,img.size[0]+int(image_thun.size[0]*img.size[1]/image_thun.size[1]),img.size[1]))
	return img_out

def bordure(image_bord,factor):
	"renvoie une image avec les bordures supprimees"
	size=image_bord.size
	#bordure superieure
	xx0,xx1,xx2,xx3,xx4,y0=int(size[0]/5),int(2*size[0]/5),int(3*size[0]/5),int(4*size[0]/5),int(size[0]/2),0
	while y0<size[1]-1:
		coord_1=(xx0,y0)
		coord_2=(xx1,y0)
		coord_3=(xx2,y0)
		coord_4=(xx3,y0)
		coord_5=(xx4,y0)
		if image_bord.getpixel(coord_1)[0]<=factor[0]:
			if image_bord.getpixel(coord_1)[1]<=factor[1]:
				if image_bord.getpixel(coord_1)[2]<=factor[2]:
					break
		if image_bord.getpixel(coord_2)[0]<=factor[0]:
			if image_bord.getpixel(coord_2)[1]<=factor[1]:
				if image_bord.getpixel(coord_2)[2]<=factor[2]:
					break
		if image_bord.getpixel(coord_3)[0]<=factor[0]:
			if image_bord.getpixel(coord_3)[1]<=factor[1]:
				if image_bord.getpixel(coord_3)[2]<=factor[2]:
					break
		if image_bord.getpixel(coord_4)[0]<=factor[0]:
			if image_bord.getpixel(coord_4)[1]<=factor[1]:
				if image_bord.getpixel(coord_4)[2]<=factor[2]:
					break
		if image_bord.getpixel(coord_5)[0]<=factor[0]:
			if image_bord.getpixel(coord_5)[1]<=factor[1]:
				if image_bord.getpixel(coord_5)[2]<=factor[2]:
					break
		y0=y0+1
	#bordure inferieur
	y1=size[1]-1
	while y1>=0:
		coord_1=(xx0,y1)
		coord_2=(xx1,y1)
		coord_3=(xx2,y1)
		coord_4=(xx3,y1)
		coord_5=(xx4,y1)
		if image_bord.getpixel(coord_1)[0]<=factor[0]:
			if image_bord.getpixel(coord_1)[1]<=factor[1]:
				if image_bord.getpixel(coord_1)[2]<=factor[2]:
					break
		if image_bord.getpixel(coord_2)[0]<=factor[0]:
			if image_bord.getpixel(coord_2)[1]<=factor[1]:
				if image_bord.getpixel(coord_2)[2]<=factor[2]:
					break
		if image_bord.getpixel(coord_3)[0]<=factor[0]:
			if image_bord.getpixel(coord_3)[1]<=factor[1]:
				if image_bord.getpixel(coord_3)[2]<=factor[2]:
					break
		if image_bord.getpixel(coord_4)[0]<=factor[0]:
			if image_bord.getpixel(coord_4)[1]<=factor[1]:
				if image_bord.getpixel(coord_4)[2]<=factor[2]:
					break
		if image_bord.getpixel(coord_5)[0]<=factor[0]:
			if image_bord.getpixel(coord_5)[1]<=factor[1]:
				if image_bord.getpixel(coord_5)[2]<=factor[2]:
					break
		y1=y1-1
	#bordure de gauche
	yy0,yy1,yy2,yy3,yy4,x0=int(size[1]/5),int(2*size[1]/5),int(3*size[1]/5),int(4*size[1]/5),int(size[1]/2),0
	while x0<size[0]-1:
		coord_1=(x0,yy0)
		coord_2=(x0,yy1)
		coord_3=(x0,yy2)
		coord_4=(x0,yy3)
		coord_5=(x0,yy4)
		if image_bord.getpixel(coord_1)[0]<=factor[0]:
			if image_bord.getpixel(coord_1)[1]<=factor[1]:
				if image_bord.getpixel(coord_1)[2]<=factor[2]:
					break
		if image_bord.getpixel(coord_2)[0]<=factor[0]:
			if image_bord.getpixel(coord_2)[1]<=factor[1]:
				if image_bord.getpixel(coord_2)[2]<=factor[2]:
					break
		if image_bord.getpixel(coord_3)[0]<=factor[0]:
			if image_bord.getpixel(coord_3)[1]<=factor[1]:
				if image_bord.getpixel(coord_3)[2]<=factor[2]:
					break
		if image_bord.getpixel(coord_4)[0]<=factor[0]:
			if image_bord.getpixel(coord_4)[1]<=factor[1]:
				if image_bord.getpixel(coord_4)[2]<=factor[2]:
					break
		if image_bord.getpixel(coord_5)[0]<=factor[0]:
			if image_bord.getpixel(coord_5)[1]<=factor[1]:
				if image_bord.getpixel(coord_5)[2]<=factor[2]:
					break
		x0=x0+1
	#bordure de droite
	x1=size[0]-1
	while x1>=0:
		coord_1=(x1,yy0)
		coord_2=(x1,yy1)
		coord_3=(x1,yy2)
		coord_4=(x1,yy3)
		coord_5=(x1,yy4)
		if image_bord.getpixel(coord_1)[0]<=factor[0]:
			if image_bord.getpixel(coord_1)[1]<=factor[1]:
				if image_bord.getpixel(coord_1)[2]<=factor[2]:
					break
		if image_bord.getpixel(coord_2)[0]<=factor[0]:
			if image_bord.getpixel(coord_2)[1]<=factor[1]:
				if image_bord.getpixel(coord_2)[2]<=factor[2]:
					break
		if image_bord.getpixel(coord_3)[0]<=factor[0]:
			if image_bord.getpixel(coord_3)[1]<=factor[1]:
				if image_bord.getpixel(coord_3)[2]<=factor[2]:
					break
		if image_bord.getpixel(coord_4)[0]<=factor[0]:
			if image_bord.getpixel(coord_4)[1]<=factor[1]:
				if image_bord.getpixel(coord_4)[2]<=factor[2]:
					break
		if image_bord.getpixel(coord_5)[0]<=factor[0]:
			if image_bord.getpixel(coord_5)[1]<=factor[1]:
				if image_bord.getpixel(coord_5)[2]<=factor[2]:
					break
		x1=x1-1
	if y0==size[1]-1:
		y0=0
	if x0==size[0]-1:
		x0=0
	if y1==-1:
		y1=size[1]
	if x1==-1:
		x1=size[0]
	if x1==x0:
		x1=size[0]-1
	if y1==y0:
		y1=size[1]-1
	text.insert('end','taille d origine :'+str(size)+'taille recadree :'+str(x1-x0)+','+str(y1-y0)+'\n...')
	image_out_bord=coupe(image_bord,x0,y0,x1,y1)
	return image_out_bord

def vertical(image_vert,factor,controle,facteur_forme):
	"recherche la premiere ligne blanche"
	size=image_vert.size
	x=[0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9]
	i=0
	for y in range(size[1]):
		if y>=int(facteur_forme*size[1]):
			if y<=int((1-facteur_forme)*size[1]):
				mkx=0
				for i in range(len(x)):
					xx=int((x[i])*int(size[0]))
					coord=(xx,y)
					if image_vert.getpixel(coord)[0]>=factor[0]:
						if image_vert.getpixel(coord)[1]>=factor[1]:
							if image_vert.getpixel(coord)[2]>=factor[2]:
								mkx=mkx+1
					if mkx>=controle:
						return y

def horizontal(image_hor,factor,controle,facteur_forme):
	"recherche la premiere colone blanche"
	size=image_hor.size
	y=[0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9]
	i=0
	for x in range(size[0]):
		if x>=int(facteur_forme*size[0]):
			if x<=int((1-facteur_forme)*size[0]):
				mky=0
				for i in range(len(y)):
					yy=int((y[i])*int(size[1]))
					coord=(x,yy)
					if image_hor.getpixel(coord)[0]>=factor[0]:
						if image_hor.getpixel(coord)[1]>=factor[1]:
							if image_hor.getpixel(coord)[2]>=factor[2]:
								mky=mky+1
					if mky>=controle:
						return x

def division_vert(image_div_vert,coord):
	"division d'une image en deux horizontallement"
	try:
		x0,y0,x1,y1=0,0,int(image_div_vert.size[0]),coord
		image_out_1=coupe(image_div_vert,x0,y0,x1,y1)
		x0,y0,x1,y1=0,coord,int(image_div_vert.size[0]),int(image_div_vert.size[1])
		image_out_2=coupe(image_div_vert,x0,y0,x1,y1)
		return image_out_1,image_out_2
	except:
		nop=0
		text.insert('end','L image n est pas plus divisible selon y')
#		print 'L image',nom_image_in,'n est pas divisible selon y'

def division_hor(image_div_hor,coord):
	"division d'une image en deux verticalement"
	try:
		x0,y0,x1,y1=0,0,coord,int(image_div_hor.size[1])
		image_out_1=coupe(image_div_hor,x0,y0,x1,y1)
		x0,y0,x1,y1=coord,0,int(image_div_hor.size[0]),int(image_div_hor.size[1])
		image_out_2=coupe(image_div_hor,x0,y0,x1,y1)
		return image_out_1,image_out_2
	except:
		nop=0
		text.insert('end','L image n est pas plus divisible selon x')
#		print 'L image',nom_image_in,'n est pas divisible selon x'

def vign_vert(image_vign_vert,facteur,facteur_forme,facteur_bord,controle_x,controle_y):
	"division des images en lignes"
	stack=0
	temp=0
	vignettes_vert={}
#	vignettes_vert['tampon'+str(stack)]=bordure(image_vign_vert,facteur)
	vignettes_vert['tampon'+str(stack)]=image_vign_vert
	#Decoupage des vignettes :
	while 1:
		#1. Recherche d'une bande
		coord=vertical(vignettes_vert['tampon'+str(temp)],facteur,controle_y,facteur_forme)
		if coord!=vignettes_vert['tampon'+str(temp)].size[1]-1:
			if coord>=image_vign_vert.size[1]*facteur_forme:
				img_1,img_2=division_vert(vignettes_vert['tampon'+str(temp)],coord)
				stack=stack+1
				temp=temp+1
				#vignettes_vert['image'+str(stack)]=bordure(img_1,facteur_bord)
				#vignettes_vert['tampon'+str(temp)]=bordure(img_2,facteur_bord)
				vignettes_vert['image'+str(stack)]=img_1
				vignettes_vert['tampon'+str(temp)]=img_2
			else :
				#print 'L image','image'+str(stack),'n est pas divisible selon y'
				break
		else :
			#print 'L image','image'+str(stack),'n est pas divisible selon y'
			break
	#vignettes_vert['image'+str(stack+1)]=bordure(vignettes_vert['tampon'+str(temp)],facteur)
	vignettes_vert['image'+str(stack+1)]=vignettes_vert['tampon'+str(temp)]
	mk=1
	vign_final={}
	for j_vert in range(len(vignettes_vert)):
		try:
			vign_final=vign_hor(vignettes_vert['image'+str(mk)],facteur,facteur_forme,facteur_bord,controle_x,controle_y)
			mk2=1
			for k_vert in range(len(vign_final)):
				try:
					if Q_boite.get()==1:
						img_final=mini(vign_final['image'+str(mk2)])
						img_final.save(repertoire_out+'th_'+nom_image_in[0:-4]+str(j_vert)+str(k_vert)+'.jpg',"JPEG")
					else:
						vign_final['image'+str(mk2)].save(repertoire_out+nom_image_in[0:-4]+str(j_vert)+str(k_vert)+'.jpg',"JPEG")
					mk2=mk2+1
				except:
					break
			mk=mk+1
		except:
			break
	return vignettes_vert

def vign_hor(image_vign_hor,facteur,facteur_forme,facteur_bord,controle_x,controle_y):
	"division des images en colones"
	stack_hor=0
	temp_hor=0
	vignettes_hor={}
	#vignettes_hor['tampon'+str(stack_hor)]=bordure(image_vign_hor,facteur)
	vignettes_hor['tampon'+str(stack_hor)]=image_vign_hor
	while 1:
		coord=horizontal(vignettes_hor['tampon'+str(temp_hor)],facteur,controle_x,facteur_forme)
		if coord!=vignettes_hor['tampon'+str(temp_hor)].size[0]-1:
			if coord>=image_vign_hor.size[0]*facteur_forme:
				img_1,img_2=division_hor(vignettes_hor['tampon'+str(temp_hor)],coord)
				stack_hor=stack_hor+1
				temp_hor=temp_hor+1
				#vignettes_hor['image'+str(stack_hor)]=bordure(img_1,facteur_bord)
				#vignettes_hor['tampon'+str(temp_hor)]=bordure(img_2,facteur_bord)
				vignettes_hor['image'+str(stack_hor)]=img_1
				vignettes_hor['tampon'+str(temp_hor)]=img_2
			else :
				#print 'L image n est pas divisible selon x'
				break
		else :
			#print 'L image n est pas divisible selon x'
			break
	#vignettes_hor['image'+str(stack_hor+1)]=bordure(vignettes_hor['tampon'+str(temp_hor)],facteur)
	vignettes_hor['image'+str(stack_hor+1)]=vignettes_hor['tampon'+str(temp_hor)]
	return vignettes_hor
def decoupage():
	global repertoire_in
	global repertoire_out
	try:
		repertoire_in=path_in
		repertoire_out=path_out
		global facteur
		facteur=(int(cut.get()),int(cut.get()),int(cut.get()))
		global facteur_bord
		facteur_bord=(int(border.get()),int(border.get()),int(border.get()))
		global facteur_forme
		facteur_forme=float(form.get())
		global controle_y
		controle_y=int(y_control.get())
		global controle_x
		controle_x=int(x_control.get())
		path=os.listdir(repertoire_in)
		#Recherche des images dans le repertoire
		for i in range(len(path)):
			if path[i].count('.jpg')==1:
				fen1.update()
				text.delete('3.0','end')
				global nom_image_in
				nom_image_in=path[i]
				global nom_image_out
				nom_image_out=nom_image_in[0:-4]+str(i)+'_py.jpg'
				image_in=Image.open(repertoire_in+'/'+nom_image_in,'r')
				image_in_thun=Image.open(repertoire_in+'/'+nom_image_in,'r')
				image_in_thun.thumbnail((200,300))
				photo=ImageTk.PhotoImage(image_in_thun)
				espace_image.create_image(100,150,image=photo)
				text.insert('end','\n...Impossible d afficher la miniature\n...')
				text.insert('end','\n...'+str(i)+' image(s) traitee(s)'+'\n...Image '+str(nom_image_in)+' en cours de traitement \n...')
				#Decoupage de la bordure superieure
				image_out=bordure(image_in,facteur_bord)
				vignette={}
				vignette=vign_vert(image_out,facteur,facteur_forme,facteur_bord,controle_x,controle_y)
		text.delete('3.0','end')
		text.insert('end','\n...Traitement termine avec succes	\n...')
	except:
		text.insert('end','Choisissez des repertoires d entree et de sortie valides\n...')

def entree():
	global path_in
	path_in=tkFileDialog.askdirectory(parent=fen1,initialdir="D:\\BD\\",title='Choisissez un repertoire d entree')
	text.insert('end','Repertoire d entree : '+str(path_in)+'\n...')

def sortie():
	global path_out
	path_out=tkFileDialog.askdirectory(parent=fen1,initialdir="D:\\BD\\test\\",title='Choisissez un repertoire de sortie')+'/'
	text.insert('end','Repertoire de sortie : '+str(path_out)+'\n...')

Image.init()
#Programme principal
fen1=Tkinter.Tk()
#affichage de la fenetre en attente d'interaction avec l'utilisateur
#Initialisation des widgets de la premiere colone (texte)
#Initialisation des widgets de la deuxieme colone (zone de frappe utilisateur)
#Initialisation des widgets de la Troisieme colone (boutons)
b1=Tkinter.Button(fen1,text='Effectuer le traitement',command=decoupage)
b2=Tkinter.Button(fen1,text='Choisir un repertoire d entree',command=entree)
b3=Tkinter.Button(fen1,text='Choisir un repertoire de sortie',command=sortie)
Q_boite=Tkinter.IntVar()
boite=Tkinter.Checkbutton(fen1,text='miniatures ?', variable=Q_boite)
#Mise en page avec la fonction grid
form=Tkinter.Scale(fen1,from_=0,to=1,resolution=0.01,label='Facteur de forme',orient='horizontal')
form.set(0.12)
border=Tkinter.Scale(fen1,from_=0,to=254,resolution=1,label='Facteur de bordure',orient='horizontal')
border.set(160)
cut=Tkinter.Scale(fen1,from_=0,to=254,resolution=1,label='Facteur de decoupe',orient='horizontal')
cut.set(220)
x_control=Tkinter.Scale(fen1,from_=1,to=9,resolution=1,label='Controle selon x',orient='horizontal')
x_control.set(7)
y_control=Tkinter.Scale(fen1,from_=1,to=9,resolution=1,label='Controle selon y',orient='horizontal')
y_control.set(6)
form.grid(row=2,column=0)
border.grid(row=3,column=0)
cut.grid(row=4,column=0)
x_control.grid(row=5,column=0)
y_control.grid(row=6,column=0)
b1.grid(row=8,column=0)
b2.grid(row=0,column=0)
b3.grid(row=1,column=0)
boite.grid(row=7,column=0)
#Initialisation de la zone de communication avec l'utilisateur
text=Tkinter.Text(fen1)
text.insert('0.0','Bonjour et bienvenu\nPour tout renseignement : http://gdaveau.free.fr\n...')
text.grid(row=0,rowspan=8,column=2)
espace_image=Tkinter.Canvas(fen1, width =200,height=300, bg ='black')
espace_image.grid(row=0 ,rowspan=8, column=3)
#Boucle sans fin
fen1.mainloop()

Conclusion :


Pour avoir le fichier executable compilé pour windows xp, ou pour me faire plaisir, rendez vous sur http://gdaveau.free.fr

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.