Charment images dans un Thread et affichage en même temps

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Charment images dans un Thread et affichage en même temps

Message par Thyphoon »

Bonjour,

je profite de ce long week-end pour me remettre un peu au purebasic.
Je cherche a afficher des miniatures de photos... mais pour ne pas figer l'application durant le chargement des miniatures, j'essaye de charger ça dans un Thread
Mais le problème c'est que ça bug du fait que j'utilise la même liste dans le thread de chargement que dans la boucle principal pour les afficher.
Certaine miniatures disparaissent ou bien même se décalent ... Je sais qu'il faut utiliser les mutex ou les semaphores... mais ou bien ça n'affiche plus rien le temps que ça charge ou bien ça continue de déconner.
quelqu'un pourrait il m'aider ? ou me donner une piste ?
voici un version de mon code simplifier. il faut sélectionner un répertoire avec des images en ".jpg" (si possible plus d'une dizaine)

Code : Tout sélectionner

EnableExplicit

UseJPEGImageDecoder()

;-Applications Datas
Structure media
  name.s
  mutex.i
  image.i
EndStructure

Structure appDatas
  folder.s                ;current folder to examine
  exiftoolExe.s           ;path to exifTool executable
  thumbnailSize.l         ;thumbnail Size
  List media.media()     
EndStructure

Global appDatas.appDatas

;- Preferences
#Gdt_ThumbnailSize_Max=320
#Gdt_ThumbnailSize_Min=64
appDatas\folder=PathRequester("Choisissez un répertoire avec des photos", "")

appDatas\thumbnailSize=128

;-Windows And Gadget Init

; Windows
#win_Main=0

; Gadget
Enumeration
  #Gdt_Thumbnails
  #Gdt_ThumbnailSize
EndEnumeration

; Timer
Enumeration
   #Timer_RefreashThumbnails
EndEnumeration
OpenWindow(#win_Main,0,0,1900,980,"PhotoRanking", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CanvasGadget(#Gdt_Thumbnails, WindowWidth(#win_Main)/6, 10, WindowWidth(#win_Main)/6*4, WindowHeight(#win_Main)-100)
TrackBarGadget(#Gdt_ThumbnailSize, WindowWidth(#win_Main)/6, GadgetY(#Gdt_Thumbnails)+GadgetHeight(#Gdt_Thumbnails), 200, 25, #Gdt_ThumbnailSize_Min, #Gdt_ThumbnailSize_Max)

Procedure loadFolder(n)
  AddWindowTimer(#win_Main, #Timer_RefreashThumbnails, 250) ; add a Timer to refreash Thumbnails
  If ExamineDirectory(0, appDatas\folder, "*.*")  
    While NextDirectoryEntry(0)
      If DirectoryEntryType(0) = #PB_DirectoryEntry_File
        ;Taille$ = " (Taille : " + DirectoryEntrySize(0) + ")"
        Select LCase(GetExtensionPart(DirectoryEntryName(0)))
          Case "jpg"
            AddElement(appDatas\media())
            appDatas\media()\mutex=CreateMutex()

            appDatas\media()\name=appDatas\folder+"\"+DirectoryEntryName(0)
            appDatas\media()\image=ListSize(appDatas\media())
            If  LoadImage(ListSize(appDatas\media()),appDatas\media()\name)
              ;ResizeImage(appDatas\media()\image,320,200,#PB_Image_Raw)
              Debug "Ok : "+Str(ListSize(appDatas\media()))+" >"+DirectoryEntryName(0)
            Else
              Debug "Error load :"+DirectoryEntryName(0)
            EndIf
        EndSelect
      EndIf
      
      ;Debug DirectoryEntryName(0)
    Wend
    FinishDirectory(0)
  EndIf
  
  RemoveWindowTimer(#win_Main, #Timer_RefreashThumbnails) ;Not needed anymore to refreash Thumbnails
  
EndProcedure

CreateThread(@loadFolder(),0)

Procedure DrawPreview()
  Protected width.l
  Protected n.l
  Protected nb.l      ;Thumb number on 1 line
  Protected delta.l   ;
  Protected x.l,y.l   ;Coord about a Thumbnail
  Protected nx.l
  StartDrawing(CanvasOutput(#Gdt_Thumbnails))
  Box(0,0,GadgetWidth(#Gdt_Thumbnails),GadgetHeight(#Gdt_Thumbnails),RGB(128,128,128))
  width=appDatas\thumbnailSize
  nb=Int(GadgetWidth(0)/width)
  delta=(GadgetWidth(0)-(nb*width))/nb
  ForEach appDatas\media()
    n=ListIndex(appDatas\media())
    y=Int(n/nb)*width
    nx=(n-Int(n/nb)*nb)
    x=delta/2+nx*width+nx*delta
    Box(x,y,width-2,width-2,#Red)
    
    If IsImage(appDatas\media()\image)
      DrawImage(ImageID(appDatas\media()\image),x,y,width,width)
    EndIf
    DrawText(x,y,Str(n))
  Next
  StopDrawing()
EndProcedure

DrawPreview()

Define event.i
 Repeat
     event = WaitWindowEvent()
     
     Select event
       Case #PB_Event_Timer
         Select EventTimer() 
           Case #Timer_RefreashThumbnails
             DrawPreview()
         EndSelect
       Case #PB_Event_Gadget
         Select EventGadget()
           Case #Gdt_ThumbnailSize 
             appDatas\thumbnailSize=GetGadgetState(#Gdt_ThumbnailSize)
             DrawPreview()
              ;CloseWindow(0)
              ;End  
         EndSelect
            
     EndSelect
   Until event = #PB_Event_CloseWindow


Avatar de l’utilisateur
microdevweb
Messages : 1802
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

Re: Charment images dans un Thread et affichage en même temp

Message par microdevweb »

Bonjour

As-tu cocher l'option Activer la gestion des Threds dans les option du compilateur?
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Re: Charment images dans un Thread et affichage en même temp

Message par Thyphoon »

microdevweb a écrit :Bonjour

As-tu cocher l'option Activer la gestion des Threds dans les option du compilateur?
oui c'est bien coché.
Avatar de l’utilisateur
GallyHC
Messages : 1708
Inscription : lun. 17/déc./2007 12:44

Re: Charment images dans un Thread et affichage en même temp

Message par GallyHC »

Bonjour,

Perso je mettrais toutes les infos dans une liste, après j'envois le thread qui utilise cette même liste.

Cordialement,
GallyHC
Configuration : Tower: Windows 10 (Processeur: i7 "x64") (Mémoire: 16Go) (GeForce GTX 760 - 2Go) - PureBasic 5.72 (x86 et x64)
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Re: Charment images dans un Thread et affichage en même temp

Message par Thyphoon »

GallyHC a écrit :Bonjour,

Perso je mettrais toutes les infos dans une liste, après j'envois le thread qui utilise cette même liste.

Cordialement,
GallyHC
Merci. C'est ce que je viens de faire c'est déjà mieux mais il y a encore des trucs currieux.... je posterai le code quand ça sera satisfaisant :P
Avatar de l’utilisateur
falsam
Messages : 7318
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Charment images dans un Thread et affichage en même temp

Message par falsam »

Sans Thread.

Code : Tout sélectionner

EnableExplicit

UseJPEGImageDecoder()

;-Applications Datas
Structure media
  name.s
  mutex.i
  image.i
EndStructure

Structure appDatas
  folder.s                ;current folder to examine
  exiftoolExe.s           ;path to exifTool executable
  thumbnailSize.l         ;thumbnail Size
  List media.media()     
EndStructure

Global appDatas.appDatas

;- Preferences
#Gdt_ThumbnailSize_Max=320
#Gdt_ThumbnailSize_Min=64
appDatas\folder=PathRequester("Choisissez un répertoire avec des photos", "")

appDatas\thumbnailSize=128

If Not ExamineDirectory(0, appDatas\folder, "*.*")
  Debug "oops souci"
  End
EndIf

;-Windows And Gadget Init

; Windows
#win_Main=0

; Gadget
Enumeration
  #Gdt_Thumbnails
  #Gdt_ThumbnailSize
EndEnumeration

; Timer
Enumeration
  #Timer_loadFolder  
EndEnumeration

Declare DrawPreview()

OpenWindow(#win_Main,0,0,1900,980,"PhotoRanking", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CanvasGadget(#Gdt_Thumbnails, WindowWidth(#win_Main)/6, 10, WindowWidth(#win_Main)/6*4, WindowHeight(#win_Main)-100)
If StartDrawing(CanvasOutput(#Gdt_Thumbnails))
  Box(0,0,GadgetWidth(#Gdt_Thumbnails),GadgetHeight(#Gdt_Thumbnails),RGB(128,128,128))
  StopDrawing()
EndIf

TrackBarGadget(#Gdt_ThumbnailSize, WindowWidth(#win_Main)/6, GadgetY(#Gdt_Thumbnails)+GadgetHeight(#Gdt_Thumbnails), 200, 25, #Gdt_ThumbnailSize_Min, #Gdt_ThumbnailSize_Max)
AddWindowTimer(#win_Main, #Timer_loadFolder, 100)

Procedure loadFolder()
  If Not NextDirectoryEntry(0)
    RemoveWindowTimer(#win_main, #Timer_loadFolder)
    FinishDirectory(0)  
  Else
    
    If DirectoryEntryType(0) = #PB_DirectoryEntry_File
      ;Taille$ = " (Taille : " + DirectoryEntrySize(0) + ")"
      Select LCase(GetExtensionPart(DirectoryEntryName(0)))
        Case "jpg"
          AddElement(appDatas\media())
          appDatas\media()\mutex=CreateMutex()
          
          appDatas\media()\name=appDatas\folder+"\"+DirectoryEntryName(0)
          appDatas\media()\image=ListSize(appDatas\media())
          If  LoadImage(ListSize(appDatas\media()),appDatas\media()\name)
            ;ResizeImage(appDatas\media()\image,320,200,#PB_Image_Raw)
            Debug "Ok : "+Str(ListSize(appDatas\media()))+" >"+DirectoryEntryName(0)
            DrawPreview()
          Else
            Debug "Error load :"+DirectoryEntryName(0)
          EndIf
      EndSelect
    EndIf
  EndIf 
  ;Debug DirectoryEntryName(0)  
EndProcedure

Procedure DrawPreview()
  Protected width.l
  Protected n.l
  Protected nb.l      ;Thumb number on 1 line
  Protected delta.l   ;
  Protected x.l,y.l   ;Coord about a Thumbnail
  Protected nx.l
  
  StartDrawing(CanvasOutput(#Gdt_Thumbnails))
  width=appDatas\thumbnailSize
  nb=Int(GadgetWidth(0)/width)
  delta=(GadgetWidth(0)-(nb*width))/nb
  n=ListIndex(appDatas\media())
  y=Int(n/nb)*width
  nx=(n-Int(n/nb)*nb)
  x=delta/2+nx*width+nx*delta
  Box(x,y,width-2,width-2,#Red)
  
  If IsImage(appDatas\media()\image)
    DrawImage(ImageID(appDatas\media()\image),x,y,width,width)
  EndIf
  DrawText(x,y,Str(n))
  StopDrawing()
EndProcedure

;DrawPreview()

Define event.i
Repeat
  event = WaitWindowEvent(10)
  
  Select event
    Case #PB_Event_Timer
      Select EventTimer() 
        Case #Timer_loadFolder  
          loadFolder()
      EndSelect
    Case #PB_Event_Gadget
      Select EventGadget()
        Case #Gdt_ThumbnailSize 
          appDatas\thumbnailSize=GetGadgetState(#Gdt_ThumbnailSize)
      EndSelect      
  EndSelect
Until event = #PB_Event_CloseWindow
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Re: Charment images dans un Thread et affichage en même temp

Message par Thyphoon »

merci falsam ! intéressant comme méthode ! :)
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Re: Charment images dans un Thread et affichage en même temp

Message par Thyphoon »

Voilà où j'en suis arrivé ! ça fonctionne ^_^ ! Pendant que ça charge vous pouvez changer la taille des previews avec le curseur en bas.
On pourra donc faire autre chose dans l'application pendant que ça charge.
Mais il y a encore un truc que je n'arrive pas a faire. c'est le chargement dans plusieurs Threads en même temps.
l'idéal serait d'avoir toujours 4 threads qui chargent et redimensionnent les images.
pour l'instant j'en ai un seul et je fais un WaitThread sinon tout plante... si quelqu'un a une idée ou une piste ..
Merci d'avance

Code : Tout sélectionner

EnableExplicit

UseJPEGImageDecoder()

;-Applications Datas
Structure media
  name.s
  image.i
EndStructure

Structure appDatas
  folder.s                ;current folder to examine
  exiftoolExe.s           ;path to exifTool executable
  thumbnailSize.l         ;thumbnail Size
  mutexListMedia.i    
  List media.media()     
EndStructure

Global appDatas.appDatas
appDatas\mutexListMedia=CreateMutex()

;- Preferences
#Gdt_ThumbnailSize_Max=320
#Gdt_ThumbnailSize_Min=64
appDatas\folder=PathRequester("Choisissez un répertoire avec des photos", "")

appDatas\thumbnailSize=128

;-Windows And Gadget Init

; Windows
#win_Main=0

; Gadget
Enumeration
  #Gdt_Thumbnails
  #Gdt_ThumbnailSize
EndEnumeration

; Tous nos évènements personnalisés
Enumeration #PB_Event_FirstCustomValue
  #Event_RefreashView
EndEnumeration
OpenWindow(#win_Main,0,0,1900,980,"PhotoRanking", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CanvasGadget(#Gdt_Thumbnails, WindowWidth(#win_Main)/6, 10, WindowWidth(#win_Main)/6*4, WindowHeight(#win_Main)-100)
TrackBarGadget(#Gdt_ThumbnailSize, WindowWidth(#win_Main)/6, GadgetY(#Gdt_Thumbnails)+GadgetHeight(#Gdt_Thumbnails), 200, 25, #Gdt_ThumbnailSize_Min, #Gdt_ThumbnailSize_Max)


Structure imageFit
  width.l
  height.l
  centerWidth.l
  centerHeight.l
EndStructure

Procedure getImageFitSize(*result.imagefit,imgWidth.l,imgHeight.l,contWidth.l,contHeight.l)
  Protected imgRatio.l
  Protected contRatio.l
  imgRatio.l = imgWidth / imgHeight
  contRatio.l = contWidth /contHeight
  If imgRatio<contRatio
    *result\width=imgWidth*contHeight/ImgHeight
    *result\height=contHeight
    *result\centerWidth=(contWidth-*result\width)/2
    *result\centerHeight=0
  Else
    *result\width=contWidth
    *result\height=imgHeight*contWidth/ImgWidth
    *result\centerWidth=0
    *result\centerHeight=(contHeight-*result\height)/2
  EndIf
EndProcedure

Procedure ThreadLoadImage(*data.media)
  Protected imagefit.imagefit
  Debug "Thread:"+GetFilePart(*data\name)
  If IsImage(*data\image)
    FreeImage(*data\image)
  EndIf
  If FileSize(*data\name) 
    
    LoadImage(*data\image,*data\name)
    If IsImage(*Data\image)
      Debug GetFilePart(*data\name)+" OK"
      getImageFitSize(@imagefit,ImageWidth(*data\image),ImageHeight(*data\image),#Gdt_ThumbnailSize_Max,#Gdt_ThumbnailSize_Max)
      ResizeImage(*data\image,imagefit\width,imagefit\height,#PB_Image_Smooth) 
    EndIf 
  Else
    Debug GetFilePart(*data\name)+" ERROR"
  EndIf
EndProcedure

Procedure loadThumbnails(n)
  
  If ExamineDirectory(0, appDatas\folder, "*.*")  
    While NextDirectoryEntry(0)
      If DirectoryEntryType(0) = #PB_DirectoryEntry_File
        ;Taille$ = " (Taille : " + DirectoryEntrySize(0) + ")"
        Select LCase(GetExtensionPart(DirectoryEntryName(0)))
          Case "jpg"
            LockMutex(appDatas\mutexListMedia)
            AddElement(appDatas\media())
            appDatas\media()\name=appDatas\folder+"\"+DirectoryEntryName(0)
            appDatas\media()\image=ListIndex(appDatas\media())
            UnlockMutex(appDatas\mutexListMedia)
        EndSelect
      EndIf
    Wend
    FinishDirectory(0)
  EndIf
  
  Protected NewList tmpMedia.media()
  LockMutex(appDatas\mutexListMedia)
  CopyList(appDatas\media(),tmpMedia())
  UnlockMutex(appDatas\mutexListMedia)
  
  ForEach tmpMedia()
    Debug tmpMedia()\name
    Protected thread
    thread=CreateThread(@ThreadLoadImage(),@tmpMedia())
    WaitThread(thread) ;<-------------------------------------------------Un seul thread je sais pas comment faire pour en avoir 4
    PostEvent(#Event_RefreashView)
  Next
  
EndProcedure

CreateThread(@loadThumbnails(),0)

Procedure drawView()
  Protected width.l
  Protected n.l
  Protected nb.l      ;Thumb number on 1 line
  Protected delta.l   ;
  Protected x.l,y.l   ;Coord about a Thumbnail
  Protected nx.l
  Protected imagefit.imagefit
  
  StartDrawing(CanvasOutput(#Gdt_Thumbnails))
  
  Box(0,0,GadgetWidth(#Gdt_Thumbnails),GadgetHeight(#Gdt_Thumbnails),RGB(128,128,128))
  DrawText(15,15,Str(ElapsedMilliseconds()))
  width=appDatas\thumbnailSize
  nb=Int(GadgetWidth(0)/width)
  delta=(GadgetWidth(0)-(nb*width))/nb
  LockMutex(appDatas\mutexListMedia)
  ForEach appDatas\media()
    n=ListIndex(appDatas\media())
    y=Int(n/nb)*(width+delta)
    nx=(n-Int(n/nb)*nb)
    x=delta/2+nx*width+nx*delta
    Box(x,y,width-2,width-2,RGB(150,150,150))
    
    If IsImage(appDatas\media()\image)
      getImageFitSize(@imagefit,ImageWidth(appDatas\media()\image),ImageHeight(appDatas\media()\image),width-4,width-4)
      DrawImage(ImageID(appDatas\media()\image),x+imagefit\centerWidth,y+imagefit\centerHeight,imagefit\width,imagefit\height)
    EndIf
    DrawText(x,y,Str(n))
  Next
  UnlockMutex(appDatas\mutexListMedia)
  StopDrawing()
EndProcedure

drawview()

Define event.i
Repeat
  event = WaitWindowEvent()
  
  Select event
    Case #Event_RefreashView
      drawView()
    Case #PB_Event_Gadget
      Select EventGadget()
        Case #Gdt_ThumbnailSize 
          appDatas\thumbnailSize=GetGadgetState(#Gdt_ThumbnailSize)
          drawView()
      EndSelect
      
  EndSelect
Until event = #PB_Event_CloseWindow
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Re: Charment images dans un Thread et affichage en même temp

Message par Thyphoon »

Et voilà je touche au but ... mais je sais pas si ma façon de faire est très "system friendly" quelqu'un a un avis sur la question ?
en tout cas les performances sont bien meilleur en chargant avec des Threads ça c'est certain ...
toute amélioration est la bienvenu ..

Code : Tout sélectionner

EnableExplicit

UseJPEGImageDecoder()

;-Applications Datas
Structure media
  name.s
  image.i
EndStructure

Structure appDatas
  folder.s                ;current folder to examine
  exiftoolExe.s           ;path to exifTool executable
  thumbnailSize.l         ;thumbnail Size
  mutexListMedia.i    
  List media.media()     
EndStructure

Global appDatas.appDatas
appDatas\mutexListMedia=CreateMutex()

;- Preferences
#Gdt_ThumbnailSize_Max=320
#Gdt_ThumbnailSize_Min=64
appDatas\folder=PathRequester("Choisissez un répertoire avec des photos .jpg", "")

appDatas\thumbnailSize=128

;-Windows And Gadget Init

; Windows
#win_Main=0

; Gadget
Enumeration
  #Gdt_Thumbnails
  #Gdt_ThumbnailSize
EndEnumeration

; Tous nos évènements personnalisés
Enumeration #PB_Event_FirstCustomValue
  #Event_RefreashView
EndEnumeration
OpenWindow(#win_Main,0,0,1900,980,"PhotoRanking", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CanvasGadget(#Gdt_Thumbnails, WindowWidth(#win_Main)/6, 10, WindowWidth(#win_Main)/6*4, WindowHeight(#win_Main)-100)
TrackBarGadget(#Gdt_ThumbnailSize, WindowWidth(#win_Main)/6, GadgetY(#Gdt_Thumbnails)+GadgetHeight(#Gdt_Thumbnails), 200, 25, #Gdt_ThumbnailSize_Min, #Gdt_ThumbnailSize_Max)

Structure imageFit
  width.l
  height.l
  centerWidth.l
  centerHeight.l
EndStructure

Procedure getImageFitSize(*result.imagefit,imgWidth.l,imgHeight.l,contWidth.l,contHeight.l)
  Protected imgRatio.l
  Protected contRatio.l
  imgRatio.l = imgWidth / imgHeight
  contRatio.l = contWidth /contHeight
  If imgRatio<contRatio
    *result\width=imgWidth*contHeight/ImgHeight
    *result\height=contHeight
    *result\centerWidth=(contWidth-*result\width)/2
    *result\centerHeight=0
  Else
    *result\width=contWidth
    *result\height=imgHeight*contWidth/ImgWidth
    *result\centerWidth=0
    *result\centerHeight=(contHeight-*result\height)/2
  EndIf
EndProcedure
  Structure proc
    thread.i
    image.i
    name.s
  EndStructure 

Procedure ThreadLoadImage(*data.proc)
  Protected imagefit.imagefit
  Debug "Thread:"+GetFilePart(*data\name)
  If IsImage(*data\image)
    FreeImage(*data\image)
  EndIf
  If FileSize(*data\name) 
    
    LoadImage(*data\image,*data\name)
    If IsImage(*Data\image)
      Debug GetFilePart(*data\name)+" OK"
      getImageFitSize(@imagefit,ImageWidth(*data\image),ImageHeight(*data\image),#Gdt_ThumbnailSize_Max,#Gdt_ThumbnailSize_Max)
      ResizeImage(*data\image,imagefit\width,imagefit\height,#PB_Image_Smooth) 
    EndIf 
  Else
    Debug GetFilePart(*data\name)+" ERROR"
  EndIf
EndProcedure

Procedure loadThumbnails(z.l)
  
  If ExamineDirectory(0, appDatas\folder, "*.*")  
    While NextDirectoryEntry(0)
      If DirectoryEntryType(0) = #PB_DirectoryEntry_File
        ;Taille$ = " (Taille : " + DirectoryEntrySize(0) + ")"
        Select LCase(GetExtensionPart(DirectoryEntryName(0)))
          Case "jpg"
            LockMutex(appDatas\mutexListMedia)
            AddElement(appDatas\media())
            appDatas\media()\name=appDatas\folder+"\"+DirectoryEntryName(0)
            appDatas\media()\image=ListIndex(appDatas\media())
            UnlockMutex(appDatas\mutexListMedia)
        EndSelect
      EndIf
    Wend
    FinishDirectory(0)
  EndIf
  
  Protected NewList tmpMedia.media()
  LockMutex(appDatas\mutexListMedia)
  CopyList(appDatas\media(),tmpMedia())
  UnlockMutex(appDatas\mutexListMedia)
  

  
  Protected Dim proc.proc(10)
  Protected n.l=0
  Protected maxThread.l=8
  
  ForEach tmpMedia()
    
      ;this loop limit thread number to maxThread
      Repeat
        n=n+1
        Delay(1)
        If n>maxThread:n=1:EndIf 
      Until IsThread(proc(n)\thread)=0 ; Always a Thread if finished you can add another

      proc(n)\image=tmpMedia()\image
      proc(n)\name=tmpMedia()\name
      Debug ">>>>>>>>>>>>>>>>>>>"+Str(n)+" "+Str(proc(n)\image)+proc(n)\name
      proc(n)\thread=CreateThread(@ThreadLoadImage(),@proc(n))

    If n=maxThread:PostEvent(#Event_RefreashView):EndIf
  Next
  ;Wait all Thread are finished
  For n=1 To maxThread
    WaitThread(proc(n)\thread)
  Next
  
EndProcedure

CreateThread(@loadThumbnails(),0)

Procedure drawView()
  Protected width.l
  Protected n.l
  Protected nb.l      ;Thumb number on 1 line
  Protected delta.l   ;
  Protected x.l,y.l   ;Coord about a Thumbnail
  Protected nx.l
  Protected imagefit.imagefit
  
  StartDrawing(CanvasOutput(#Gdt_Thumbnails))
  
  Box(0,0,GadgetWidth(#Gdt_Thumbnails),GadgetHeight(#Gdt_Thumbnails),RGB(128,128,128))
  DrawText(15,15,Str(ElapsedMilliseconds()))
  width=appDatas\thumbnailSize
  nb=Int(GadgetWidth(0)/width)
  delta=(GadgetWidth(0)-(nb*width))/nb
  LockMutex(appDatas\mutexListMedia)
  ForEach appDatas\media()
    n=ListIndex(appDatas\media())
    y=Int(n/nb)*(width+delta)
    nx=(n-Int(n/nb)*nb)
    x=delta/2+nx*width+nx*delta
    If y+width>0 And y<GadgetHeight(#Gdt_Thumbnails)
    Box(x,y,width-2,width-2,RGB(150,150,150))
    
    If IsImage(appDatas\media()\image)
      getImageFitSize(@imagefit,ImageWidth(appDatas\media()\image),ImageHeight(appDatas\media()\image),width-4,width-4)
      DrawImage(ImageID(appDatas\media()\image),x+imagefit\centerWidth,y+imagefit\centerHeight,imagefit\width,imagefit\height)
    EndIf
    DrawText(x,y,Str(n))
    EndIf 
  Next
  UnlockMutex(appDatas\mutexListMedia)
  StopDrawing()
EndProcedure

drawview()

Define event.i
Repeat
  event = WaitWindowEvent()
  
  Select event
    Case #Event_RefreashView
      drawView()
    Case #PB_Event_Gadget
      Select EventGadget()
        Case #Gdt_ThumbnailSize 
          appDatas\thumbnailSize=GetGadgetState(#Gdt_ThumbnailSize)
          drawView()
      EndSelect
      
  EndSelect
Until event = #PB_Event_CloseWindow

Répondre