PureBasic

Forums PureBasic
Nous sommes le Lun 21/Mai/2018 21:43

Heures au format UTC + 1 heure




Poster un nouveau sujet Répondre au sujet  [ 10 messages ] 
Auteur Message
 Sujet du message: Pure Reductor
MessagePosté: Ven 23/Juin/2017 11:13 
Hors ligne
Avatar de l’utilisateur

Inscription: Mar 31/Mai/2016 9:06
Messages: 1930
Pure Reductor

n'est pas a proprement parlé fait pour reduire la taille des images

mais plutot un prg qui permet de reduire le nombre couleurs utilisé pour dessiner une image
par la suite un algo de compression pour etre mis en place pour profiter du nombre de couleurs reduite
et reduire la taille de l'image !

utilisation : (il y a plusieurs mode d'utilisations )

mode normal :
vous chargez une image , elle va se dessiner dans l'interface

[Nbr de couleurs] indique le nombre de couleur que vous voulez utiliser pour redessiner l'image
a noter que vous pouvez faire plusieurs essai, sans avoir a recharger l'image d'origine,le prg repart toujours de l'image d'origine meme si pas affichée
un appuis sur [Run] , ça bosse (indication en haut a gauche de la fenetre)

ça va afficher le resultat ....

le curseur vertical a gauche permet de regler la tolerance , plus il y a de tolerance, plus vous permettez au prg de prendre la couleur qu'il veux pour dessiner !
diminuer la tolerance, oblige le prg a utiliser un crayon de la palette le plus proche possible de la couleur a dessiner ....

faites des tests :)

Mode Pick :

dans ce mode, vous chargez une image
ensuite en activant le bouton [pick] , vous choisissez des pixels de couleur pour creer la palette de crayons pour le prg
chaque click = un crayon de plus (le compteur se met a jour dans l'interface )

ensuite vous reglez votre tolerance (ou pas) , et lancez le dessin avec [Run] !


la case a cocher Floyd sert a tramer en utilisant l'algo Floyd
la case Flou permet d'ajouter un leger flou sur l'image final



voici le code :

Code:

;***********************************************
;Titre  :*Pure_reductor_interface
;Auteur  : Dobro
;Date  :17/03/2016
;Heure  :18:01:29
;Version Purebasic : PureBasic 5.60 (Windows - x86)
;Version de l'editeur :EPB V2.64
; Libairies necessaire : Aucune
;***********************************************



;{- Enumerations / DataSections
;{ Windows
Enumeration
      #Win
EndEnumeration
;}
;{ Gadgets
Enumeration
      #Button_Load
      #CheckBox_Floyd
      #CheckBox_Flou
      #TrackBar_tolerance
      #Text_info
      #Text_info2
      #Text_tol_val
      #Text_tolerance
      #Text_Titre
      #Container_8
      #Button_Run
      #String_nb_couleur
      #Text_color
      #Button_Save
      #zone_acenseur
      #image_palette
      #Button_pick
      #Image_ori
EndEnumeration

;}
;{ Fonts
Enumeration
      #Font_Text_Titre
EndEnumeration
;}
Define.l Event
InitMouse()
UseJPEGImageDecoder():UsePNGImageDecoder():UseTGAImageDecoder():UseTIFFImageDecoder()
UseJPEGImageEncoder()
Resultat = InitSprite()
Declare distance_couleur(couleur1,couleur2)
Declare  make_palette(nb_image,nbr_couleur.i,palette )
Declare  Dessin(nb_image,nbr_couleur,tolerance,Floyd,flou)
Declare  mise_en_tab_ori(nb_image,Largeur_image,Hauteur_image)
Declare  mise_en_tab(nb_image,largeur_image,hauteur_image)
Declare  flou(nb_image,imagex,imagey, niveau)
Declare  doomohundro(himg) ; floyd
Declare.i truncf0255 (a.f)
Declare  rgbtolum(c.l)  ;get luminosity (the min and max rgb levels / 2)
Enumeration
      #Image
      #image_resultat
      #Fenetre
      #file
EndEnumeration
Global NewList palette()
Global NewList des()
Global Flag_pick=-1,compteur,vertical,pas,compteur_coul,nbr_couleur,Flag_pick_pick

;}
Procedure OpenWindow_Win()
      If OpenWindow(#Win, 180, 5, 1096, 672, "Pure_reductor By Dobro", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_TitleBar)
            ;If CreateGadgetList(WindowID(#Win))
            ButtonGadget(#Button_Load, 15, 50, 90, 35, "Load Img")
            CheckBoxGadget(#CheckBox_Floyd, 15, 135, 105, 25, "Floyd Tramage")
            CheckBoxGadget(#CheckBox_Flou, 15, 160, 105, 25, "Flou")
            TrackBarGadget(#TrackBar_tolerance, 10, 235, 45, 310, 0,442, #PB_TrackBar_Ticks|#PB_TrackBar_Vertical)
            TextGadget(#Text_tolerance, 10, 210, 75, 25, "Tolerance")
            TextGadget(#Text_tol_val,90, 210, 40, 30,  "0")
            tolerance=0 ; Tolerance par defaut !
            SetGadgetState(#TrackBar_tolerance,tolerance)
            SetgadgetText (#Text_tol_val,str(tolerance))
            SetgadgetText (#Text_tol_val,str(tolerance))
            TextGadget(#Text_Titre, 430, 15, 195, 40, "Pure_reductor")
            TextGadget(#Text_info, 20, 15, 100, 25, "Info")
            TextGadget(#Text_info2, 150,5, 195,40, "Info2")
            ButtonGadget(#Button_Run, 10, 545, 90, 35, "Run")
            StringGadget(#String_nb_couleur, 85, 90, 35, 20, "256")
            TextGadget(#Text_color, 15, 90, 70, 20, "Nbr Couleurs")
            ButtonGadget(#Button_Save, 10, 595, 90, 35, "Save Img")
            ButtonGadget(#Button_pick, 55, 240, 50, 20, "Pick",#PB_Button_Toggle )
            
            ScrollAreaGadget(#zone_acenseur,130, 55,  940, 595,0, 0, 30)
            CanvasGadget(#image_palette, 0,55, 8*16, 8*256)
            ContainerGadget(#Container_8, 130, 55, 940, 595,#PB_Container_Double)
            OpenWindowedScreen(gadgetID(#Container_8),0, 0, 940, 595, 0, 0, 0 ) ; on met un ecrant dedans
            CloseGadgetList()
            ; Gadget Fonts
            SetGadgetFont(#Text_Titre, LoadFont(#Font_Text_Titre, "Microsoft Sans Serif", 22, #PB_Font_HighQuality))
            ;EndIf
      EndIf
EndProcedure
OpenWindow_Win()
;{- Event loop
Repeat
      Event = WaitWindowEvent(12)
      Select Event
            ; ///////////////////
            Case #PB_Event_Gadget
            Select EventGadget()
                  Case #Button_Load
                  Flag_pick_pick=0 :vertical=0:compteur=0
                  if FileSize("chemin.inf")<>-1
                        if Openfile(#file,"chemin.inf")
                              chemin$=ReadString(#file)
                        CloseFile(#file)
                        NomFichier$=OpenFileRequester("Charge une image", chemin$+"*.*", "", 0)
                  Endif
                  chemin$=GetPathPart(NomFichier$)
                  Openfile(#file,"chemin.inf")
                        WriteStringN(#file,chemin$)
                  CloseFile(#file)
            Else
                  NomFichier$ = OpenFileRequester("Charge une image", "*.*", "", 0) ; on choisi un ficher
                  chemin$=GetPathPart(NomFichier$)
                  Openfile(#file,"chemin.inf")
                        WriteStringN(#file,chemin$)
                  CloseFile(#file)
            Endif
            If NomFichier$<>""
                  Resultat = LoadImage(#Image, NomFichier$ ) ; on charge une image
                  global format$=GetExtensionPart(NomFichier$)
            EndIf
            if IsImage(#image)
                  Global largeur_image=ImageWidth(#Image)
                  Global Hauteur_image=ImageHeight(#Image)
                  if largeur_image>Hauteur_image : ResizeImage(#image,1024,768):endif
                  if largeur_image<Hauteur_image : ResizeImage(#image,768,1024):endif
                  Global largeur_image=ImageWidth(#Image)
                  Global Hauteur_image=ImageHeight(#Image)
                  CloseScreen()
                  OpenWindowedScreen(gadgetID(#Container_8),0, 0, largeur_image,Hauteur_image, 0, 0, 0 ) ; on met un ecran dedans
                  CopyImage(#Image,#Image_ori)
                  StartDrawing(ScreenOutput()) ;
                        DrawImage(ImageID(#Image), 0, 0)
                  StopDrawing()
                  
                  ResizeGadget(#container_8, #PB_Ignore, #PB_Ignore,Largeur_image, Hauteur_image)
                  SetGadgetAttribute(#zone_acenseur, #PB_ScrollArea_InnerWidth  , Largeur_image+(Largeur_image/2))
                  SetGadgetAttribute(#zone_acenseur, #PB_ScrollArea_InnerHeight  ,Hauteur_image+(Hauteur_image/2))
            Else
                  MessageRequester("erreur", "l'image n'a pas pu etre chargée")
                  End
            Endif
            GLobal Dim TAB_ori(Largeur_image,Hauteur_image) ; le Tableau
            GLobal Dim TAB(Largeur_image,Hauteur_image) ; le Tableau
            StartDrawing(ImageOutput(nb_image))
                  mise_en_tab_ori(nb_image,largeur_image,Hauteur_image) ; apres ça l'image 16 millions de couleurs est dans le Tableau Tab_ori()
            StopDrawing()
            CopyArray(TAB_ori(), TAB())
            FlipBuffers()
            Case #Button_pick
            if IsImage(#image_ori)
                  ClearScreen($0)
                  CopyArray(TAB_ori(), TAB())
                  CopyImage(#Image_ori,#Image)
                  Flag_pick=-Flag_pick
                  nbr_couleur=0
                  if Flag_pick>0 ; mode on recup les couleurs
                        ;on nettoie le canvas qui contient la palette
                        ; StartDrawing(CanvasOutput(#image_palette))
                        ; Box(0,0,GadgetWidth(#image_palette),GadgetHeight(#image_palette),$0)
                        ; StopDrawing()
                        
                        ; on nettoie aussi les listes concernant la palette
                        ClearList(palette())
                        ClearList(Des())
                  Endif
            Endif
            Case #zone_acenseur
            ;debug "ascenseur"
            ; if IsImage(nb_image)
            ; StartDrawing(ScreenOutput()) ;
            ; DrawImage(ImageID(nb_image), 0, 0)
            ; StopDrawing()
            ; FlipBuffers()
            ; Endif
            Case #CheckBox_Floyd
            statF=GetGadgetstate(#CheckBox_Floyd)
            if statf=#PB_CheckBox_Checked 
                  floyd=1
            Else
                  floyd=0
            Endif
            Case #CheckBox_Flou
            statfl=GetGadgetstate(#CheckBox_Flou)
            if statfl=#PB_CheckBox_Checked 
                  Flou=1
            Else
                  Flou=0
            Endif
            Case #TrackBar_tolerance
            tolerance=GetGadgetstate(#TrackBar_tolerance)
            SetgadgetText (#Text_tol_val,str(tolerance))
            Case #Text_tolerance
            Case #Text_Titre
            Case #Container_8
            Case #Button_Run
            if Flag_pick>0
                  SetGadgetState(#Button_pick, 0)
                  Flag_pick=-Flag_pick
            Endif
            if isimage(#image)
                  ;-bouton RUN
                  if Flag_pick_pick=0 
                        
                        ClearList(palette())
                        ClearList(Des())
                        
                        CopyArray(TAB_ori(), TAB())
                        
                  Endif
                  ClearScreen($0)
                  FlipBuffers()
                  ;Tolerance
                  tolerance=GetGadgetstate(#TrackBar_tolerance)
                  ; Flou
                  statfl=GetGadgetstate(#CheckBox_Flou)
                  if statfl=#PB_CheckBox_Checked 
                        Flou=1
                  Else
                        Flou=0
                  Endif
                  ;FLoyd
                  statF=GetGadgetstate(#CheckBox_Floyd)
                  if statf=#PB_CheckBox_Checked 
                        floyd=1
                  Else
                        floyd=0
                  Endif
                  ; Nbr_couleur
                  nbr_couleur=val(GetGadgetText(#String_nb_couleur))
                  ; Run
                  palette=1; pour afficher la palette dans l'image
                  if Flag_pick_pick=0
                        make_palette(#image,nbr_couleur,palette)
                  Endif
                  dessin(#image,nbr_couleur,tolerance,Floyd,flou ) ;
            Else
                  MessageRequester("info", "Chargez d'abord une image")
            ENdif
            Case #String_nb_couleur
            compteur_coul=0
            nbr_couleur=val(GetGadgetText(#String_nb_couleur))
            Case #Text_color
            Case #Button_Save
            if isimage(#image)
                  SaveImage(#image,"resultat_en_"+str(nbr_couleur)+"_"+str(tolerance)+".bmp",#PB_ImagePlugin_BMP)
                  MessageRequester("info", "Image sauvé avec le nom :"+chr(10)+"resultat_en_"+str(nbr_couleur)+"_"+str(tolerance)+".bmp")
            Else
                  MessageRequester("info", "Chargez d'abord une image")
            Endif
      EndSelect
      ; ////////////////////////
      Case #PB_Event_CloseWindow
      Select EventWindow()
            Case #Win
            CloseWindow(#Win)
            Break
      EndSelect
      Case #WM_LBUTTONDOWN
      
      if Flag_pick>0 ; on pick
            GetCursorPos_(@cp.POINT)
            GetWindowRect_(GadgetID(#Container_8),gr.RECT)
            PtInRect_(@gr, cp\x<<32+cp\Y)
            MapWindowPoints_(#Null, GadgetID(#Container_8), cp, 1) ; cp now contains gadget coords
            if ( cp\x>=0 and cp\x<=ImageWidth(#image)) and (cp\y>=0 and cp\y<=ImageHeight(#image) )
                  StartDrawing(ScreenOutput()) ;
                        couleur_pick=point(cp\x,cp\Y)
                  StopDrawing()
                  coul.i=couleur_pick
            Endif
            ForEach palette()
                  if palette()=coul.i  ; c'est une couleurs nouvelle pour la palette ?                   
                        flag_ok=1 ; non on l'a deja !
                  Endif
            Next
            ; *************************************************
            if flag_ok=1 ; couleur deja presente dans la palette
                  flag_ok=0
            Else ; couleur nouvelle trouvée
                  Flag_pick_pick=1
                  AddElement(palette()) ; on la stock
                  palette()=coul.i
                  compteur_coul=compteur_coul+1
                  nbr_couleur=compteur_coul
                  SetGadgetText( #String_nb_couleur,str(nbr_couleur))
            Endif
            
            SortList(palette(), #PB_Sort_Descending)
            StartDrawing(CanvasOutput(#image_palette))
                  
                  Box(0,0,GadgetWidth(#image_palette),GadgetHeight(#image_palette),$0)
                  compteur=0:vertical=0
                  ForEach palette()
                        pas=8
                        
                        Box (1+compteur,vertical,pas,pas,palette())
                        compteur=compteur+pas
                        
                        if compteur => GadgetWidth(#image_palette)
                              compteur=0
                              vertical=vertical+pas
                              compteur=0
                        Endif
                  Next
                  
            StopDrawing()
            
            
            
            
      Endif
EndSelect


if IsImage(#image)
      StartDrawing(ScreenOutput()) ;
            DrawImage(ImageID(#Image), 0, 0)
      StopDrawing()
      FlipBuffers()
Endif

Forever
;
;}
;-Procedures Zone
;-calcul Distance couleur
Procedure distance_couleur(couleur1,couleur2)
      ; by Dobro
      rf.c=red(couleur1) :vf.c=green(couleur1): bf.c=blue(couleur1)
      r.c=red(couleur2) :v.c=green(couleur2): b.c=blue(couleur2)
      distance=sqr(pow(rf-r.c,2)+ pow(vf-v.c,2)+pow(bf-b.c,2)) ; calcul de la distance qui sépare la couleur de l'image avec la couleur de la palette
      ProcedureReturn distance
Endprocedure

;-make palette
Procedure make_palette(nb_image,nbr_couleur.i,palette)
      if nbr_couleur.i=0 :  nbr_couleur.i=16:Endif
      ; By Dobro
      largeur_image=ImageWidth(nb_image)
      Hauteur_image=ImageHeight(nb_image)
      ; mise en tableau
      StartDrawing(ImageOutput(nb_image))
            ;mise_en_tab(nb_image,largeur_image,Hauteur_image) ; apres ça l'image 16 millions de couleurs est dans le Tableau Tab()
            RandomSeed(13)
            ; ajout obligatoire du blanc, et du noir !
            AddElement(palette()) ; on la stock
            palette()=$0
            AddElement(palette()) ; on la stock
            palette()=rgb(255,255,255)
            ccc=0
            compteur_coul=0
            for i=1 to  nbr_couleur.i-2
            
                  recommence:
                  x=random(largeur_image-1,1) ; choisi x couleurs au hazard dans l'image pour fabriquer la palette
                  y=random(Hauteur_image-1,1)
                  
                  ; ici en principe, on est sur que 2 fois le meme pixel (et donc 2 fois la meme couleur, ne sera pas dans la palette
                  coul.i=TAB(x,y) ; recupere la couleur dans l'image d'origine (celle des 16 millions de couleurs )
                  ; **** Scan la liste pour chercher des couleurs nouvelles **
                  If nbr_couleur.i<=800
                        tol=5
                  Else
                        Tol=1
                  Endif
                  ForEach palette()
                        If distance_couleur(palette(),coul.i)<=Tol ; ICI on regarde si on a affaire a une nouvelle couleur ,
                              ; on considere que si la couleur trouvée est supérieur en distance  a : 5 , alors c'est une nouvelle couleur , sinon si c'est infereur, on considere qu'on a deja cette couleur dans la palette
                              ;if palette()=coul.i ; c'est une couleurs nouvelle pour la palette ?                   
                              flag_ok=1 ; non on l'a deja !
                              Break
                        Endif
                        ccco=ccco+1
                        if ccco>nbr_couleur.i-2/3
                              WaitWindowEvent(2)
                              ccco=0
                        Endif
                  Next
                  ; *************************************************
                  if flag_ok=1 ; couleur deja presente dans la palette
                        flag_ok=0
                        Goto recommence
                  Else ; couleur nouvelle trouvée
                        AddElement(palette()) ; on la stock
                        palette()=coul.i
                        compteur_coul=compteur_coul+1
                  Endif
            Next i
            SortList(palette(), #PB_Sort_Descending)
            
            if palette=1 ; Dessine la palette
                  pos=0:compteur=0:vertical=0
            StopDrawing() ; ferme l'ecran pour le moment
            StartDrawing(CanvasOutput(#image_palette))
                  Box(0,0,GadgetWidth(#image_palette),GadgetHeight(#image_palette),$0)
                  ForEach palette()
                        if nbr_couleur.i<=512
                              pas=8
                        Else
                              Pas=4
                        Endif
                        Box (1+compteur,vertical,pas,pas,palette())
                        compteur=compteur+pas
                        if compteur => GadgetWidth(#image_palette)
                              compteur=0
                              vertical=vertical+pas
                        Endif
                  Next
                  compteur=0
                  vertical=0
            StopDrawing()
            StartDrawing(ImageOutput(nb_image)) ; reouvre l'ecran
            Endif
            ; a ce stade nous devrions avoir le bon nombre de couleurs
            ; *************************************************
      StopDrawing()
      taa$= " il y a "+str(compteur_coul+2)+" couleurs dans la palette"
      taa1$= "ok la palette est créé j'attaque le dessin ... patience"
      SetgadgetText (#Text_info2,taa$+chr(10)+taa1$)
      
Endprocedure
;- Dessin
Procedure Dessin(nb_image,nbr_couleur,tolerance,Floyd,flou)
      DisableDebugger
      
      
      ClearScreen(0)
      FlipBuffers()
      largeur_image=ImageWidth(nb_image)
      Hauteur_image=ImageHeight(nb_image)
      FreeImage(nb_image) ; efface l'image pour etre sur d'avoir une nouvelle base
      CreateImage(nb_image, largeur_image,Hauteur_image) ; recreer l'image vierge
      taa2$= "debut du dessin"
      ;SetgadgetText (#Text_info2,taa$+ " "+taa1$+ " "+taa2$)
      StartDrawing(ImageOutput(nb_image))
            For y=0 to Hauteur_image-1
                  For x=0 to largeur_image-1
                        coul.i=TAB(x,y)
                        mem_distance=RGB(255,255,255)
                        coull=$0
                        ; rf.c=red(coul.i)
                        ; vf.c=green(coul.i)
                        ; bf.c=blue(coul.i)
                        
                        ;if nbr_couleur>8
                        ForEach palette() ; Pour chaque couleur de la palette
                              ;r.c=red(palette()) :v.c=green(palette()):b.c=blue(palette())
                              distance=distance_couleur(coul.i,palette()) ; on regarde la distance qui separe la couleur d'origine de l'image avec la couleur en cours de la palette
                              
                              If distance<=mem_distance                ; si la distance trouvé est plus petite ou egale a la distance mise en memoire
                                    
                                    mem_distance=distance ; on prends cette couleur qui se rapproche de l'originale
                                    coull=palette()                                    
                              Endif  ; a la fin , en principe on a la couleur de la palette qui se raproche le plus de la couleur du point original de l'image
                              
                              ; Accelerateur si tolerance est grande ... mais image moins fidele
                              If distance <=tolerance ; si la distance mesuré est inferieur au curseur de tolerance, on arrete la et on garde la derniere couleur de la palette trouvée
                                    Break
                              Endif
                              
                        Next
                        plot(x,y,coull) ; dessine avec la couleur de la  palette en cours , en principe la couleur la plus proche du point d'origine
                        mem_couleur=palette()
                        
                        compteur_activity=compteur_activity+1
                        ccco=ccco+1
                        if ccco=4000
                              WaitWindowEvent(2)
                              ccco=0
                        Endif
                  Next x
                  taa$=str(compteur_activity/100)+"/"+str(largeur_image * Hauteur_image/100) ; affiche l'activité
                  SetgadgetText (#Text_info,taa$)
            Next y
            taa$= "Fin dessin"
            SetgadgetText (#Text_info,taa$)
            SetgadgetText (#Text_info2,"")
            if Floyd=1 ; dessine le Floyd
            StopDrawing()
            mise_en_tab(nb_image,largeur_image,Hauteur_image)
            DoOmohundro(nb_image)
      Endif
      If Flou=1 ; ajoute du Flou
      StopDrawing()
      mise_en_tab(nb_image,largeur_image,Hauteur_image)
      Niveau=1
      Flou(nb_image,largeur_image,Hauteur_image, Niveau)
Endif
StopDrawing()
EnableDebugger
EndProcedure
;
Procedure mise_en_tab_ori(nb_image,Largeur_image,Hauteur_image)
      ; By Dobro
      ; mise en tableau du resultat de la reduction
      ;;StartDrawing(ImageOutput(nb_image))
      For y=0 to Hauteur_image-1
            For x=0 to largeur_image-1
                  TAB_ori(x,y)=point(x,y)
            Next x
      Next y
      ;;StopDrawing()
EndProcedure
Procedure mise_en_tab(nb_image,Largeur_image,Hauteur_image)
      ; By Dobro
      ; mise en tableau du resultat de la reduction
      
      StartDrawing(ImageOutput(nb_image))
            For y=0 to Hauteur_image-1
                  For x=0 to largeur_image-1
                        TAB(x,y)=point(x,y)
                  Next x
            Next y
      StopDrawing()
EndProcedure
Procedure Flou(nb_image,ImageX,ImageY, Niveau)
      ; Le Soldat inconnu
      StartDrawing ( ImageOutput (nb_image)) ; on dessine sur l'image
            x = 0 ; on se place en x=0 sur l'image
            Repeat
                  y = 0 ; on se place en y=0 sur l'image
                  Repeat
                        ; on récupère la couleur du point en x et y et alentour
                        Rouge = 0
                        Vert = 0
                        Bleu = 0
                        NbPixel = 0
                        For Px = -Niveau To Niveau
                              For Py = -Niveau To Niveau
                                    If Px + x >= 0 And Px + x < ImageX
                                          If Py + y >= 0 And Py + y < ImageY
                                                ; on fait le mélange des couleurs entre le point en x,y et ceux qui sont à sont alentour
                                                Couleur = TAB(Px + x, Py + y)
                                                Rouge = Rouge + Red (Couleur)
                                                Vert = Vert + Green (Couleur)
                                                Bleu = Bleu + Blue (Couleur)
                                                NbPixel + 1
                                          EndIf
                                    EndIf
                              Next
                        Next
                        ; On recalcule la nouvelle couleur
                        Couleur = RGB (Rouge / NbPixel, Vert / NbPixel, Bleu / NbPixel)
                        ; si la taille du nouveau pixel est positive
                        Plot (x, y, Couleur) ; on dessine un carré qui fait le nouveau pixel de la même couleur que celle récupéré en x et y
                        ; on se déplace sur l'image en y de la taille d'un pixel
                        y = y + 1
                  Until y >= ImageY ; si on a finit la colonne de l'image placé en x
                  ; on se déplace sur l'image en x de la taille d'un pixel
                  x = x + 1
                  ; on fait progresser la barre
                  ;;;SetGadgetState ( #Barre , x)
            Until x >= ImageX ; si on a traité toutes les lignes de l'image
      StopDrawing ()
EndProcedure
Procedure DoOmohundro(hImg) ; Floyd
      Protected nextpixel.f, ierror.f, fer.f, eer.f, teer.f, lr.f
      StartDrawing(ImageOutput(hImg))
            width = ImageWidth(hImg): height = ImageHeight(hImg)
            Protected error.f         ;hold error for current pixel
            Dim error_arr.f(width)
            For y = 2 To height-3
                  lr = 0
                  For x = 2 To width-3     
                        val = TruncF0255(RGBtoLum(Point(x,y)) + error_arr(x))
                        If val > 128       
                              Plot(x,y,TAB(x,y))     
                              error = val-255
                        Else
                              r=red(TAB(x,y))/1.5
                              v=green(TAB(x,y))/1.5
                              b=blue(TAB(x,y))/1.5
                              Plot(x,y,rgb(r,v,b))
                              error = val
                        EndIf           
                        fer.f = error/4     ;a fourth of the error
                        eer.f = fer/2       ;an eighth
                        teer.f = fer + eer  ;three eights
                        error_arr(x-1) + eer
                        error_arr(x) = teer + lr
                        lr = eer
                        error_arr(x+1) + teer
                  Next x
            Next y
      StopDrawing()
EndProcedure

Procedure.i TruncF0255 (a.f)
      If a > 255: a = 255: ElseIf a < 0: a = 0: EndIf
      ProcedureReturn a
EndProcedure
Procedure RGBtoLum(c.l)  ;Get luminosity (the min and max RGB levels / 2)
      r = (c & $FF) :  g = ((c & $FF00) >> 8) :  b = ((c & $FF0000) >> 16)
      If g < r: min = g: Else: min = r: EndIf
      If b < min: min = b: EndIf
      If g > r: max = g: Else: max = r: EndIf
      If b > max: max = b: EndIf
      If b > max: max = b: EndIf   
      lum = (max + min) >> 1  ;/ 2.0
      ProcedureReturn lum
EndProcedure

; Epb



_________________
Image
Image
Site: http://stline.ddns.net/STLINE/
Devise :"dis moi ce dont tu as besoin, je t'expliquerai comment t'en passer"


Dernière édition par Zorro le Jeu 16/Nov/2017 12:57, édité 7 fois.

Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Pure Reductor
MessagePosté: Ven 23/Juin/2017 11:36 
Hors ligne
Avatar de l’utilisateur

Inscription: Mar 31/Mai/2016 9:06
Messages: 1930
si on part de cette image :

Image

voici en 512 couleur Tolerance 0
Image

voici en 256 couleur Tolerance 0
Image

en 64 couleurs Tolerance 0
Image

en 16 Couleurs Tolerance 0
Image

En 8 Couleurs Tolerance 0
Image

En 4 couleurs Tolerance 0
Image

En 2 couleurs Tolerance 0
Image

:)

_________________
Image
Image
Site: http://stline.ddns.net/STLINE/
Devise :"dis moi ce dont tu as besoin, je t'expliquerai comment t'en passer"


Dernière édition par Zorro le Jeu 16/Nov/2017 11:56, édité 5 fois.

Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Pure Reductor
MessagePosté: Ven 23/Juin/2017 13:20 
Hors ligne
Avatar de l’utilisateur

Inscription: Mer 09/Nov/2005 9:53
Messages: 3816
En bleu, comme ca, on se croirait dans another world 8)

_________________
http://xmas.free.fr/
!i!i!i!i!i!i!i!i!i!
!i!i!i!i!i!i!
!i!i!i!
//// Informations ////
Portable LENOVO ideapad 110-17ACL 64 bits
Version de PB : 5.60 - 32 bits


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Pure Reductor
MessagePosté: Mer 15/Nov/2017 11:54 
Hors ligne
Avatar de l’utilisateur

Inscription: Mar 31/Mai/2016 9:06
Messages: 1930
j'ai modifié mon code de Pure_Reductor

maintenant la tolérance marche bien mieux

donc si tolérance grande => traitement plus rapide mais image moins fidele
si Tolerance petite => Traitement plus lent , mais image Fidele !

Tolerance a 0 = image le plus fidele possible, mais tres lent sur Grosse image, ou avec un nobre de couleurs important (>256 )

bon test

Reedit (correction d'un bug lié a StarDrawing() )

_________________
Image
Image
Site: http://stline.ddns.net/STLINE/
Devise :"dis moi ce dont tu as besoin, je t'expliquerai comment t'en passer"


Dernière édition par Zorro le Mer 15/Nov/2017 12:56, édité 1 fois.

Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Pure Reductor
MessagePosté: Mer 15/Nov/2017 12:22 
Hors ligne

Inscription: Mer 14/Sep/2011 16:59
Messages: 872
Y a un problème quelque part.

La photo originale ci-dessus fait 46.7ko.
Les traitements de zorro donnent des images très détériorées tout en restant autour de 40ko alors que le logiciel gratuit photofiltre donne une image sans aucune dégradation avec 16.2ko seulement ! Juste en réenregistrant la photo.
Il peut descendre jusqu'à 3.18ko avec une image qui se dégrade de plus en plus.

M.


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Pure Reductor
MessagePosté: Mer 15/Nov/2017 12:59 
Hors ligne
Avatar de l’utilisateur

Inscription: Mar 31/Mai/2016 9:06
Messages: 1930
chez moi les images ne sont pas "déteriorées"
simplement elles perdent des couleurs , puisque c'est le but de ce prg

diminuer le nombre de couleur ....

j'etabli une palette
ensuite en fonction de la couleur d'un point de l'image original, je remplace par la couleur de la palette le plus proche de la couleur du point d'origine

voila c'est tout :)

ps j'ai reposté les images de François Hollande avec Bill Gate car les anciennes images ne correspondaient plus au code actuelle !

ce qui cause une différence avec un logiciel "Pro"
c'est qu'un soft Pro va analyser l'images et creer une palette intelligente

c'est au moment de la création de la palette que mon code peut effectivement "pecher" :)

_________________
Image
Image
Site: http://stline.ddns.net/STLINE/
Devise :"dis moi ce dont tu as besoin, je t'expliquerai comment t'en passer"


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Pure Reductor
MessagePosté: Jeu 16/Nov/2017 12:05 
Hors ligne
Avatar de l’utilisateur

Inscription: Mar 31/Mai/2016 9:06
Messages: 1930
j'ai un peu modifié mon code
pour qu'il fabrique une palette ayant un peut plus de differences (voir commentaire dans le code )

avant , je prenais des pixels au hasard dans l'image , si la couleur trouvé est nouvelle dans la palette
je l'ajoutais , et recommençais ainsi de suite pour les X couleurs de la palette (32 fois pour une palette de 32 couleurs )

maintenant, je prends les pixel au hasard dans l'image , mais si la couleur trouvée est nouvelle (avec une difference d'au moins 5 )
avec une couleur de la palette, alors seulement je la considere comme nouvelle couleur a intergrer dans la palette
sinon je recommence la tirage d'un pixel au hasard ...

du coup ça me donne une palette avec des couleurs qui ne peuvent pas etre trop proche (au moins 5 de distance d'eccart )
la palette deviens plus diverse !
on peut augmenter ce chiffre pour tester , ça se passe Ligne 374
mais il faut savoir qu'en diversifiant trop les couleur de la palette on perd aussi les transitions entre deux couleur (sur les dégradés par exemple )

j'ai mis 5 car ça me semble pas etre un trop mauvais compromis entre la diversité de la palette, et le respect des degradés (voir le Front de Hollande pour se rendre compte )

l'ensemble n'est pas trop rapide ... car plus on a de couleurs dans la palette , plus la comparaison pour dessiner avec une couleur proche
est longue, il faut regarder chaque couleur de la palette ....

c'est beaucoup plus rapide sur petite palette .....

mais en ayant focé la diversification des couleurs, j'ai un bien meilleur résultat sur les images au dessus de 200 couleurs

_________________
Image
Image
Site: http://stline.ddns.net/STLINE/
Devise :"dis moi ce dont tu as besoin, je t'expliquerai comment t'en passer"


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Pure Reductor
MessagePosté: Jeu 16/Nov/2017 13:11 
Hors ligne
Avatar de l’utilisateur

Inscription: Dim 09/Oct/2005 16:51
Messages: 8367
Yo,
C'est vraiment pas mal pour les images < 8bits. En fait le résultat est aussi bon mais ton algo de couleur est plus fidèle donc l'image est plus ressemblante à l'originale.
De 8bits et + par contre, je trouve que le résultat via encodeimage() est plus propre. Un poil plus granuleux mais du coup sans cet effet de "blur" un peu trop prononcé sur ton image.
Bon job :)

_________________
.: Ar-S :. Tour W10 x64 - Portable W10 x64 K501U PB 5.4x / 5.6x
LDV MULTIMEDIA : Dépannage informatique Aude (11) Isère (38)
RESIZER GOLD : Mon logiciel de redimensionnement par lot


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Pure Reductor
MessagePosté: Jeu 16/Nov/2017 19:06 
Hors ligne
Avatar de l’utilisateur

Inscription: Lun 17/Déc/2007 12:44
Messages: 1600
Salut Zorro,

J'ai remarqué une choses sur les images de résultats, par rapport a celle d'origine. L'image est étirer verticalement, non?

Cordialement,
GallyHC

_________________
Image

Image

Image Official site of PureBasic
Image Official site of SpiderBasic

Configuration : Tower: Windows 7 (Processeur: i7 "x64") (Mémoire: 16Go) (GeForce GTX 760 - 2Go) - PureBasic 5.62 (x86 et x64)


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Pure Reductor
MessagePosté: Jeu 16/Nov/2017 20:21 
Hors ligne
Avatar de l’utilisateur

Inscription: Mar 31/Mai/2016 9:06
Messages: 1930
oui , ligne 139 -140 tu as

Code:
   if largeur_image>Hauteur_image : ResizeImage(#image,1024,768):endif
   if largeur_image<Hauteur_image : ResizeImage(#image,768,1024):endif


j'avais fait ça pour avoir mes images test en pleine interface :)

tu les commentes ; ça respectera exactement l'image d'origine (plus la resolution est grande, plus c'est lent bien sur :) )

_________________
Image
Image
Site: http://stline.ddns.net/STLINE/
Devise :"dis moi ce dont tu as besoin, je t'expliquerai comment t'en passer"


Haut
 Profil  
Répondre en citant le message  
Afficher les messages postés depuis:  Trier par  
Poster un nouveau sujet Répondre au sujet  [ 10 messages ] 

Heures au format UTC + 1 heure


Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 2 invités


Vous ne pouvez pas poster de nouveaux sujets
Vous ne pouvez pas répondre aux sujets
Vous ne pouvez pas éditer vos messages
Vous ne pouvez pas supprimer vos messages

Rechercher:
Aller à:  

 


Powered by phpBB © 2008 phpBB Group | Traduction par: phpBB-fr.com
subSilver+ theme by Canver Software, sponsor Sanal Modifiye