Lire la taille d'une image d'un fichier jpeg (très rapide)

Soyez le premier à donner votre avis sur cette source.

Vue 10 909 fois - Téléchargée 716 fois

Description

petit didacticiel sur le entpete et maker des fichier jpeg.
y a plus q"à copier-coller pour améliore grandement la vitesse d'affichage des fichier jpeg.
D'habitude il faut 'peindre' 2 images (une pour interroger la taille, l'autre pour l'affichage). Là, y en a s'une est c'est 2 fois plus rapide

Source / Exemple :


Private Sub Dir1_Change()
    File1.Path = Dir1.Path
End Sub

Private Sub Drive1_Change()
    Dir1.Path = Drive1.Drive
End Sub

Private Sub File1_Click()
    Dim hauteur As Variant
        Dim largeur As Variant
        Dim image As String
        Dim a0 As Byte
        Dim a1 As Byte
        Dim a10 As Long
        
    If File1.ListCount > 0 Then
    
        For i = 0 To File1.ListCount - 1
            If File1.Selected(i) Then
                If Right(File1.Path, 1) <> "\" Then
                    image = File1.Path & "\" & File1.List(i)
                Else
                    image = File1.Path & File1.List(i)
                End If
            End If
        Next i
    End If

        
        ' ouverture du fichier
        ' c'est 5 car dans mon autre source 1 et 2 était pris
        Open image For Binary As #5 Len = 1024
        
        ' les markers sont de type FFXX suivi de 2 octets, sa taille
        ' on trouve normalement
        ' en 1 : FFD0 le SOI marker, sa taille est donc en octet 3
        ' en 2 FFE0 (jfif marker)
        ' ensuite FFDB(quantizise)/FFEC(?)/FFEE(commentaire)
        ' enfin le FFCx (avec x=0,1,2,3,5,6,7,9,a,b,d,e,f) les autes sont pas bons
        ' c'est le début de l'image, ke x, c'est le début de codage
        ' puis FFC4 (table de huffman) et le FFDA (start odf scan)
        ' et à la fin FFD9 : fin d'image
        ' le nombre de marker est variable, donc fo chercher
        Get #5, 1, a0
        Get #5, 2, a1
        ' vérification de l'entête, le jpg c'est FFD8
        If (a0 = 255 And a1 = 216) Then
            a10 = 3
            For i = 1 To 10
                ' a10 pointe sur l'entête du marker
                ' la boucle limitée à 10 recherches permet que ça plante pas sur 'EOF' dès qu'un fichier est pas bon
                Get #5, a10, a0
                Get #5, a10 + 1, a1
                If (a1 = 192 Or a1 = 193 Or a1 = 194 Or a1 = 195 Or a1 = 197 Or a1 = 198 Or a1 = 199 Or a1 = 201 Or a1 = 202 Or a1 = 203 Or a1 = 205 Or a1 = 206 Or a1 = 207) Then
                    ' par exemple FF C0 00 11 08 05 E0 03 E8
                    ' FF C0 : début de frame
                    ' 00 11 : la taille de ce marker (17 octets), a10 pointe sur 00
                    ' 08 : P (sample precision = 8 quasi toujours)
                    ' 05 E0 : Y (hauteur)
                    ' 03 E8 : X (laurgeur)
                    Get #5, a10 + 5, a0
                    Get #5, a10 + 6, a1
                    ' a10 et hauteur sont de long, a1 et a2 des bytes
                    ' le & permet de pas générer d'erreur en dessus de 32736
                    ' le calcul se fait en long comme ça au lieu de interger par défaut
                    hauteur = 256& * a0 + a1
                    Get #5, a10 + 7, a0
                    Get #5, a10 + 8, a1
                    largeur = 256& * a0 + a1
                    i = 20
                    'MsgBox ("H=" + Str(hauteur) + "- L=" + Str(largeur))
                End If
                Get #5, a10 + 2, a0
                Get #5, a10 + 3, a1
                ' a10 : ancien offset
                ' a0*256+a1 : offset du à la taille du marker
                ' et le 2, c'est l'offset pour la taille de l'entête du marker FFXX
                a10 = 2& + a10 + a0 * 256& + a1
            Next i
            Label1 = "H=" + Str(hauteur) + " - L=" + Str(largeur)
        Else
            Label1 = "En tête non standard" + Str(a0) + Str(a1)
        End If
        Close #5
        ' si i= 11,  pas de frame valide trouvée
        ' si i=21, frame valide touvée
        

        If (i = 11) Then
            Label1 = "pas de frame valable trouvée ou plus de 10 marker"
        End If
        

End Sub

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

pascal16m
Messages postés
67
Date d'inscription
jeudi 19 juin 2003
Statut
Membre
Dernière intervention
13 juillet 2019
-
Merci, moi aussi je l'avais fait dans le but d'apprendre.

Avec VB6, on peut lire la taille d'une image, mais pour cela, il doit d'abord la charger, ce qui est très lent.
Ce bout de code m'a permis ensuite de faire un comparateur sans ouverture d'image. Puis un logiciel de classement d'image. Le classeur incorporait une routine qui copiait les images impossibles à ouvrir dans un répertoire. Les images récalcitrantes peuvent être parfois ouverte avec un logiciel tierce d'édition, on modifie un petit truc, on enregistre et l'image est bonne.

Avec VB10, le chargement d'une image est rapide, donc le code ne permet plus vraiment d'accélérer.
patriceB2
Messages postés
10
Date d'inscription
mardi 5 janvier 2010
Statut
Membre
Dernière intervention
17 novembre 2011
-
Je disposais d'une image que LOADPICTURE ne pouvait lire. Impossible aussi de gérér une erreur (plantage complet de VB6). Ce programme détecte que l'image a un problème!! Bravo donc! Bravo aussi à la démarche de ce genre de recherche pour comprendre, plutôt que d'utiliser des utilitaires tout fait, même s'ils sont plus simples. Il est bon de comprendre aussi....
pascal16m
Messages postés
67
Date d'inscription
jeudi 19 juin 2003
Statut
Membre
Dernière intervention
13 juillet 2019
-
Merci Florian,
le but de ce code était de voir un peu comment était fait le Jpeg.
en rechercanht sur internet, j'avais trouvé pas mal de dossiers assez épais sur la structure jpeg.
J'avais mi ce bout de code pour en faire un résumé.
La boucle 1 à 10 est pas terrible, mais ça évite d'avoir plus de ligne de code pour gérer les images HS (et c'est pas rare sur les images téléchargées) que pour afficher 2 chiffres.


pour les fonctions :
Label1.Caption = "Hauteur : " & LoadPicture(chemin).Height
Label2.Caption = "Largeur : " & LoadPicture(chemin).Width
J'ai pas trop pigé pourquoi je ne retombais pas sur la taille en twips, mais c'est bien ça en théorie. Sauf que pour afficher deux nombre, il charge deux fois l'image en mémoire. C'est tres long, surtout sur de grandes images.
Vu que windows affiche les excifs, il doit y avoir des fonctions API rapides pour le faire rapidement.
L'avantage avec ce bout de code, c'est de ne lire que le début de l'image et une seule fois et c'est rapide.
TFlorian
Messages postés
194
Date d'inscription
dimanche 3 mars 2002
Statut
Membre
Dernière intervention
19 décembre 2005
3 -
GÉNIAL !
J'ai réussi à récupérer des images suite à un formatage d'un disque...
Après la récupération des fichiers les photos mes images ne faisaient plus que 160 x 120 au lieu de 1600 x 1200 ..
Grâce a ton code j'ai compris la structure du JPEG et j'ai réussi à le décortiquer pour récupérer mes images HD ..
(Lorsque le fichier n'avait pas été trop détruit dut à une fragmentation trop importante du disque.. )

D'un point de vue perf, je préfère ta méthode que les méthodes toutes faire car on ne lit qu'une seule foi le fichier (sur le disque) alors que les APIs des Windows comme on les appels plusieurs fois, font plusieurs accès disque

Encore merci, et bonne prog a tous ;-)

TFlorian
pascal16m
Messages postés
67
Date d'inscription
jeudi 19 juin 2003
Statut
Membre
Dernière intervention
13 juillet 2019
-
Ca c'est du deterrage
quand une photo est redimentionnée lors de son ouverture pour loger dans un controle picture ou image, il me semble qu'il te donne la taille de l'image redimentionnée.

Je pense qu'il existe une fonction toute faite qui donne toujours la bonne taille, mais je la connais pas.

J'ai quelques images où il y a un décalage d'1 ou 2 octets à l'intérieur du fichier, je sais pas pourquoi, et la fonction se trompe

sinon, lequel des deux se trompe ?

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.