#1 Le 06/10/2013, à 19:15
- masterbalby
Découpage automatique bande dessinée
Bonsoir à tous,
je viens de m'acheter la nouvelle nexus 7 et j'aimerais bien pouvoir mettre dessus quelques bds pour les lire dans les transports.
Je trouve que le format pdf n'est pas top pour les bds car il obliger à faire défiler chaque page pour pouvoir lire chaque vignette.
Ce que je voudrais c'est utiliser des bds au format cbr ou cbz.
Il s'agit de fichiers compressés au format rar ou zip contenant chaque page de la bd en jpg.
Mais le problème est le même que les pdf : il faut faire défiler chaque page pour pouvoir lire chaque vignette.
La solution serait de découper chaque vignette (ou case) et de les nommer dans l'ordre de la lecture 1.jpg , 2.jpg , etc...
De cette façon la lecture se ferait de vignette en vignette.
Maitenant pour faire le traitement de la bd quel logiciel utiliser.
Je pourrais utiliser gimp et faire les découpes des vignettes à la main mais là je ne suis pas prêt d'avoir fini.
Je voulais donc savoir si quelqu'un connaissait un logiciel ou un script permettant d'automatiser la tâche.
Voila un exemple de page à traiter :
Par avance je vous remercie pour votre aide
Hors ligne
#2 Le 06/10/2013, à 22:18
- Zakhar
Re : Découpage automatique bande dessinée
Question intéressante !
Une petite recherche avec duckduckgo m'a donné ça :
http://pdfjpg.fr/
Tu y mets ton PDF, et ça te convertit en autant de jpg qu'il y a de page.
Ensuite tu DL le zip, et tu récupères les jpg.
Pas de ligne de commande, et rien à installer (c'est le serveur qui fait tout), et c'est multi-OS... du moment que tu as un navigateur pour atteindre le site et de quoi lire un zip !..
Il y a aussi certainement d'autres sites/logiciels, car celui-ci est gratuit mais avec certaines limites (max. 300DPI, max. 25Mb pour le pdf,...)
A toi de chercher si la solution donnée ne convient pas à ton cas.
Dernière modification par Zakhar (Le 06/10/2013, à 22:20)
"A computer is like air conditioning: it becomes useless when you open windows." (Linus Torvald)
Hors ligne
#3 Le 07/10/2013, à 07:47
- masterbalby
Re : Découpage automatique bande dessinée
merci pour la réponse mais j'ai du mal m'expliquer.
Les planches en jpg je les ai déjà.
Ce que je veux c'est découper chaque jpg en plusieurs vignettes.
Comme l'exemple ci-dessous pour deux vignettes :
De cette manière je n'ai qu'une vignette qui apparait sur l'écran de la tablette et c'est beaucoup plus lisible
Hors ligne
#4 Le 07/10/2013, à 08:33
- Zakhar
Re : Découpage automatique bande dessinée
Ah... eh bien tu vois tout de suite le problème : tes vignettes sont de taille "aléatoire" ou plutôt irrégulière.
Donc à part le faire "à la main", ça va être coton !
Si les vignettes étaient bien régulières avec des dimensions fixes, tu pourrais utiliser imagemagick qui permet de manipuler des images en ligne de commande. Mais là ton truc va réclamer l'oeil humain pour le découpage, je le crains.
"A computer is like air conditioning: it becomes useless when you open windows." (Linus Torvald)
Hors ligne
#5 Le 07/10/2013, à 12:49
- Brunod
Re : Découpage automatique bande dessinée
Sans compter pour certaines bd spéciales ou une case prend une page ou deux en vis-à-vis, ou encore où les cases fusionnent les unes avec les autres...
Dernière modification par Brunod (Le 07/10/2013, à 12:55)
Windows est un système d'exploitation de l'homme par l'ordinateur. Linux, c'est le contraire...
39 pc linux convertis
Hors ligne
#6 Le 10/10/2013, à 07:13
- masterbalby
Re : Découpage automatique bande dessinée
merci pour vos réponses
Pour l'instant je pars sur des bds on va dire classique (comme celle que j'ai mis en exemple ou des tintin).
Donc ce sont des bds qui ne présentent pas de grosses particularités au niveau des vignettes.
J'ai trouvé un script en python censé faire ces découpes.
Le voila :
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()
Le script fait presque bien le boulot j'ai jusque quelques erreurs (vignettes coupées en deux, ou vignettes fusionnées).
Par contre je n'ai pas bien compris les 4 réglages dispos.
Voila
Hors ligne