Mai 2024 | Lun | Mar | Mer | Jeu | Ven | Sam | Dim |
---|
| | 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 | | | Calendrier |
|
| | Nouveau défi pour les spécialistes | |
| | |
Auteur | Message |
---|
jjn4
Nombre de messages : 2709 Date d'inscription : 13/09/2009
| Sujet: Nouveau défi pour les spécialistes Jeu 11 Mai 2023 - 18:21 | |
| Il y a une dizaine d'années, on avait concocté, avec JL35 et je ne sais plus qui, un moyen d'obtenir les dimensions d'une photo jpg (largeur et hauteur) avec le pg suivant : - Code:
-
rem ' Routine de calcul des dimensions d'une image jgg ou bmp - Rout-format-imag dim HA% , LA% : rem HAuteur et LArgeur de la photo dim PB% : rem Plan B pour les jpg anormaux label clic : rem Redirection de l`on-click
rem form0 width 0,999 caption 0,"Calcul des dimensions d'une image"
alpha 10 : rem Affichage des dimensions de la photo left 10,5 top 10,5
button 20 : rem Bouton de choix de la photo à mesurer left 20,10 top 20,40 caption 20,"Choisir" on_click 20,clic
end : ' =======================================================================
clic: : rem Redirection de l`on-click ========================================= choisir() return
sub choisir() : rem Choisir la photo à mesurer ================================ dim_local np$ : rem Nom de la Photo open_dialog 99 np$=file_name$(99) delete 99 LA%=0 HA%=0 if lower$(right$(np$,4))=".bmp" format_bmp(np$) end_if PB%=0 if lower$(right$(np$,4))=".jpg" format_jpg(np$) end_if if PB%=1 format_pb(np$) end_if caption 0,np$ caption 10,"L="+str$(LA%)+" x "+"H="+str$(HA%)+" - Plan "+chr$(65+PB%)+right$(np$,4) end_sub
sub format_bmp(npf1$) : rem Calcul des dimensions d`une photo bmp dim_local va1% , vb1% , vc1% , vd1% : rem Variables à utilisation multiple rem npf1$ : Nom de la Photo pour le Format BMP npf1$=lower$(npf1$) if right$(npf1$,4)=".bmp" filebin_open_read 1,npf1$ filebin_position 1,18 filebin_read 1,va1% filebin_read 1,vb1% filebin_position 1,22 filebin_read 1,vc1% filebin_read 1,vd1% filebin_close 1 LA%=256*vb1%+va1% HA%=256*vd1%+vc1% end_if end_sub
sub format_jpg(npf2$) : rem Calcul des dimensions d`une photo jpg normale dim_local vh2% , vi2% , vj2% : rem Variables à utilisation multiple dim_local va2% : rem Variables à utilisation multiple dim_local vta2% : rem Taille du fichier dim_local voc2%(10) : rem Les 10 premiers octets du fichier rem npf2$ : Nom de la Photo pour le Format JPG formule 2 (normale) npf2$=lower$(npf2$) if right$(npf2$,4)=".jpg" filebin_open_read 1,npf2$ vta2%=filebin_size(1) filebin_read 1,voc2%(1) filebin_read 1,voc2%(2) if voc2%(1)=255 and voc2%(2)=216 repeat repeat vh2%=vi2%+2+vj2% if vh2%>=vta2% PB%=1 filebin_close 1 exit_sub end_if filebin_position 1,vh2% for va2%=1 to 4 filebin_read 1,voc2%(va2%) next va2% if voc2%(1)<>255 PB%=1 filebin_close 1 exit_sub end_if vj2%=256*voc2%(3)+voc2%(4) vi2%=filebin_pos(1)-4 until voc2%(2)=192 or voc2%(2)=194 for va2%=1 to 5 filebin_read 1,voc2%(va2%) next va2% until voc2%(1)=8 HA%=256*voc2%(2)+voc2%(3) LA%=256*voc2%(4)+voc2%(5) else PB%=1 end_if filebin_close 1 end_if end_sub sub format_pb(npf3$) : rem Plan B : Calcul dimensions d`une jpg anormale ====== dim_local va3% , vb3% , vc3% , vd3% : rem Variables à utilisation multiple rem npf3$ : Nom de la Photo pour le Format JPG formule 3 (anormale) npf3$=lower$(npf3$) picture 199 : rem Affichage provisoire de la photo hide 199 file_load 199,npf3$ file_save 199,"C:\Provy.bmp" delete 199 filebin_open_read 1,"C:\Provy.bmp" filebin_position 1,18 filebin_read 1,va3% filebin_read 1,vb3% filebin_position 1,22 filebin_read 1,vc3% filebin_read 1,vd3% filebin_close 1 file_delete "C:\Provy.bmp" LA%=256*vb3%+va3% HA%=256*vd3%+vc3% end_sub
Je l'ai réutilisée et j'observe que quelquefois, la photo est présentée sur le côté ou même carrément à l'envers, et puis aussi que c'est un peu lent, pour les photos modernes, qui sont très volumineuses. Est-ce que quelqu'un connaît un moyen plus rapide et plus fiable pour y parvenir, par exemple en utilisant une dll comme user32 ou quelque chose comme ça ? Et est-ce qu'il y a aussi un moyen d'extraire la date de la photo à partir du contenu jgg ? | |
| | | Yannick
Nombre de messages : 8611 Age : 53 Localisation : Bretagne Date d'inscription : 15/02/2010
| Sujet: re Jeu 11 Mai 2023 - 18:58 | |
| Salut JJN4. Chez Klaus (KGF.dll) y'a tout ce qu'il faut : Gestion d'images res% = dll_call3("AnalyzeImageFile",adr(jpg$),adr(larg%),adr(haut%)) | |
| | | jjn4
Nombre de messages : 2709 Date d'inscription : 13/09/2009
| Sujet: Re: Nouveau défi pour les spécialistes Jeu 11 Mai 2023 - 19:02 | |
| Ah oui, ça a l'air intéressant ! Et on peut aussi extraire la date de la photo ? | |
| | | Yannick
Nombre de messages : 8611 Age : 53 Localisation : Bretagne Date d'inscription : 15/02/2010
| Sujet: re Jeu 11 Mai 2023 - 19:09 | |
| res% = dll_call3("GetExifInfoFromJPG",adr(jpg$),adr(tag$),adr(txt$)) - exemple:
Exemple: | ' test_GetExifInfoFromJPG.bas
dim jpg$ dim larg%, haut%, res%
dll_on "KGF.dll" picture 40 : stretch_on 40 open_dialog 1 filter 1,"Images JPG|*.jpg" memo 2 : top 2,10 : left 2,200 : width 2,200 : height 2,400 bar_vertical 2 jpg$ = file_name$(1) if jpg$="_" then terminate
file_load 40,jpg$ test("ImageLength") test("ImageDesc") test("Make") test("Model") test("Orientation") test("OrientationDesk") test("XResol") test("YResol") test("Copyright") test("DateTime") test("Software") test("DateTimeOriginal") test("DateTimeDigitized") test("UserComments") test("ExposureTime") test("FNumber") test("ExifVersion") test("SubjectDistance") test("MeteringMode") test("LightSource") test("Flash") test("Focallength") test("ExpProg") test("ISO")
test("ImageWidth") test("ImageHeight")
test("Compression") test("XResolThumb") test("YResolThumb") test("JPEG_OffsThumb") test("JPEG_LengThumb") test("UserComment") dll_off end
sub test(t$) dim_local s$ s$ = string$(255," ") res% = dll_call3("GetExifInfoFromJPG",adr(jpg$),adr(t$),adr(s$)) item_add 2,t$+" = "+trim$(s$) end_sub |
tu peux tout savoir même l'âge de la belle mère du capitaine. | |
| | | jjn4
Nombre de messages : 2709 Date d'inscription : 13/09/2009
| Sujet: Re: Nouveau défi pour les spécialistes Jeu 11 Mai 2023 - 19:12 | |
| Ouhaaa ! Il faut que je regarde ça ! Merci de l'info !!! | |
| | | jjn4
Nombre de messages : 2709 Date d'inscription : 13/09/2009
| Sujet: Re: Nouveau défi pour les spécialistes Ven 12 Mai 2023 - 16:58 | |
| J'ai essayé cette formule donnée par Yannick en exemple, cela donne ça : ?????????????????????? Ce sont les réponses, qui m'auraient intéressé ! (impossible de savoir l'âge du capitaine) | |
| | | Marc
Nombre de messages : 2397 Age : 63 Localisation : TOURS (37) Date d'inscription : 17/03/2014
| Sujet: Re: Nouveau défi pour les spécialistes Ven 12 Mai 2023 - 18:31 | |
| Bonjour à tous ! @JJN4 - Citation :
- ??????????????????????
Ce sont les réponses, qui m'auraient intéressé ! (impossible de savoir l'âge du capitaine) Probablement que ton fichier JPG ne contient pas les métadonnées EXIF. Voici le résultat pour une de mes photos : | |
| | | JL35
Nombre de messages : 7095 Localisation : 77 Date d'inscription : 29/11/2007
| Sujet: Re: Nouveau défi pour les spécialistes Ven 12 Mai 2023 - 20:23 | |
| Les Exifs sont une des particularités du format jpg pour les photos. La structure générale jpg est constituée d'un certain nombre de 'Frames' d'en-tête 'FF xx' La frame Exifs commence par 'FF E1' (cas des photos) Format d'une 'Frame': FF xx (type) xx xx (longueur) xx xx xx... (données La Frame donnant les dimensions est: FF C0 00 11 hh hh ww ww xx xx xx J'avais fait une petite sub (c'est vieux...) pour connaître les dimensions d'un jpg quelconque (w et h sont définis dans le programme appelant): - Code:
-
SUB DimJpg(f$) ' dimensions d'un jpg -> w, h : frame FF C0 ' (frames: FF tt 00 yy xx ... ' tt = type de frame, xx+256*yy taille du contenu (+2 = taille totale) DIM_LOCAL sz,t,x,v%(10) FILEBIN_OPEN_READ 9,f$: sz = FILEBIN_SIZE(9): x = 2 WHILE x < sz FILEBIN_POSITION 9,x: FILEBIN_BLOCK_READ 9,10,v%(0) t = v%(1): ' type de frame (FF xx) IF t=192 OR t=193 OR t=194 OR t=195: ' C0, C1, C2, C3 frame dimensions h = v%(6)+256*v%(5): w = v%(8)+256*v%(7) EXIT_WHILE END_IF x = x+v%(3)+256*v%(2)+2: ' frame suivant END_WHILE FILEBIN_CLOSE 9 END_SUB à tout hasard... Il y a aussi la solution (que j'utilise souvent...) de charger le jpg dans un picture caché que l'on sauvegarde dans un bmp provisoire, et là les données w et h se trouvent à un endroit précis et fixe (18,19 et 22,23), exemple: - Code:
-
SUB DimJpgBmp(f$) ' Dimensions d'une image Bmp ou Jpg -> w,h, définis dans l'appelant DIM_LOCAL p,fp$ p = 900: fp$ = "C:\Tmp.bmp" IF FILE_EXTRACT_EXTENSION$(UPPER$(f$)) <> ".BMP" PICTURE p: HIDE p: FILE_LOAD p,f$: FILE_SAVE p,fp$: DELETE p: f$ = fp$ END_IF FILEBIN_OPEN_READ 1,f$ FILEBIN_POSITION 1,18: w = FILEBIN_READ(1)+256*FILEBIN_READ(1) FILEBIN_POSITION 1,22: h = FILEBIN_READ(1)+256*FILEBIN_READ(1) FILEBIN_CLOSE 1: IF FILE_EXISTS(fp$) = 1 THEN FILE_DELETE fp$ END_SUB
PS Tiens une image retrouvée dans mes archives, structure jpg: Pour ceux qui seraient intéressés par une description détaillée (in english) du format jpeg: http://dev.exiv2.org/projects/exiv2/wiki/The_Metadata_in_JPEG_files | |
| | | jjn4
Nombre de messages : 2709 Date d'inscription : 13/09/2009
| Sujet: Re: Nouveau défi pour les spécialistes Sam 13 Mai 2023 - 15:04 | |
| Merci tout le monde ! Effectivement, j'ai trouvé des images avec des métadonnées EXIF qui font que la dll de Klaus fonctionne. Ceci dit, c'est souvent qu'il n'y en a pas. Qu'est-ce qui fait que des photos en ont et d'autres pas ? Ont-elles des origines différentes ? Si trop de photos n'en ont pas, ce n'est finalement pas très intéressant...? @JL35: Ta sub pour les jpg est un peu différente de celle qu'on avait travaillée ensemble il y a............. ouh !!!!!!!!! et que j'ai mise plus haut sous le nom : sub format_jpg(npf2$) : rem Calcul des dimensions d`une photo jpg normale Celle qu'on avait faite venait elle aussi des EXIF (car elles marchent pour toutes les photos, celle-là) Celle que tu présentes est-elle plus moderne, ou plus complète ? Prend elle en compte les jpg « anormales » (qu'on avait trouvées à cette époque) ? Et plein de questions me viennent : - Pourquoi, avec la formule ancienne, qu'on avait mise au point, certaines photos sont-elles tournées de 90°, voire de 180° ? - Pourrait-on alors tourner volontairement les photos de cette façon, sans que ça prenne des plombes ? - As-tu également une sub qui extrait la date de prise de vue de la photo ? (au moins l'année) ? (désolé si j'ai plein d'idées qui me viennent) | |
| | | JL35
Nombre de messages : 7095 Localisation : 77 Date d'inscription : 29/11/2007
| Sujet: Re: Nouveau défi pour les spécialistes Sam 13 Mai 2023 - 20:33 | |
| Salut jjn4 ! et tous les autres ! Il faut bien se dire que les images photo en jpg sont une variante du format jpg avec des informations supplémentaires (la partie Exifs), qui contiennent des infos spécifiques: entre autres date heure de prise de vue, focale, etc.. Si par exemple tu convertis une image photo jpg en bmp, puis le bmp à nouveau en jpg, tu perds les infos Exifs et tu te retrouves avec une image de base normale, sans rapport avec une image photo. Par exemple: l'origine est bien une photo, mais retravaillée, donc plus d'exifs, c'est un jpg ordinaire. Et là, plus de date et heure de prise de vue..., mais enfin, en majorité les exifs sont toujours présents dans les photos (même par exemple redimensionnées, mais sans changement de format). Pour la date et heure de prise de vue, on doit pouvoir trouver en cherchant dans la partie exifs du fichier, perso j'utilise une ressource externe: jhead.exe qui doit être facile à trouver, et est facile à utiliser: - Code:
-
SUB JpgDate(f$)
Pour ce qui est de la rotation des images jpg (ou autres) de 90° ou 180°, j'ai bien une sub, mais il y a reformatage, et s'il s'agit de photo on perd les exifs et ça devient une image jpg lambda, sans les infos photo. Il y a peut-être moyen de pivoter une photo avec ses exifs, mais je ne connais pas (c'est peut-être une info contenue dans les exifs ?). La méthode photo pivotée -> jpg ordinaire (c'est un script vbs): [code]SUB ImgRot90(f$,RL$,fr$) ' Rotation d'une image f$ de 90° à gauche (RL$="L") ou à droite (RL$="R") ' ou à 180° (RL$ = "RL"). (angles intermédiaires inadmis). ' Résultat dans le fichier fr$ (-> NOTA: doit être de même type que f$) ' NB: si photo, perte des Exifs. DIM_LOCAL scr$,arg$,r$,q$: q$ = CHR$(34) r$ = "270": IF UPPER$(RL$)="R" THEN r$ = "90" IF UPPER$(RL$)="RL" THEN r$ = "180" IF FILE_EXISTS(fr$) = 1 THEN FILE_DELETE fr$: ' sinon, erreur scr$ = "C:\Temp\Vbscript.vbs" FILE_OPEN_WRITE 9,scr$ FILE_WRITELN 9,"Dim Img 'As ImageFile" FILE_WRITELN 9,"Dim IP 'As ImageProcess" FILE_WRITELN 9,"Set Img = CreateObject("+q$+"WIA.ImageFile"+q$+")" FILE_WRITELN 9,"Set IP = CreateObject("+q$+"WIA.ImageProcess"+q$+")" FILE_WRITELN 9,"Img.LoadFile "+q$+f$+q$ FILE_WRITELN 9,"IP.Filters.Add IP.FilterInfos("+q$+"RotateFlip"+q$+").FilterID" FILE_WRITELN 9,"IP.Filters(1).Properties("+q$+"RotationAngle"+q$+") = "+r$ FILE_WRITELN 9,"Set Img = IP.Apply(Img)" FILE_WRITELN 9,"Img.SaveFile "+q$+fr$+q$ FILE_WRITELN 9,"WScript.Quit(0)" FILE_CLOSE 9 EXECUTE_WAIT "Wscript.exe|" + scr$: ' Exécution du script FILE_DELETE scr$ END_SUB[/code] ' Date/Heure de prise de vue Exif de l'image Jpg f$ -> dat$ (aaaa:mm:jj hh:mm) DIM_LOCAL a$,k IF VARIABLE("dat$")=0 THEN DIM dat$ EXECUTE_WAIT "cmd.exe|/c C:\UTIL\jhead.exe "+f$+" |clip" a$ = CLIPBOARD_STRING_PASTE$: k = INSTR(a$,"Date/Time") dat$ = MID$(a$,k+15,16) END_SUB Autre moyen, en pur Panoramic (mais il faut qu'il y ait des exifs dans l'image/photo): - Code:
-
SUB Datexif(f$) ' Date/heure de prise de vue exifs (jpg), résultat dans dat$ (pré-défini) ' format dat$ rendu = "AAAA:MM:JJ HH:MM:SS" DIM_LOCAL k,id,vhx$: dat$ = "non trouvé !" FILEBIN_OPEN_READ 1,f$: FILEBIN_HEXA_READ 1,2000,vhx$: FILEBIN_CLOSE 1 id = INSTR(vhx$, "0CA4030001"): IF id<1 THEN id = INSTR(vhx$, "0AA4030001") IF id<1 THEN id = INSTR(vhx$, "06A4030001") IF id > 0 dat$ = "" FOR k = 0 TO 37 STEP 2 dat$=dat$+CHR$(HEX(MID$(vhx$,k+id+64,2))) NEXT k END_IF END_SUB Concernant la rotation des images de 90° ou 180°, je connais quelques procédés, mais qui transforment la photo en image jpg lambda, c'est à dire avec perte des exifs (infos photo). Il y a peut-être des moyens pour les conserver (l'orientation est peut-être une des infos exifs), mais a priori je ne connais pas, je vais regarder à tout hasard. Une sub qui pivote l'image de 90 ou 180° et qui renvoie un jpg simple sans infos photo (c'est un script vbs): - Code:
-
SUB ImgRot90(f$,RL$,fr$) ' Rotation d'une image f$ de 90° à gauche (RL$="L") ou à droite (RL$="R") ' ou à 180° (RL$ = "RL"). (angles intermédiaires inadmis). ' Résultat dans le fichier fr$ (-> NOTA: doit être de même type que f$) ' NB: si photo, perte des Exifs. DIM_LOCAL scr$,arg$,r$,q$: q$ = CHR$(34) r$ = "270": IF UPPER$(RL$)="R" THEN r$ = "90" IF UPPER$(RL$)="RL" THEN r$ = "180" IF FILE_EXISTS(fr$) = 1 THEN FILE_DELETE fr$: ' sinon, erreur scr$ = "C:\Temp\Vbscript.vbs" FILE_OPEN_WRITE 9,scr$ FILE_WRITELN 9,"Dim Img 'As ImageFile" FILE_WRITELN 9,"Dim IP 'As ImageProcess" FILE_WRITELN 9,"Set Img = CreateObject("+q$+"WIA.ImageFile"+q$+")" FILE_WRITELN 9,"Set IP = CreateObject("+q$+"WIA.ImageProcess"+q$+")" FILE_WRITELN 9,"Img.LoadFile "+q$+f$+q$ FILE_WRITELN 9,"IP.Filters.Add IP.FilterInfos("+q$+"RotateFlip"+q$+").FilterID" FILE_WRITELN 9,"IP.Filters(1).Properties("+q$+"RotationAngle"+q$+") = "+r$ FILE_WRITELN 9,"Set Img = IP.Apply(Img)" FILE_WRITELN 9,"Img.SaveFile "+q$+fr$+q$ FILE_WRITELN 9,"WScript.Quit(0)" FILE_CLOSE 9 EXECUTE_WAIT "Wscript.exe|" + scr$: ' Exécution du script FILE_DELETE scr$ END_SUB PSJe viens de trouver une autre sub dans mes archives pour pivoter une image, qui fait appel à une ressource externe IrfanView (incontournable pour le traitement d'images et que j'utilise depuis très longtemps). Apparemment ça pivote de 90 ou 180° et surtout ça conserve le statut de photo avec les infos Exif$ ! - Code:
-
SUB Rot_Image(f$,fr$,LR$) ' Rotation de l'image f$, résultat fr$ (ou clipboard si fr$ = "") ' LR$ = "L": 90° gauche, ="R": 90° droite, ="LL": 180° DIM_LOCAL iv$,a$,b$ iv$ = "C:\Progra~2\Irfanv~1\i_view64.exe": ' <- CHEMIN À ADAPTER ! a$ = "/rotate_l": IF LR$ = "R" THEN b$ = "/rotate_r" IF LR$ = "LL" THEN a$ = "/rotate_l /rotate_l": ' 180° b$ = "/convert="+fr$: IF fr$ = "" THEN b$ = "/clipcopy /killmesoftly" EXECUTE_WAIT iv$+"|"+f$+" "+a$+" "+b$ END_SUB | |
| | | jjn4
Nombre de messages : 2709 Date d'inscription : 13/09/2009
| Sujet: Re: Nouveau défi pour les spécialistes Lun 15 Mai 2023 - 15:54 | |
| J'ai compris pourquoi certaines photos apparaissent tournées à 90 ou 180° dans les picture de panoramic. Ce sont celles qui proviennent de smartphones. Si on le prend horizontalement, elles sont droites, si on le prend verticalement, elles sont tournées de 90° et si on met le smartphone horizontalement à l'envers, elles sont tournées de 180°. Jusque là, cela semble évident. Le problème, c'est quand on les a mis dans le bon sens avec un système Windows. Dans l'explorateur Windows, elles apparaissent à l'endroit et dans un picture de panoramic, elles apparaissent dans leur position d'origine (couchées ou à l'envers) comme si Windows ne tournait pas vraiment les photos, mais juste leur apparence. Par contre, si on les tourne avec IrfanView, là, ça marche. Panoramic les voient dans le bon sens. Voilà donc un problème de réglé. Suffit de les tourner préalablement avec le bon instrument. Ouf ! Pour ce qui est de dégager la date de la photo, j'ai essayé les deux méthodes de JL35 (avec jhead.exe et sans), mais cela ne marche pas. J'ai essayé avec la dll de KGF, ça marche, mais quand on lance le programme plusieurs fois, l'ordinateur déclare un bug : il faut alors attendre « un certain temps » avant qu'il accepte de remarcher...? J'ai aussi essayé d'isoler l'apparition de la date par une fnc (pour l'isoler de tout le fourbi que la dll sort), pas concluant non plus, ça me sort la dernière ligne. Décidément... | |
| | | JL35
Nombre de messages : 7095 Localisation : 77 Date d'inscription : 29/11/2007
| Sujet: Re: Nouveau défi pour les spécialistes Lun 15 Mai 2023 - 16:52 | |
| Salut jjn4, Pour la date avec jhead, tu m'étonnes... Essaye celle-ci: - Code:
-
SUB JpgDate(f$) ' Date/Heure de prise de vue Exif de l'image Jpg f$ -> dat$ (aaaa:mm:jj hh:mm) DIM_LOCAL a$,k IF VARIABLE("dat$")=0 THEN DIM dat$ EXECUTE_WAIT "cmd.exe|/c C:\UTIL\jhead.exe "+f$+" |clip" a$ = CLIPBOARD_STRING_PASTE$: k = INSTR(a$,"Date/Time") dat$ = MID$(a$,k+15,16) END_SUB Mais il est bien entendu que le jpg contient bien les infos exif photo et qu'il n'a pas été bricolé et devenu un jpg de base. Pour info, l'exif contient deux dates: celle du fichier qui est mise à jour à chaque modif, et celle de prise de vue d'origine, qui elle ne change pas (info 'Date/Time:') Pour avoir toutes les infos photo de base (une dizaine) pour un fichier jpg photo, intéressant: - Code:
-
SUB Exifs(f$) ' Données Exifs de base f$ -> clipboard EXECUTE_WAIT "cmd.exe|/c C:\UTIL\jhead.exe "+f$+" |clip" END_SUB | |
| | | jjn4
Nombre de messages : 2709 Date d'inscription : 13/09/2009
| Sujet: Re: Nouveau défi pour les spécialistes Lun 15 Mai 2023 - 18:04 | |
| Non décidément, cela ne marche pas. Il faut dire que je ne suis pas arrivé à télécharger jhead.exe Maintenant, c'est jhead2.90.exe... Dommage que la méthode en pur panoramic pour trouver la date : - Code:
-
SUB Datexif(f$) ' Date/heure de prise de vue exifs (jpg), résultat dans dat$ (pré-défini) ' format dat$ rendu = "AAAA:MM:JJ HH:MM:SS" DIM_LOCAL k,id,vhx$: dat$ = "non trouvé !" FILEBIN_OPEN_READ 1,f$: FILEBIN_HEXA_READ 1,2000,vhx$: FILEBIN_CLOSE 1 id = INSTR(vhx$, "0CA4030001"): IF id<1 THEN id = INSTR(vhx$, "0AA4030001") IF id<1 THEN id = INSTR(vhx$, "06A4030001") IF id > 0 dat$ = "" FOR k = 0 TO 37 STEP 2 dat$=dat$+CHR$(HEX(MID$(vhx$,k+id+64,2))) NEXT k END_IF END_SUB ne marche pas (c'est toujours « non trouvé ! ») car ce serait bien pour faire ça sur (par exemple) 1000 photos d'affilée car avec l'aide de jhead, il se pourrait bien que ça fasse un peu long. | |
| | | JL35
Nombre de messages : 7095 Localisation : 77 Date d'inscription : 29/11/2007
| Sujet: Re: Nouveau défi pour les spécialistes Lun 15 Mai 2023 - 19:58 | |
| Un peu bizarre, si tu es sûr que ton fichier contient les exifs... Peut-être y a t'il des particularités avec les photos issues d'un téléphone portable... Pour récupérer en manuel la date/heure de prise de vue (pour vérification): sous explorateur Windows, clic droit sur la photo, puis clic 'Propriétés', puis onglet 'Détails' et ça t'affiche la date de pdv, et si tu parcours, toutes les infos photo Exif. Sinon il y a plein d'utilitaires pour lire et manipuler les exifs, ExifLoad, Exifread, Exiftags, Exiftool... PS Puisque tu as IrfanView, tu peux aussi l'utiliser, il renvoie toutes les données exif (dont date/heure de prise de vue) dans un fichier texte au format spécial (un caractère 0 après chaque caractère du texte) - Code:
-
DIM f$,fr$ f$ = "F:\Reduc\P1040037.JPG": ' exemple fr$ = "Z:\Infos.txt": ' résultat, toutes les infos y compris exifs ExifInfos(f$,fr$) Supzero_Fic(fr$,fr$) PRINT "Terminé !" END
SUB ExifInfos(f$,fr$) ' Infos exifs d'un fichier image photo, résultat dans le fichier texte fr$ DIM_LOCAL iv$ iv$ = "C:\Progra~2\IrfanV~1\i_view64.exe": ' chemin IrfanView, à adapter ! EXECUTE_WAIT iv$+"|"+f$+" /info="+fr$+" /fullinfo /killmesoftly" END_SUB
SUB Supzero_Fic(f$,fr$) ' Suppression des caractères '0' dans un fichier texte f$ -> fr$ DIM_LOCAL sz%,i%,a$ FILEBIN_OPEN_READ 1,f$: sz% = FILEBIN_SIZE(1): DIM_LOCAL v%(sz%) FILEBIN_BLOCK_READ 1,sz%,v%(0): FILEBIN_CLOSE 1 a$="" FOR i% = 4 TO sz%-1: ' sauf en-tête 'FF FE 3B 00' IF v%(i%)<>0 THEN a$=a$+CHR$(v%(i%)) NEXT i%: FREE v% FILE_OPEN_WRITE 1,fr$: FILE_WRITELN 1,a$: FILE_CLOSE 1 END_SUB Après il faut aller chercher dans le fichier résultat la rubrique 'DateTime', exemple ici: DateTime - 2023:05:13 12:47:16qui est bien la date heure de prise de vue, et non la date du fichier, qui a été modifié (redimensionné), qui elle se trouve avant dans File date/time = ... | |
| | | jjn4
Nombre de messages : 2709 Date d'inscription : 13/09/2009
| Sujet: Re: Nouveau défi pour les spécialistes Mar 16 Mai 2023 - 18:20 | |
| Ca y est, en explorant un peu, j'ai réussi à isoler l'obtention de la date par la dll KGF en procédant par séries. Voici un exemple : - Code:
-
' Chercher la date d'une photo jpg avec KGF.dll
dim V4M$ , RES% , pic$(5) , a% pic$(1)="IMG_1795.JPG" pic$(2)="IMG_1797.JPG" pic$(3)="IMG_1799.JPG" pic$(4)="IMG_1804.JPG" pic$(5)="IMG_1812.JPG" dll_on KGF.dll"
picture 40 : stretch_on 40 : hide 40 grid 2
for a% = 1 to 5 V4M$=pic$(a%) file_load 40,V4M$ test("DateTimeOriginal") next a% dll_off
end
sub test(t$) dim_local s$ s$ = string$(255," ") RES% = dll_call3("GetExifInfoFromJPG",adr(V4M$),adr(t$),adr(s$)) grid_write 2,a%+1,2,left$(trim$(s$),4) end_sub J'ai intégré ça dans le programme que je concocte et ça marche, et c'est assez rapide, Hourra !!! Quant à la recherche des dimensions de la photo, je garde le système que j'avais et que j'ai publié au début de ce post, puisqu'il fonctionne sans EXIF et traite même les jpg « bizarroïdes ». Je vais encore pouvoir vous sortir bientôt un joli programme nouveau...! Et merci pour toute l'aide apportée ! | |
| | | jjn4
Nombre de messages : 2709 Date d'inscription : 13/09/2009
| Sujet: Re: Nouveau défi pour les spécialistes Lun 22 Mai 2023 - 17:30 | |
| @JL35: Je ne suis pas sûr de pouvoir utiliser cette dll KGF qui semble avoir des limites. Alors je reviens aux formules que tu m'as présentées : Celle-ci me paraît intéressante : - Code:
-
dim a$ , dat$ a$="C:\Users\admin\Pictures\IMG_1795.JPG" Datexif(a$) caption 0,dat$ end SUB Datexif(f$) ' Date/heure de prise de vue exifs (jpg), résultat dans dat$ (pré-défini) ' format dat$ rendu = "AAAA:MM:JJ HH:MM:SS" DIM_LOCAL k,id,vhx$: dat$ = "non trouvé !" FILEBIN_OPEN_READ 1,f$: FILEBIN_HEXA_READ 1,2000,vhx$: FILEBIN_CLOSE 1 id = INSTR(vhx$, "0CA4030001"): IF id<1 THEN id = INSTR(vhx$, "0AA4030001") IF id<1 THEN id = INSTR(vhx$, "06A4030001") IF id > 0 dat$ = "" FOR k = 0 TO 37 STEP 2 dat$=dat$+CHR$(HEX(MID$(vhx$,k+id+64,2))) NEXT k END_IF END_SUB Elle semble pouvoir aller assez vite et pouvoir être répétée à la suite sur des centaines de photos sans que l'utilisateur inconnu, (quand on offre ce pg sur le forum) ait besoin d'avoir IrfanView ou un autre pg donné. Le problème de cette formule ci-dessus, c'est qu'elle ne marche jamais ! Quelle que soit la photo proposée en a$, avec EXIF ou sans, c'est toujours « non trouvé ! », « non trouvé ! », « non trouvé ! » As-tu testé ta formule, es-tu bien sûr qu'elle fonctionne chez toi ? | |
| | | JL35
Nombre de messages : 7095 Localisation : 77 Date d'inscription : 29/11/2007
| Sujet: Re: Nouveau défi pour les spécialistes Lun 22 Mai 2023 - 21:34 | |
| Salut jjn4, et désolé, effectivement il semble y avoir un décalage dans la sub, ou alors quelque chose a évolué depuis (ce qui serait quand même étonnant)... ? Je viens de la modifier, essaie plutôt celle-ci: (recherche de la balise date/time, puis recherche du premier caractère ':' de AAAA:MM:JJ...) - Code:
-
SUB Datexif(f$) ' Date/heure de prise de vue exifs (jpg), résultat dans dat$ (pré-défini) ' format dat$ = "AAAA:MM:JJ HH:MM:SS" DIM_LOCAL k,id,vhx$: dat$ = "non trouvé !" FILEBIN_OPEN_READ 1,f$: FILEBIN_HEXA_READ 1,2000,vhx$: FILEBIN_CLOSE 1 id = INSTR(vhx$, "0CA4030001"): IF id<1 THEN id = INSTR(vhx$, "0AA4030001") IF id<1 THEN id = INSTR(vhx$, "06A4030001") IF id > 0 dat$ = "": id = INSTR_POS(vhx$,"3A",id): id = id-8 FOR k = 0 TO 37 STEP 2 dat$=dat$+CHR$(HEX(MID$(vhx$,k+id,2))) NEXT k END_IF END_SUB | |
| | | jjn4
Nombre de messages : 2709 Date d'inscription : 13/09/2009
| Sujet: Re: Nouveau défi pour les spécialistes Mar 23 Mai 2023 - 14:40 | |
| Cette fois, il y a certaines photos avec lesquelles ça marche, mais beaucoup d'autres, qui ont pourtant un Exif, puisque la date est donnée en miniature Windows, mais pour lesquelles ça ne marche pas, et en particulier toutes celles provenant de mon appareil photo. Pour quelles raisons...??? Je t'envoie une de ces photos, peut-être sauras-tu dire pourquoi ? (désolé de te donner du travail en plus) Et merci d'avance ! Nota en plus : C'est plutôt rare qu'il donne la date. Je l'ai adapté pour faire de ces calculs en série : (à ne donner que l'année (les 4 premiers caractères) une fois, il a trouvé l'année : « f5 » Il lui arrive aussi de faire des bugs : La ligne 1640, c'est : dat$=dat$+CHR$(HEX(MID$(vhx$,k+id,2))) Décidément ! | |
| | | JL35
Nombre de messages : 7095 Localisation : 77 Date d'inscription : 29/11/2007
| Sujet: Re: Nouveau défi pour les spécialistes Mar 23 Mai 2023 - 17:37 | |
| Effectivement... dans ton image/photo la séquence "A4030001" est remplacée par "A2030001"... je regarde de plus près s'il y a d'autres indices, mais... la structure Exifs est bien compliquée... Je crois que le mieux c'est encore de faire appel à un logiciel externe, j'essaie de comprendre la structure des exifs mais c'est très compliqué ! Par exemple tu as jhead: - Code:
-
SUB JpgDate(f$) ' Date/Heure de prise de vue Exif de l'image Jpg f$ -> dat$ (aaaa:mm:jj hh:mm) DIM_LOCAL a$,k IF VARIABLE("dat$")=0 THEN DIM dat$ EXECUTE_WAIT "cmd.exe|/c C:\UTIL\jhead.exe "+f$+" |clip" a$ = CLIPBOARD_STRING_PASTE$: k = INSTR(a$,"Date/Time") dat$ = MID$(a$,k+15,16) END_SUB ou encore kgf.dll de l'ami Klaus, mais c'est peut-être moins rapide (à tester avec une série de fichiers): - Code:
-
SUB InfosExif(f$,info$) ' Infos exif de f$, type d'info = info$, résultat dans clipboard) ' Type d'info: ex info$="DateTimeOriginal", "ImageWidth", "ImageHeight" etc. DIM_LOCAL s$,r% DLL_ON "C:\PANORAMIC\KGF\KGF.dll": ' à ajuster s$ = STRING$(255," ") r% = DLL_CALL3("GetExifInfoFromJPG",ADR(f$),ADR(info$),ADR(s$)) DLL_OFF CLIPBOARD_STRING_COPY TRIM$(s$) END_SUB je continue à regarder, mais sans trop d'espoir... PS Je viens de faire l'expérience sur un dossier de 39 photos. Avec la sub JpgDate (jhead.exe): les 39 résultats en 15 secondes Avec la sub InfosExifs (kgf.dll): les 39 résultats en 6 secondes Y'a pas photo ! (enfin si, quand même !) En tout cas ça me semble très acceptable avec kgf. Et mieux encore, si on fait le DLL_ON en début de série et DLL_ON à la fin (et en les supprimant de la sub) j'arrive à une exécution presque immédiate, ~1 seconde pour les 39 images ! Tiens, avec kgf, il me semble que ce qui t'intéresse c'est le traitement de tout un répertoire d'images, je trouve que c'est très rapide. Et en tout cas ça marche avec la photo que tu as donné en exemple ci-dessus. - Code:
-
SUB DateurPV(rep$,obj) ' Date/Heure de prise de vue Exif des images jpg (photos) du répertoire rep$ ' Résultats dans l'objet de n° obj (LIST, MEMO, etc) sous la forme d'une liste, ' chaque élément = "AAAA:MM:JJ HH:MM:SS Nom du fichier" ' (la liste résultat est triée par ordre chronologique croissant). DIM_LOCAL f$,ft$,a$,info$,i,k,r%,s$ info$ = "DateTimeOriginal": ' info cherchée LIST 900: HIDE 900 EXECUTE_WAIT "cmd.exe|/c DIR /B "+r$+"*.JPG |clip": CLIPBOARD_PASTE 900 DLL_ON "C:\PANORAMIC\KGF\KGF.dll": ' chemin à ajuster FOR i = 1 TO COUNT(900) f$ = ITEM_READ$(900,i): ft$ = rep$+f$ s$ = STRING$(255," ") r% = DLL_CALL3("GetExifInfoFromJPG",ADR(ft$),ADR(info$),ADR(s$)) ITEM_ADD obj,TRIM$(s$)+" "+f$ NEXT i DLL_OFF: DELETE 900 SORT obj: ' tri du résultat par ordre chronologique croissant END_SUB Ceci dit... bonne nuit ! | |
| | | jjn4
Nombre de messages : 2709 Date d'inscription : 13/09/2009
| Sujet: Re: Nouveau défi pour les spécialistes Mer 24 Mai 2023 - 16:27 | |
| La dll KGF est peut-être très bien, mais elle peut occasionner un bug que je ne sais pas traiter : Comme on peut le voir, j'ai déjà essayé de changer RES% par RES, mais ça ne change rien au problème. Comment faire vérifier préalablement par le programme si ça risque de provoquer une erreur ou non ???????? J'ai essayé aussi la gestion des erreur (on_error_goto) mais apparemment, comme c'est une erreur externe, ça ne marche pas... Si quelqu'un a une solution, avant que je jette l'éponge...????????? (et le bébé avec l'eau du bain) | |
| | | JL35
Nombre de messages : 7095 Localisation : 77 Date d'inscription : 29/11/2007
| Sujet: Re: Nouveau défi pour les spécialistes Mer 24 Mai 2023 - 18:56 | |
| Alors là ça me dépasse... Il semble que ce soit un des paramètres de l'appel à la dll qui est incorrect... et effectivement, 4278714374 ne ressemble pas à une adresse de chaîne mais à une séquence de caractères en hexadécimal ("BxqCt")... | |
| | | jjn4
Nombre de messages : 2709 Date d'inscription : 13/09/2009
| Sujet: Re: Nouveau défi pour les spécialistes Mer 24 Mai 2023 - 19:34 | |
| Alors là, si JL35 est dépassé ! Il ne me reste plus qu'à jeter l'éponge, l'eau du bain, le bébé, la baignoire et aussi la salle de bain !!! Car je n'y connais rien, dans ces domaines là ! | |
| | | JL35
Nombre de messages : 7095 Localisation : 77 Date d'inscription : 29/11/2007
| Sujet: Re: Nouveau défi pour les spécialistes Mer 24 Mai 2023 - 22:40 | |
| Un des 3 paramètres donnés à la dll n'est pas correct... tu devrais peut-être les afficher avant l'appel, pour voir, par exemple Message V4M$+";"+t$+";"+s$ | |
| | | JL35
Nombre de messages : 7095 Localisation : 77 Date d'inscription : 29/11/2007
| Sujet: Re: Nouveau défi pour les spécialistes Jeu 25 Mai 2023 - 10:46 | |
| Tu peux aussi essayer cette fonction, ça marche sur la photo que tu as donnée ci-dessus. Il y a dans les exifs d'abord la date du fichier lui-même, puis deux dates successives: prise de vue et numérisation, en règle générale identiques. La première peut être différente de l'origine, si le fichier a été modifié d'une façon ou d'une autre. Donc on recherche une des deux autres (la 1ère). - Code:
-
DIM f$: f$ = "C:\GRAPH\JPG\JJN4.jpg" PRINT DateExif$(f$) END
FNC DateExif$(f$) ' Date/heure de prise de vue, recherche de deux dates successives ' (prise de vue et enregistrement, identiques) DIM_LOCAL a$,b$,k FILEBIN_OPEN_READ 1,f$: a$ = FILEBIN_HEXA_READ$(1,2000): FILEBIN_CLOSE 1 k = INSTR(a$,"3A"): ' séparateur ':' WHILE k > 0 IF MID$(a$,k+40,2) = "3A" THEN EXIT_WHILE: ' ok, 2 dates successives k = INSTR_POS(a$,"3A",k+40) END_WHILE IF k = 0 RESULT "Non trouvé" ELSEhttps://2img.net/i/fa/i/smiles/icon_rendeer.png a$ = MID$(a$,k-8,38): b$ = "" FOR k = 1 TO 37 STEP 2: b$ = b$+CHR$(HEX(MID$(a$,k,2))): NEXT k RESULT b$: ' format AAAA:MM:JJ HH:MM:SS END_IF END_FNC | |
| | | jjn4
Nombre de messages : 2709 Date d'inscription : 13/09/2009
| Sujet: Re: Nouveau défi pour les spécialistes Jeu 25 Mai 2023 - 15:40 | |
| Formidable, ça marche ! Bravo, JL35 et merci ! (toujours le grand spécialiste qu'on connaît) Bon, c'est vrai que ça ne marche pas à tous les coups, mais presque (alors je ne vais chipoter) Ca donne aussi quelquefois de drôles de date ( ) (voir ligne marquée « page 14 ») mais bon, avec un petit : if numeric(... ça ira. Et surtout, surtout, surtout !!! Ca ne fait pas de plantage, même sur des listes de plusieurs milliers de photos !!! Alors, là encore bravo, JL35, je ne vais finalement pas jeter le bébé et inclure cette fonction dans le programme que je prépare, et que je vais donc bientôt sortir ! | |
| | | Contenu sponsorisé
| Sujet: Re: Nouveau défi pour les spécialistes | |
| |
| | | | Nouveau défi pour les spécialistes | |
|
Sujets similaires | |
|
| Permission de ce forum: | Vous ne pouvez pas répondre aux sujets dans ce forum
| |
| |
| |