Avec ce code , vous pouvez recuperer facilement les dimension Width et Height reels d'une image Jpeg sans passer par un PictureBox ou un StdPicture ou Cdib, meme pas d'api , rien.
Copiez simplement ce ptit bout de code dans un module
Utilisation :
Private Sub Command1_Click()
Dim o As SIZE
Dim ErrorH As Integer
ErrorH = JpgSize("c:\surf41.jpg", o)
If ErrorH = 0 Then
Text1 = o.cx & " x " & o.cy
Else
MsgBox GetErrorString(ErrorH)
End If
End Sub
Source / Exemple :
Option Base 0
Option Explicit
'RogerStudio
'JpgSize
'Fonction qui recupere la dimension d'un image JPG rapidement
'Sans control Picture ou CDib
'Simple ouvertur du fichier , recherche des valeurs dans l'entete.
'Entrée : Nom et chemin complet du fichier Jpg
' Dimension de structure SIZE
'Sortie : NULL si Reussi
' >0 en cas d'erreur
'Reference Doc : http://www.landscapeimage.com/ThumbHTML/help/exif_file_format.html
'http://www.w3.org/Graphics/JPEG/jfif3.pdf
'Travail perso de recherche sur le format JFIF Version 1.1 et 1.2
Private PHeight As Long, PWidth As Long 'Resultats des recherches
Private Free As Integer 'numero de fichier libre
Private Temp() As Byte, Temp1() As Byte
Private MarkerLenght As Integer 'Longeur du markeur
Private IsJpg(1) As Byte '2 Premiers octets pour verifier l'entet du Jpg
Private AppMarker(1) As Byte 'Structure du marker (FFD8 FFD0 FFC0 FFE1 FFE0 .... FFxx)
Private MarkerOffset As Long 'Offset du marker
Private Mark As Integer
Private Origin As Long 'Pour la boucle Get
Private NotFound As Boolean
Private LngS As String * 4 'Phrase fixe de 4 octets pour la mise en forme Hexa
Private IntS1 As String * 2 ' // de 2 octets
Private IntS2 As String * 2 ' // //
Private IntS3 As String * 2 ' // //
Private IntS4 As String * 2 ' // //
Private X1 As Long 'Boucles
'Psd format
Private LngS1 As String * 8 'Phrase fixe de 8 octets pour la mise en forme Hexa
Private PsdSignature As Long
Private PsdVersionFormat As Integer
Private PsdRows As Long
Private PsdColumns As Long
Public Type SIZE
cx As Long
cy As Long
End Type
Public Function PhotoShopFileSize(SzFileName As String, ByRef Dimension As SIZE) As Integer
On Error GoTo Fin
If ExistFile(SzFileName) = False Then PhotoShopFileSize = 1: Exit Function
Free = FreeFile
Open SzFileName For Binary As #Free
Get #Free, , PsdSignature
'Verifie que l'entete est bien "8BPS"
If Hex(PsdSignature) <> "53504238" Then PhotoShopFileSize = 5: Close #Free: Exit Function
Get #Free, , PsdVersionFormat
'Verifie que la version est a 1
If Hex(PsdVersionFormat) <> "100" Then PhotoShopFileSize = 6: Close #Free: Exit Function
'debu a offset 15
Seek #Free, 15
ReDim Temp(3)
Get #Free, , Temp
IntS1 = String(2 - Len(Hex(Temp(0))), "0") & Hex(Temp(0))
IntS2 = String(2 - Len(Hex(Temp(1))), "0") & Hex(Temp(1))
IntS3 = String(2 - Len(Hex(Temp(2))), "0") & Hex(Temp(2))
IntS4 = String(2 - Len(Hex(Temp(3))), "0") & Hex(Temp(3))
LngS1 = IntS1 & IntS2 & IntS3 & IntS4
PHeight = Val("&H" & LngS1)
Get #Free, , Temp
IntS1 = String(2 - Len(Hex(Temp(0))), "0") & Hex(Temp(0))
IntS2 = String(2 - Len(Hex(Temp(1))), "0") & Hex(Temp(1))
IntS3 = String(2 - Len(Hex(Temp(2))), "0") & Hex(Temp(2))
IntS4 = String(2 - Len(Hex(Temp(3))), "0") & Hex(Temp(3))
LngS1 = IntS1 & IntS2 & IntS3 & IntS4
PWidth = Val("&H" & LngS1)
Dimension.cx = PWidth
Dimension.cy = PHeight
PhotoShopFileSize = 0
Fin:
Close #Free
If Err Then PhotoShopFileSize = Err.Number
End Function
Public Function JpgSize(SzFileName As String, ByRef Dimension As SIZE) As Integer
On Error GoTo Fin
'Verifie que le fichier existe
If ExistFile(SzFileName) = False Then JpgSize = 1: Exit Function
Free = FreeFile
Open SzFileName For Binary As #Free
Get #Free, , IsJpg 'FFD8 = Fichier Jpg
If Hex(IsJpg(0)) <> "FF" And Hex(IsJpg(1)) <> "D8" Then JpgSize = 2: GoTo Fin
'LE fichier est bien un Jpg
'On recupere le premier marker
Get #Free, , AppMarker 'Marker FFE0 ou FFE1 'Les autres fichiers ne sont pas geré pour le moment
'Le marker est suivi de sa longeur 2octets
ReDim Temp(1)
Get #Free, , Temp
MarkerLenght = ("&H" & Hex(Temp(0)) & Hex(Temp(1)))
MarkerOffset = 5 'C'est obligatoirement le premier marker
'A quel genre de jpg a t'on affaire ? avec Exif ou sans Exif ?
'FFE0 Sans exif , entete simple JFIF
'FFE1 Avec exif, entete Exif
If Hex(AppMarker(1)) = "E0" Then 'JFIF
'Fichier Jfif
'verifie que c'est bien un Jfif, Recupere les 5 prochain bytes
'ca doit etre 4A 46 49 46 00
' J F I F 0
ReDim Temp(4)
Get #Free, , Temp
If Hex(Temp(0)) <> "4A" Then JpgSize = 3: GoTo Fin
If Hex(Temp(1)) <> "46" Then JpgSize = 3: GoTo Fin
If Hex(Temp(2)) <> "49" Then JpgSize = 3: GoTo Fin
If Hex(Temp(3)) <> "46" Then JpgSize = 3: GoTo Fin
If Hex(Temp(4)) <> "0" Then JpgSize = 3: GoTo Fin
ReDim Temp(1)
ReDim Temp1(1)
NotFound = True
'a l 'offset "MArkerLenght" , on doit avoir un FF xx puis FFxx ....
'Rechercher le marker FFC0
Do
Seek #Free, MarkerLenght + MarkerOffset
'Offset en cours =MarkerLenght + MarkerOffset
Get #Free, , Temp 'recupere le marker
MarkerOffset = Seek(1)
Get #Free, , Temp1 'recupere la taille du marker
MarkerLenght = ("&H" & Hex(Temp1(0)) & Hex(Temp1(1)))
If Hex(Temp(0)) = "FF" And Hex(Temp(1)) = "C0" Then NotFound = False
Loop While NotFound
'Marker FFC0 trouvé ! cool
ReDim Temp(0)
Get #Free, , Temp 'je ne sais pas a quoi correspond ce byte , c'est souvent 8 !
'mais bon passons
ReDim Temp(1)
'Ici on recupere la hauteur
Get #Free, , Temp
IntS1 = String(2 - Len(Hex(Temp(0))), "0") & Hex(Temp(0))
IntS2 = String(2 - Len(Hex(Temp(1))), "0") & Hex(Temp(1))
LngS = IntS1 & IntS2
PHeight = Val("&H" & LngS)
'et ici la longeur
Get #Free, , Temp
IntS1 = String(2 - Len(Hex(Temp(0))), "0") & Hex(Temp(0))
IntS2 = String(2 - Len(Hex(Temp(1))), "0") & Hex(Temp(1))
LngS = IntS1 & IntS2
PWidth = Val("&H" & LngS)
JpgSize = 0
'Fichier JFIF normal terminé
'Retourne 0 (pas d'erreur)
'Et les valeurs dans la streucture
Dimension.cx = PWidth
Dimension.cy = PHeight
ElseIf Hex(AppMarker(1)) = "E1" Then 'Exif
'Exif presents , il faut chercher dans les marques exif ,
'car au markeur FFC0 , c'est la dimension de la miniaturre . et non de l'image
'Le numero de case est : A002 pour la longuer
'Le numero de case est : A003 pour la hauteur
'****************
'Codage Motorola ou Intel ?
'**************
'Recherche du marker "Exif"
ReDim Temp(5)
Origin = 0
NotFound = True
Do
Origin = Origin + 1
Get #1, Origin, Temp
If Temp(0) = 69 And Temp(1) = 120 And Temp(2) = 105 And Temp(3) = 102 And Temp(4) = 0 And Temp(5) = 0 Then NotFound = False
Loop While NotFound
Origin = Origin + 6
ReDim Temp(1)
Get #1, Origin, Temp
Debug.Print Temp(0)
Debug.Print Temp(1)
Codage = None
If Temp(0) = 77 And Temp(1) = 77 Then Codage = Motorola
If Temp(0) = 73 And Temp(1) = 73 Then Codage = Intel
If Codage = None Then JpgSize = 5: GoTo Fin
Dim Marke As Integer
If Codage = Intel Then Marke = &HA002
If Codage = Motorola Then Marke = &H2A0
Origin = 1
NotFound = True
Do
'Recherche du premier marker : a002
Get #1, Origin, Mark
Origin = Origin + 1
DoEvents
If Mark = Marke Then NotFound = False
Loop While NotFound
'Premier marker A002 Trouvé
If Codage = Intel Then
Origin = Origin + 7
'4 Derniers octets de la structure de 12
Get #1, Origin, PWidth
Origin = Origin + 4
ElseIf Codage = Motorola Then
Origin = Origin + 7
ReDim Temp(1)
Get #1, Origin, Temp
IntS1 = String(2 - Len(Hex(Temp(0))), "0") & Hex(Temp(0))
IntS2 = String(2 - Len(Hex(Temp(1))), "0") & Hex(Temp(1))
LngS = IntS1 & IntS2
PWidth = Val("&H" & LngS)
Origin = Origin + 4
End If
'on recomence pour Le deuxieme
If Codage = Intel Then Marke = &HA003
If Codage = Motorola Then Marke = &H3A0
Get #1, Origin, Mark
If Mark = Marke Then
For X1 = 1 To 3
Get #1, , Mark
Next X1
If Codage = Intel Then
Origin = Origin + 8
'4 Derniers octets de la structure de 12
Get #1, Origin, PHeight
ElseIf Codage = Motorola Then
Origin = Origin + 8
ReDim Temp(1)
Get #1, Origin, Temp
IntS1 = String(2 - Len(Hex(Temp(0))), "0") & Hex(Temp(0))
IntS2 = String(2 - Len(Hex(Temp(1))), "0") & Hex(Temp(1))
LngS = IntS1 & IntS2
PHeight = Val("&H" & LngS)
End If
Else
JpgSize = 4: GoTo Fin
End If
JpgSize = 0
'Fichier exif terminé
'Retourne 0 (pas d'erreur)
'Et les valeurs dans la streucture
Dimension.cx = PWidth
Dimension.cy = PHeight
End If
Fin:
Close #Free
If Err Then JpgSize = Err.Number
End Function
Private Function ExistFile(ByVal sSpec As String) As Boolean
On Error Resume Next
Call FileLen(sSpec)
ExistFile = (Err = 0)
End Function
Public Function GetErrorString(Index As Integer) As String
Select Case Index
Case 1: GetErrorString = "Le fichier specifié n'existe pas"
Case 2: GetErrorString = "Le fichier specifié n'est pas un JPG"
Case 3: GetErrorString = "LE fichier est bien un Jpg mais contient une mauvaise entete !"
Case 4: GetErrorString = "Marqueur mal placé , non trouvé , peut etre encodage MM"
End Select
End Function
'Erreur
'1 : Le fichier n'existe pas
'2 : Le fichier n'est pas un JPG
'3 : Fichier Jpg mais mauvaise entete !
'4 : Marqueur mal placé , non trouvé , peut etre encodage MM
Conclusion :
j'ai testé sur des jpg provenant d'un apareil canon eos 350, donc avec EXIF
et sur des vielles photo jpg JFIF ver 1.1 et 1.2.
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.