qui seraient posées n'importe comment, dans une grande image
et permet de sauver automatiquement le résultat de la découpe
le prg se présente comme ceci :
[Load img] pour charger une planche de sprites
et juste apres avoir choisi une planche de sprite, le prg vous demande dans quel
dossier vous voulez que les sauvegardes se fassent ..
[couleur fond] permet de choisir la couleur du fond des sprites (par defaut c'est le pixel (1,1) )
[decoupe] , lance le protocole de decoupe , j'ai voulu qu'on puise voir tout se qui se passe , donc c'est un peu plus long
mais c'est cool de le voir bosser
par defaut un appuis sur [decoupe] , ne decoupe qu'une seule image
si vous entrez un nombre dans le String "Nbr SPR" ça va decouper plusieurs sprites les uns apres les autres
j'ai testé sur cette image :
et sur celle-ci :
si par hasard vous trouvez une image qui fasse planter mon prg , n'hesitez pas a me le dire
le code :
Code : Tout sélectionner
;***********************************************
;Titre :*Img_cutter_3
;Auteur : Zorro
;Date :12/08/2016
;Heure :14:45:15
;Version Purebasic : PureBasic 5.50 (Windows - x86)
;Version de l'editeur :EPB V2.64
; Libairies necessaire : Aucune
;***********************************************
UseJPEG2000ImageDecoder()
UseJPEG2000ImageEncoder()
UseJPEGImageDecoder()
UseJPEGImageEncoder()
UsePNGImageDecoder()
UsePNGImageEncoder()
UseTGAImageDecoder()
UseTIFFImageDecoder()
;{ Windows
Enumeration
#Win
EndEnumeration
;{ Gadgets
Enumeration
#Text_Titre
#Text_Auteur
#Gadget_Button_Load
#Gadget_Button_couleur_fond
#Gadget_Image_couleur_fond
#ScrollArea_4
#ScrollArea_5
#Gadget_Image_travail
#Gadget_Button_decoupe
#Gadget_Image_control
#Gadget_Progress_bar
#Gadget_V_H
#Gadget_Button_selec_man
#Text_info
#Text_info_sprite
#Gadget_nbr
#Text_nbr
#Gadget_checkbox_selection
#image_couleur_fond
#image_origine
#image_buffer
#image_sortie
#image_sortie2
;
#image_text
EndEnumeration
;{ Fonts
Enumeration
#Font_Text_Titre
EndEnumeration
Define.l Event
Declare openwin()
Declare selection(coul_fond)
Declare decoupe(coul_fond)
Declare selectionv(coul_fond)
Declare couleur_fond(state)
Declare selection_manuel( coul_fond ,coul_marquage)
OpenWin()
Global path_prg.s=GetCurrentDirectory()
Global State ,nbr2
Global coul_marquage=Rgb(255,2,3),coul_fond
Global yyyyy_start ; cette variable va me servir a connaitre le numero de ligne de depart du sprite trouvé !
Global state_vh=#false ,State_selec_manu=#false,Flag_sel_manu=#false
Text.s="il etait une bergere, et ri et ron , petit patapon"
Alphabet.s="a,b,c,d,e,f,g,h,i,j,k,l,m,,n,o,p,q,r,s,t,u,v,w,x,y,z,0,1,2,3,4,5,6,7,8,9, "
; **** a mettre en commentaire au deuxieme lancement ****
; if CreateImage(#image_text,800,600,32,rgb(255,255,255) ) ;
; StartDrawing(ImageOutput(#image_text))
; DrawingMode(#PB_2DDrawing_Default )
; DrawText(1,1,text.s,$0,rgb(255,255,255))
; StopDrawing()
;
; SaveImage(#image_text,"image_text.png",#PB_ImagePlugin_PNG)
; Else
; MessageRequester("erreur","creation image texte impossible")
; Endif
; End
; ***************************************************
Repeat
;-boucle
Event = WaitWindowEvent(12)
Select Event
Case #PB_Event_Gadget
Select EventGadget()
Case #Text_Titre
Case #Gadget_Button_Load
im_origine.s=OpenFileRequester("charge une image",path_prg.s,"images|*.png;*.jpg;*.bmp;*.tga;*.Tiff",0)
If im_origine.s<>""
If LoadImage(#image_origine,im_origine.s)
CopyImage(#image_origine,#image_buffer)
CreateImage( #image_sortie,ImageWidth(#image_origine),ImageHeight(#image_origine),32,#PB_Image_Transparent )
SetGadgetState(#Gadget_Image_travail,imageId(#image_buffer))
Global Dim im_origine(ImageWidth(#image_origine),ImageHeight(#image_origine))
Global Dim im_buffer(ImageWidth(#image_origine),ImageHeight(#image_origine))
StartDrawing(ImageOutput(#image_origine))
DrawingMode(#PB_2DDrawing_AlphaBlend )
For y=0 to ImageHeight(#image_origine)-1
For x=0 to ImageWidth(#image_origine)-1
im_origine(x,y)=point(x,y)
Next x
Next y
coul_fond=point(1,1)
StopDrawing()
StartDrawing(ImageOutput(#Image_couleur_fond))
box(0,0,ImageWidth(#Image_couleur_fond),ImageHeight(#Image_couleur_fond),coul_fond)
StopDrawing()
SetGadgetAttribute(#scrollarea_4, #PB_ScrollArea_InnerWidth , ImageWidth(#image_origine))
SetGadgetAttribute(#scrollarea_4, #PB_ScrollArea_InnerHeight , ImageHeight(#image_origine))
Endif
Endif
Global path_sauv.s=PathRequester("ou sauver ?",path_prg.s)
Case #Gadget_Button_couleur_fond
State=GetGadgetState(#Gadget_Button_couleur_fond)
Case #Gadget_Button_selec_man
State_selec_manu=GetGadgetState(#Gadget_Button_selec_man)
Case #Gadget_Image_couleur_fond
Case #ScrollArea_4
Case #gadget_v_h
state_vh=GetGadgetState(#gadget_v_h)
Case #Gadget_Image_travail
Case #Gadget_Button_decoupe
nbr=val(GetGadgetText(#gadget_nbr ))-1
if nbr=<0:nbr=0:Endif
For nb=nbr to 0 step -1
if Flag_sel_manu=#False
if state_vh=#PB_CheckBox_Unchecked
Selection(coul_fond)
Else
SelectionV(coul_fond)
Endif ;|
SetGadgetState(#Gadget_Image_travail,imageId(#image_buffer))
Endif;<
decoupe(coul_fond)
Flag_sel_manu=#False
SetGadgetText(#text_info, "")
SetGadgetText(#gadget_nbr,str(nb) )
UpdateWindow_(GadgetID(#gadget_nbr)); actualise le gadget
;WaitWindowEvent(2)
Next nb;]
SetGadgetText(#gadget_nbr,"000" )
UpdateWindow_(GadgetID(#gadget_nbr)) ; actualise le gadget
SetGadgetState(#Gadget_progress_bar,0)
Case #Gadget_Image_control
EndSelect
;
State=GetGadgetState(#Gadget_Button_couleur_fond)
if State=#True
coul_fond=couleur_fond(State)
SetGadgetState( #gadget_Image_couleur_fond, imageId(#Image_couleur_fond))
Endif
;
State_selec_manu=GetGadgetState(#Gadget_Button_selec_man)
if State_selec_manu=#True
selection_manuel( coul_fond ,coul_marquage)
if State_selec_manu=2
decoupe(coul_fond)
State_selec_manu=#False
SetGadgetState(#gadget_button_selec_man, State_selec_manu) ; releve le bouton
Endif
SetGadgetState(#ScrollArea_5, 0)
Endif
Case #PB_Event_CloseWindow
Select EventWindow()
Case #Win
CloseWindow(#Win)
Break
EndSelect
EndSelect
Forever
;}
;]2
Procedure OpenWin()
;-OpenWindow
If OpenWindow(#Win, 214, 10, 942, 641, "Img_Cutter3 by Zorro", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_TitleBar)
TextGadget(#Text_Titre, 300, 30, 260, 30, "Img_Cutter 3")
TextGadget(#Text_Auteur, 400, 65, 260, 35, "By Zorro")
ButtonGadget(#Gadget_Button_Load, 15, 100, 105, 25, "Load img")
ButtonGadget(#Gadget_Button_couleur_fond, 15, 165, 105, 25, "Couleur fond",#PB_Button_Toggle )
TextGadget(#Text_nbr, 15, 210, 80, 35, "Nbr SPR")
StringGadget(#Gadget_nbr,70, 200,30, 25, "000",#PB_String_Numeric )
CheckBoxGadget(#gadget_v_h, 15, 240, 150, 20, "Mode H/V")
ButtonGadget(#Gadget_Button_selec_man, 15, 260, 105, 25, "Sel_man",#PB_Button_Toggle)
ImageGadget(#Gadget_Image_couleur_fond, 135, 150, 50, 45, 0, #PB_Image_Border)
CreateImage(#image_couleur_fond,GadgetWidth(#Gadget_Image_couleur_fond),GadgetHeight(#Gadget_Image_couleur_fond),32)
ButtonGadget(#Gadget_Button_decoupe, 15, 300, 105, 25, "Decoupe")
ProgressBarGadget(#Gadget_Progress_bar, 15, 360, 200, 15, 0,100)
TextGadget(#Text_info, 15,390, 120, 15, "Zorro")
TextGadget(#Text_info_sprite, 15,420, 120, 30, "résolution")
ScrollAreaGadget(#ScrollArea_5, 10, 450, 200, 165, 700, 1100, 10, #PB_ScrollArea_Single)
ImageGadget(#Gadget_Image_control, 0, 0, 10, 10, #PB_Image_Border) ;>2
CloseGadgetList()
ScrollAreaGadget(#ScrollArea_4, 220, 120, 700, 550, 700, 1100, 10, #PB_ScrollArea_Single) ;
ImageGadget(#Gadget_Image_travail, 0, 0, 10, 10,#PB_Image_Border) ;>2
CloseGadgetList()
SetGadgetFont(#Text_Titre, LoadFont(#Font_Text_Titre, "Courier New", 24, #PB_Font_Bold|#PB_Font_HighQuality))
Endif
EndProcedure
Procedure selection(coul_fond)
;-selection
SetGadgetText(#text_info, "selection d'un sprite")
StartDrawing(ImageOutput(#image_buffer))
DrawingMode(#PB_2DDrawing_Default )
compteur_c=0
For y=0 to ImageHeight(#image_origine) -1
For x=0 to ImageWidth(#image_origine) -1
coul_o=point(x,y) ; regarde toutes le couleur de l'image
if coul_o<> coul_fond ;and coul_o <> coul_marquage ; tiens un sprite (une couleur est differente de la couleur du fond et du remplissage )
FillArea(x,y, coul_fond ,coul_marquage) ; on rempli (c'est notre pseudo selection ) l'emplacement du sprite est marqué !
yyyyy_start=y
StopDrawing();>
StartDrawing(ImageOutput(#image_buffer))
DrawingMode(#PB_2DDrawing_Default )
For y=0 to ImageHeight(#image_buffer) -1
For x=0 to ImageWidth(#image_buffer) -1
im_buffer(x,y)=point(x,y)
Next x
Next y
StopDrawing()
ProcedureReturn
Endif
Next x
Next y
StopDrawing()
Endprocedure
Procedure decoupe(coul_fond)
;-decoupe
;By Dobro
SetGadgetText(#text_info, "je decoupe")
; le moment ou la couleur est egale a notre marquage (coul_marquage )
x_max=0:y_max=0 :x_start=0:y_start=0 :Flag=0:coul_o=0
SetGadgetAttribute(#Gadget_progress_bar , #PB_ProgressBar_Maximum, ImageHeight(#image_buffer) -1)
Dim im_sortie(ImageWidth(#image_buffer),ImageHeight(#image_buffer))
Dim im_sortie2(ImageWidth(#image_buffer),ImageHeight(#image_buffer))
StartDrawing(ImageOutput(#image_buffer))
DrawingMode(#PB_2DDrawing_Default )
For y=0 to ImageHeight(#image_buffer) -1
For x=0 to ImageWidth(#image_buffer) -1
coul_o=im_buffer(x,y)
if coul_o= coul_marquage ; tiens.... un sprite
if Flag=1
if x<x_start ; au cas ou le poins de depart x serai un peu plus a gauche que prevue (cas pour un cercle par ex )
x_start=x
Endif
if x>x_max ; prends les coordonées maximum de droite
x_max=x
Endif
if y>y_max ; prends les coordonees maximum en bas
y_max =y
Endif
Endif
plot(x,y,coul_fond) ; ici on dessine dans l'image affichée (image buffer) la couleur de fond, ce qui donne l'impression qu'on efface
im_sortie(x,y)=im_origine(x,y) ; puisqu'on est dans la couleur de remplissage, on est sur d'etre sur le sprite , on le dessine en utilisant les vraies couleurs
if Flag=0 ; prends les coordonées haut gauche pour le Crop plus tard...
Flag=1 ; ce flag indique qu'on viens de passer en mode "sprite trouvée"
x_start=x
y_start=y
Endif
compteur_line=0
Else ; la couleur observé ne correspond pas a un sprite (couleur de marquage)
;im_sortie(x,y)=coul_fond
Endif
Next x
compteur_line=compteur_line+1
if compteur_line >= yyyyy_start +4; le compteur nous indique qu'on a fait 4 lignes, sans rencontrer de remplissage
SetGadgetState(#Gadget_progress_bar,0) ; on remet le progressbar a zero
compteur_line=0 ; on remet le compteur a zero (a zorro )
Flag=0
Endif
if Flag=1 and coul_o<> coul_marquage and coul_o <> coul_fond
SetGadgetState(#Gadget_Image_travail,imageId(#image_buffer))
Endif
SetGadgetState(#Gadget_progress_bar,y)
Next y
StopDrawing()
SetGadgetState(#Gadget_Image_travail,imageId(#image_buffer)) ; met a jour l'affichage dans l'interface
SetGadgetText(#text_info, "je redessine")
FreeImage( #image_sortie)
CreateImage( #image_sortie,ImageWidth(#image_origine),ImageHeight(#image_origine),32,#PB_Image_Transparent )
StartDrawing(ImageOutput(#image_sortie))
DrawingMode(#PB_2DDrawing_Default )
Box(1,1,ImageWidth(#image_sortie),ImageHeight(#image_sortie),coul_fond) ; on efface en blanc
DrawingMode(#PB_2DDrawing_AlphaBlend )
For y=0 to ImageHeight(#image_sortie) -1
For x=0 to ImageWidth(#image_sortie) -1
if im_sortie(x,y)<>coul_fond
plot(x,y,im_sortie(x,y))
Else
plot(x,y,coul_fond)
Endif
Next x
SetGadgetState(#Gadget_progress_bar,y)
Next y
StopDrawing()
if IsImage(im_sortie)
FreeImage(im_sortie)
Endif
SetGadgetText(#text_info, "je Grab")
if x_max-x_start>0 and y_max-y_start>0
GrabImage(#image_sortie, im_sortie, x_start,y_start, (x_max+1-x_start),( y_max+1-y_start))
nbr2=nbr2+1
SetGadgetText(#text_info, "je Sauve")
SaveImage( im_sortie,path_sauv.s+"sprite_"+str(nbr2)+".png",#PB_ImagePlugin_PNG )
SetGadgetAttribute(#scrollarea_5, #PB_ScrollArea_InnerWidth , ImageWidth(#image_sortie))
SetGadgetAttribute(#scrollarea_5, #PB_ScrollArea_InnerHeight , ImageHeight(#image_sortie))
SetGadgetState(#gadget_image_control,imageId( im_sortie))
;FreeGadget(#Text_info_sprite)
;TextGadget(#Text_info_sprite, 15,gadgety(#Gadget_Image_control)+GadgetHeight(#Gadget_Image_control)+10, 120, 35,str( x_max-x_start)+"x"+str(y_max-y_start))
SetGadgetText(#Text_info_sprite,"Resolution: "+str( x_max-x_start)+"x"+str(y_max-y_start))
SetGadgetState(#Gadget_progress_bar,0)
SetGadgetText(#text_info, "Fini !")
Endif
Endprocedure
Procedure selectionV(coul_fond)
;-selectionV
SetGadgetText(#text_info, "selection d'un sprite")
StartDrawing(ImageOutput(#image_buffer))
DrawingMode(#PB_2DDrawing_Default )
For x=0 to ImageWidth(#image_buffer) -1
For y=0 to ImageHeight(#image_buffer) -1
coul_o=point(x,y) ; regarde toutes le couleur de l'image
if coul_o<>coul_fond and coul_o <> coul_marquage ; tiens un sprite (une couleur est differente de la couleur du fond et du remplissage )
FillArea(x,y, coul_fond ,coul_marquage) ; on rempli (c'est notre pseudo selection ) l'emplacement du sprite est marqué !
yyyyy_start=y
StopDrawing();>
StartDrawing(ImageOutput(#image_buffer))
DrawingMode(#PB_2DDrawing_Default )
For y=0 to ImageHeight(#image_buffer) -1
For x=0 to ImageWidth(#image_buffer) -1
im_buffer(x,y)=point(x,y)
Next x
Next y
StopDrawing()
ProcedureReturn
Endif
Next y
Next x
StopDrawing()
Endprocedure
Procedure selection_manuel( coul_fond ,coul_marquage)
;-selection manu
;By Dobro
If State_selec_manu=#True
start = GetTickCount_() ; Note time of first click. (Merci guimauve ;o) )
GetAsyncKeyState_(#VK_LBUTTON) ; vide buffer
Repeat : Until GetAsyncKeyState_(#VK_LBUTTON) <> 0 Or GetTickCount_() - start > GetDoubleClickTime_()
If GetTickCount_() - start < GetDoubleClickTime_() ; Timed out!
GetCursorPos_(@cp.POINT)
GetWindowRect_(GadgetID(#Gadget_Image_travail),gr.RECT)
MapWindowPoints_(#Null, GadgetID(#Gadget_Image_travail), cp, 1) ; cp now contains gadget coords
if cp\x>0 and cp\x<GadgetWidth(#Gadget_Image_travail) and cp\y>0 and cp\y<GadgetHeight(#Gadget_Image_travail)
StartDrawing(ImageOutput(#image_buffer))
DrawingMode(#PB_2DDrawing_Default )
FillArea(cp\x,cp\Y, coul_fond ,coul_marquage)
State_selec_manu=2
UpdateWindow_(GadgetID(#gadget_button_selec_man))
StopDrawing()
StartDrawing(ImageOutput(#image_buffer))
DrawingMode(#PB_2DDrawing_Default )
For y=0 to ImageHeight(#image_buffer) -1
For x=0 to ImageWidth(#image_buffer) -1
im_buffer(x,y)=point(x,y)
if im_buffer(x,y)=coul_marquage
yyyyy_start=y
Endif
Next x
Next y
StopDrawing()
Endif
Endif
SetGadgetState(#Gadget_Image_travail,imageId(#image_buffer))
Endif
EndProcedure
Procedure couleur_fond(State)
;-Couleur_fond
;By Dobro
If State=#True
start = GetTickCount_() ; Note time of first click. (Merci guimauve ;o) )
GetAsyncKeyState_(#VK_LBUTTON) ; vide buffer
Repeat : Until GetAsyncKeyState_(#VK_LBUTTON) <> 0 Or GetTickCount_() - start > GetDoubleClickTime_()
If GetTickCount_() - start < GetDoubleClickTime_() ; Timed out!
GetCursorPos_(@cp.POINT)
GetWindowRect_(GadgetID(#Gadget_Image_travail),gr.RECT)
MapWindowPoints_(#Null, GadgetID(#Gadget_Image_travail), cp, 1) ; cp now contains gadget coords
if cp\x>0 and cp\x<GadgetWidth(#Gadget_Image_travail) and cp\y>0 and cp\y<GadgetHeight(#Gadget_Image_travail)
StartDrawing(ImageOutput(#image_buffer))
DrawingMode(#PB_2DDrawing_Default )
coul_pick=point(cp\x,cp\Y) ; recupe la couleur de fond pointée
StopDrawing()
StartDrawing(ImageOutput(#Image_couleur_fond)) ; on met a jour l'image couleur de fond
DrawingMode(#PB_2DDrawing_Default )
box(0,0,ImageWidth(#Image_couleur_fond),ImageHeight(#Image_couleur_fond),coul_pick)
StopDrawing()
SetGadgetState( #gadget_Image_couleur_fond, imageId(#Image_couleur_fond)) ; attribut la couleur
State=#False
SetGadgetState(#Gadget_Button_couleur_fond, State) ; releve le bouton
ProcedureReturn coul_pick
Endif
Endif
Endif
EndProcedure
;EPB
on prends l'image a decouper ,
on en fait une copie (on va bosser sur la copie )
on regarde en pixel 1,1 (ou on demande a l'utilisateur) quelle est la couleur de fond
1er temps :
on scan chaque pixels de l'image (mis en tableau )
si le pixel est different on est sur un sprite , alors on le rempli d'une couleur de selection (avec Fill Area ) ici couleur rouge !!
on garde le X et le Y histoire de savoir ou se trouve le coté haut-gauche du sprite (mais si le x nouveau est plus petit que le X ancien
on garde le plus petit )
on continu le scan tant qu'on est sur la couleur de selection ... si on est plus, c'est le xmax qu'on garde
pareil en y , apres ça on a les coordonées du sprite dans l'image
2eme temps :
je cree une image transparente
je parcours le tableau de pixel
si la couleur = rouge (couleur de selection )
je lis les pixel de meme coordonées de l'image d'origine (celle que j'ai gardé au debut )
et les ecrits dans l'image buffer actuel
bien sur en meme temp je peint les pixel rouge en couleur de fond (plutot blanc)
d'ou la disparition du sprite ....enfin la trace blanche que ça laisse
comme ça au prochaine Scan, le sprite n'existe plus , puisqu'il correspond a de fond !
ensuite je Grab l'image buffer .. je le presente dans l'interface en donnant sa taille, et je sauve le Sprite
on recommence au prochain clique