IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VB.NET Discussion :

Téléchargement, conversion et sauvegarde d'images multiples avec progressbar


Sujet :

VB.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    158
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2006
    Messages : 158
    Par défaut Téléchargement, conversion et sauvegarde d'images multiples avec progressbar
    Bonjour,

    Je dois télécharger plusieurs centaines d'images, les convertir en .png puis les sauver en local.
    J'ai d'abord tenté ceci (mes connaissances sont ce qu'elles sont, merci pour votre compréhension ;-)):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    For i As Integer = 1 To 200
                Dim img As String = "https://lalydo.files.wordpress.com/2010/10/for-the-birds.jpg"
                Dim name As String = "newname" & i
                Dim bitmap As New BitmapImage()
                bitmap.BeginInit()
                bitmap.UriSource = New Uri(img)
                bitmap.EndInit()
     
                Dim encoder As PngBitmapEncoder = New PngBitmapEncoder()
                encoder.Frames.Add(BitmapFrame.Create(bitmap))
                Using filestream = New FileStream(destinationFolder & "\" & name & ".png", FileMode.Create)
                    encoder.Save(filestream)
                End Using
    Next
    ...pour me rendre compte que 200 images sont bel et bien créées..mais vide.

    J'imagine que c'est parce que l'image n'a pas fini de se télécharger que l'on passe déjà à l'image suivante!!?

    J'essaie alors de déporter le traitement dans un sub qui se lance une fois que l'image a fini d'être téléchargée

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    Imports System.IO
    Class MainWindow
        Dim destinationFolder As String = "C:\Test"
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button1.Click
            If Not Directory.Exists(destinationFolder) Then Directory.CreateDirectory(destinationFolder)
            CollectBitmap()
        End Sub
        Sub CollectBitmap()
            For i As Integer = 1 To 200
                Dim img As String = "https://lalydo.files.wordpress.com/2010/10/for-the-birds.jpg"
                Dim name As String = "newname" & i
                Dim bitmap As New BitmapImage()
                bitmap.BeginInit()
                bitmap.UriSource = New Uri(img)
                bitmap.EndInit()
                '
                SaveImage(bitmap, name)
            Next
        End Sub
        Sub SaveImage(ByVal bitmap As BitmapImage, ByVal name As String)
            AddHandler bitmap.DownloadCompleted, New EventHandler(Sub(sender As Object, args As EventArgs)
                                                                      Dim encoder As PngBitmapEncoder = New PngBitmapEncoder()
                                                                      encoder.Frames.Add(BitmapFrame.Create(DirectCast(sender, BitmapImage)))
                                                                      Using filestream = New FileStream(destinationFolder & "\" & name & ".png", FileMode.Create)
                                                                          encoder.Save(filestream)
                                                                      End Using
                                                                      Label1.Content = name & " converted and saved"
                                                                  End Sub)
        End Sub
    End Class
    Est-ce la bonne facon de faire, svp?
    Si je comprends bien, il y a donc plusieurs (dizaines sans doute) d'images dont le traitement est lancé concurremment!?
    Ne serais-ce pas mieux de télécharger la première, de faire le traitement, de sauver, puis de passer à la suivante?
    Et surtout: comment pourrais je faire pour voir l'évolution du téléchargement avec une progressbar (et déjà s'assurer que Label1.Content est mis à jour, ce qui n'est pas le cas jusqu'à présent)

    Merci pour tout aide

  2. #2
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 197
    Par défaut
    le plus performant serait d'avoir quelques threads de téléchargements, quelques threads de conversion et un thread d'écriture

    après rien ne sert de faire une usine à gaz pour gagner 5% de temps

    donc il reste soit un thread pour tout faire, soit un thread de téléchargement et un de conversion/enregistrement
    après il est aussi interressant d'utiliser la POO

    je veux bien expliciter un peu plus, mais je ne comprends pas ton code, peut etre en as tu retiré un bout parce que là tu vas télécharger 200x le même fichier vu qu'il est mis en dur
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    158
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2006
    Messages : 158
    Par défaut
    je veux bien expliciter un peu plus, mais je ne comprends pas ton code, peut etre en as tu retiré un bout parce que là tu vas télécharger 200x le même fichier vu qu'il est mis en dur
    Oui, je veux bien que tu explicites un peu plus!! ;-)
    Et oui, la ligne 'Dim img As String = "https://lalydo.files.wordpress.com/2010/10/for-the-birds.jpg"' est juste là pour symboliser le traitement de plusieurs images qui seront bien différentes dans le code final!!

  4. #4
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 197
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    Public Class Form1
     
        Private _ImageDls As New List(Of ImageDl) ' une collection qui va contenir tout ce qu'il y a à traiter
     
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
     
            _ImageDls.Add(New ImageDl("http://site.fr/image1.jpg"))
            _ImageDls.Add(New ImageDl("http://site.fr/image2.jpg")) ' remplissage (ailleurs si nécessaire)
            '...
     
            Me.ProgressBar1.Value = 0
            Me.ProgressBar1.Maximum = _ImageDls.Count
            Dim th As New System.Threading.Thread(AddressOf Telechargement)
            th.IsBackground = True
            th.Start()
        End Sub
     
        Private Sub Telechargement()
            For Each i In _ImageDls
                If Not i.DL() Then
                    'ca a buggé, à toi de voir ce que tu veux faire
                End If
                Me.Invoke(New Action(AddressOf ReportProgressPlusUn)) ' un controle ne peut etre modifié depuis un autre thread, .invoke sert à "revenir" temporairement sur le thread principal
            Next
        End Sub
     
        Private Sub ReportProgressPlusUn()
            Me.ProgressBar1.Value += 1
        End Sub
     
    End Class
     
     
     
    Public Class ImageDl ' classe qui contient l'url et s'occupe du téléchargement
     
        Public Sub New(url As String)
            Me.Url = url
        End Sub
     
        Public Property Url As String ' contient http://... .jpg
     
        Public Function DL()
            Try
                Using wc As New System.Net.WebClient
                    Dim octets = wc.DownloadData(Me.Url)
                    Using m As New System.IO.MemoryStream(octets)
                        Using imgJpg = System.Drawing.Image.FromStream(m)
                            imgJpg.Save("je te laisse trouver comment tu veux définir l'emplacement de destination et le nom du fichier", System.Drawing.Imaging.ImageFormat.Png) ' conversion et enregistrement
                        End Using
                    End Using
                End Using
                Return True
            Catch ex As Exception
                '
                Return False
            End Try
        End Function
     
    End Class
    using / end using sert à vider la mémoire quand on utilise plus une variable
    il n'est possible que les classes qui gèrent des objets non managés (= géré par windows plutot que par .net) (comme les images, les connexions sql/tcp, les controles ...)

    on peut encore faire mieux mais déjà ca déporte un peu le traitement
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  5. #5
    Membre Expert
    Avatar de wallace1
    Homme Profil pro
    Administrateur systèmes
    Inscrit en
    Octobre 2008
    Messages
    1 966
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Administrateur systèmes
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 966
    Billets dans le blog
    7
    Par défaut
    Bonjour,

    Ce sujet pourrait certainement t'éclairer :

    http://www.developpez.net/forums/d15...ment-fichiers/

    Aucun soucis à se faire la source est commentée et à jour ici :

    http://3dotdevcoder.blogspot.fr/2015...s-en-file.html

    Il te faudra l'adapter à tes besoins, si tu veux éditer chaque image à la fin de chaque téléchargement c'est ici que ça se passe :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
      Private Sub DownloadFiles_DownloadFileCompleted(sender As Object, e As AsyncCompletedEventArgs) Handles wc.DownloadFileCompleted
            ' On masque cet event côté UI car il permet de savoir à quel moment se termine la fin du téléchargement de chaque fichier !
            If Not e.UserState Is Nothing Then
                Dim Infos = DirectCast(e.UserState, DownloadInfos)
                If e.Error IsNot Nothing Then
                    results.Add(New DownloadResult(Infos.Url, DownloadResult.State.Erreur, e.Error.ToString))
                Else
    ' La modification peut se faire ici car la structure infos permet de récupérer le dossier d'enregistrement de destination, l'url (le nom de l'image+ son extension)
                    results.Add(New DownloadResult(Infos.Url, DownloadResult.State.Completed, "Completed"))
                End If
            End If
     
            DownloadFiles()
        End Sub
    Bonne lecture.

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    158
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2006
    Messages : 158
    Par défaut
    Pol63, wallace1,

    Un grand merci pour votre réponse!! Je me penche sur chacune d'elles immédiatement!!
    Dans l’entre temps, j'avais fait des test avec Webclient.DownloadFileAsync qui semblait bien marcher:
    1 progress bar générale, une autre pour téléchargement individuel...mais pas de conversion en .png
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    Imports System.IO
    Imports System.Net
    Imports System.ComponentModel
    Class MainWindow
        Private _destPath$ = "C:\Test"
        Private files As New List(Of String)
        Private total As Integer
        Private Sub MainWindow_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
            If Not Directory.Exists(_destPath) Then Directory.CreateDirectory(_destPath)
            For i As Integer = 1 To 100
                files.Add("https://lalydo.files.wordpress.com/2010/10/for-the-birds.jpg")
            Next
            total = files.Count()
        End Sub
        Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
            If files.Count > 0 Then
                DownloadFileEx(files(0))
            End If
        End Sub
        Private Sub DownloadFileEx(ByVal file)
            Dim client As New WebClient()
            AddHandler client.DownloadProgressChanged, AddressOf DownloadFileEx_DownloadProgressChanged
            AddHandler client.DownloadFileCompleted, AddressOf DownloadFileEx_DownloadFileCompleted
            Label1.Content = "Items remaining: " & files.Count - 1
            client.DownloadFileAsync(New Uri(file), _destPath & "\" & "test")
        End Sub
        Private Sub DownloadFileEx_DownloadProgressChanged(ByVal sender As Object, ByVal e As DownloadProgressChangedEventArgs)
            ProgressBar1.Value = e.ProgressPercentage
            ProgressBar2.Value = total - files.Count + 1
        End Sub
        Private Sub DownloadFileEx_DownloadFileCompleted(ByVal sender As Object, ByVal e As AsyncCompletedEventArgs)
            Dim cl As WebClient = CType(sender, WebClient)
            If e.Error IsNot Nothing Then
                MsgBox(e.Error.ToString)
            End If
            files.RemoveAt(0)
            cl.Dispose()
            If files.Count > 0 Then
                DownloadFileEx(files(0))
            Else
                Label1.Content = "Download finished"
            End If
        End Sub
    End Class
    J'ai donc essayé, pour faire la conversion en png, d'utiliser un WebClient.OpenReadAsync
    Ca semble marcher, mais par contre je ne vois pas comment piloter alors la progressbar pour chaque élément!!
    Pourriez-vous me dire si mon code tient la route...et comment piloter la progressbar pour chaque élément, svp??

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    Imports System.IO
    Imports System.Net
    Imports System.ComponentModel
    Imports System.Windows.Resources
     
    Class MainWindow
        Private _destPath$ = "C:\Test"
        Private files As New List(Of String)
        Private total As Integer
        Private Sub MainWindow_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
            If Not Directory.Exists(_destPath) Then Directory.CreateDirectory(_destPath)
            For i As Integer = 1 To 100
                files.Add("https://lalydo.files.wordpress.com/2010/10/for-the-birds.jpg")
            Next
            total = files.Count
        End Sub
        Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
            If files.Count > 0 Then
                DownloadFileEx(files(0))
            End If
        End Sub
        Private Sub DownloadFileEx(ByVal file)
            Dim client As New WebClient()
            AddHandler client.DownloadProgressChanged, AddressOf DownloadProgressChanged
            AddHandler client.OpenReadCompleted, AddressOf DownloadFileCompleted
            Label1.Content = "Items remaining: " & files.Count - 1
            client.OpenReadAsync(New Uri(file))
        End Sub
        Private Sub DownloadProgressChanged(ByVal sender As Object, ByVal e As DownloadProgressChangedEventArgs)
            ProgressBar1.Value = e.ProgressPercentage
            ProgressBar2.Value = total - files.Count + 1
        End Sub
        Private Sub DownloadFileCompleted(ByVal sender As Object, ByVal e As OpenReadCompletedEventArgs)
            Dim sri As Stream = TryCast(e.Result, Stream)
            Dim bitmap As New BitmapImage()
            bitmap.BeginInit()
            bitmap.CacheOption = BitmapCacheOption.OnLoad 'forces the loading of image into memory during EndInit
            bitmap.StreamSource = sri
            bitmap.EndInit()
            sri.Close()
     
            Dim encoder As PngBitmapEncoder = New PngBitmapEncoder()
            encoder.Frames.Add(BitmapFrame.Create(bitmap))
            Using filestream = New FileStream(_destPath & "\" & "test", FileMode.Create)
                encoder.Save(filestream)
            End Using
     
            files.RemoveAt(0)
            If files.Count > 0 Then
                DownloadFileEx(files(0))
            Else
                Label1.Content = "Download finished"
            End If
        End Sub
    End Class

Discussions similaires

  1. [AJAX] Sauvegarde d'image canvas avec Ajax et PHP
    Par coincoin22 dans le forum jQuery
    Réponses: 8
    Dernier message: 09/03/2013, 22h56
  2. Sauvegarder une image cairo avec gtk
    Par dongonis38 dans le forum GTK+ avec C & C++
    Réponses: 5
    Dernier message: 07/10/2010, 16h01
  3. sauvegarder une image traiter avec flash
    Par dawla123 dans le forum ActionScript 3
    Réponses: 3
    Dernier message: 20/05/2008, 11h21
  4. Sauvegarde une image jpeg avec la qualité
    Par morgan47 dans le forum VB.NET
    Réponses: 1
    Dernier message: 19/02/2007, 10h48
  5. Réponses: 8
    Dernier message: 15/10/2006, 18h45

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo