Read/Write Exif dates

Just starting out? Need help? Post your questions and find answers here.
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Read/Write Exif dates

Post by Sparkie »

This is in response to a request from GeoTrail in another thread.

@GeoTrail: Try this code and see if it returns the Exif dates form both your cameras. If it does, then I will add a procedure for changing the dates. :)

Code: Select all

UseJPEGImageDecoder() 
#Exif_DT_Modified   = $132  ; 306 
#Exif_Sub           = $8769 ; 34665
#Exif_DT_Taken      = $9003 ; 36867
#Exif_DT_Digitized  = $9004 ; 36868
#Header             = 12 
#ModifiedDate       = 0
#TakenDate          = 1
#DigitizedDate      = 2
Global date_time 
Dim exifDate$(2)

Procedure.s GetExifDateTime(jpg$, writeIt, newDateTime$) 
  OpenFile(0, jpg$) 
  ; --> Byte 0 of EXIF begins after JPEG header 
  FileSeek(#Header) 
  ; --> Bytes 0-1 is byte order 18761 ($4949) is Intel and 19789 ($4D4D) is Motorola 
  byteOrder = ReadWord() 
  If byteOrder = $4949 
    ; --> Bytes 2-3 is TIFF format, it's always 42 ($2A). If not, give up. 
    tifFormat = ReadWord() 
    If tifFormat = $2A 
      ; --> Bytes 4-7 is starting offset for IFD (Image File Directory) 
      ifd1 = ReadLong() 
      ; --> Move to start of IFD 
      FileSeek(ifd1 + #Header) 
      ; --> First 2 bytes of IFD is number of field entries 
      nFields = ReadWord() 
      ; --> Loop through all fields to find Date/Time stamp 
      date_time = #False 
      For i = 1 To nFields 
        ; --> Bytes 0-1 contain the Tag for the field. 
        currentTag = ReadWord() &$FFFF
        Select currentTag
          Case #Exif_DT_Modified
            ; --> Bytes 2-3 contain the field Type. 
            ; --> We know this will be 2 (ASCII) For Date/Time 
            fieldType = ReadWord() 
            ; --> Bytes 4-7 contain the  Length of the field. 
            fieldLength = ReadLong() 
            currentloc = Loc() 
            ; --> Bytes 8-11 contain a pointer to ASCII Date/Time 
            fieldValue = ReadLong() 
            ; --> Move to that pointer 
            FileSeek(fieldValue + #Header) 
            ; --> This is the start point of Dat/Time ASCII string 
            If writeIt And newDateTime$ 
              WriteString(newDateTime$) 
              date_time$ = newDateTime$ 
              MessageRequester("Info", "Date and Time have been changed.") 
            Else 
              exifDate$(#ModifiedDate) = ReadString()
              allDate$ = "Modified:" + #TAB$ + exifDate$(#ModifiedDate)
              FileSeek(currentloc+4)
            EndIf 
          Case #Exif_Sub
            FileSeek(Loc() + 6)
            ExifLoc = ReadLong()
            FileSeek(ExifLoc + #Header + 2)
            Repeat
              tag = ReadWord() &$FFFF
              If tag = #Exif_DT_Taken
                currLoc = Loc()
                FileSeek(Loc() + 6)
                datLoc = ReadLong()
                FileSeek(datLoc + #Header)
                exifDate$(#TakenDate) = ReadString()
                allDate$ + #CRLF$ + "Taken:" + #TAB$ + exifDate$(#TakenDate)
                FileSeek(currLoc + 10)
              EndIf
              If tag = #Exif_DT_Digitized
                currLoc = Loc()
                FileSeek(Loc() + 6)
                datLoc = ReadLong()
                FileSeek(datLoc + #Header)
                exifDate$(#DigitizedDate) = ReadString()
                allDate$ + #CRLF$ + "Digitized:" + #TAB$ + exifDate$(#DigitizedDate)
                FileSeek(currLoc + 10)
              EndIf
              If tag <> #Exif_DT_Taken And tag <> #Exif_DT_Digitized
                FileSeek(Loc() + 10)
              EndIf
            Until tag = 0
          Default
            ; --> Move to next field. Each field is 12 bytes. 
            ; --> currentTag (2 bytes) is current Loc() so we add 10 
            FileSeek(Loc()+10) 
        EndSelect
      Next i
    Else 
      MessageRequester("Error", "Invalid file format!") 
    EndIf 
  Else 
    MessageRequester("Sorry", "Invalid file format!") 
  EndIf 
  CloseFile(0) 
  ProcedureReturn allDate$ 
EndProcedure 

If OpenWindow(0, 10, 10, 300, 200, #PB_Window_SystemMenu, "Exif Date/Time") And CreateGadgetList(WindowID()) 
  ButtonGadget(0, 10, 10, 280, 20, "Open JPG for Exif info") 
  Repeat 
    event = WaitWindowEvent() 
    If event = #PB_EventGadget 
      Select EventGadgetID() 
        Case 0 
          fileOpen$ = (OpenFileRequester("Select JPEG", "C:\Documents and Settings\Owner\My Documents\My Pictures\", "JPG files (JPG)|*.jpg;*.jpeg", 0)) 
          If fileOpen$ 
            dt$ = GetExifDateTime(fileOpen$, 0, "") 
            MessageRequester("Exif Info", dt$)
          EndIf 
      EndSelect 
    EndIf 
  Until event = #PB_Event_CloseWindow 
EndIf 
End 
Last edited by Sparkie on Tue Jun 14, 2005 12:37 pm, edited 1 time in total.
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
User avatar
GeoTrail
Addict
Addict
Posts: 2794
Joined: Fri Feb 13, 2004 12:45 am
Location: Bergen, Norway
Contact:

Post by GeoTrail »

It works when I open a picture taken with the Canon A60, but when I open a picture taken with my S700i it says it is an invalid format.
I Stepped On A Cornflake!!! Now I'm A Cereal Killer!
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

Maybe your S700i is using Big Endian then. Add this line right after line 18 to display the byte order.

Code: Select all

 MessageRequester("Endian", Hex(byteOrder))
It should look like this...

Code: Select all

byteOrder = ReadWord() 
  MessageRequester("Endian", Hex(byteOrder))
4949 = "II" = Intel = Little Endian
4D4D = "MM" = Motorola = Big Endian
Last edited by Sparkie on Thu Jun 16, 2005 2:10 pm, edited 2 times in total.
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
User avatar
GeoTrail
Addict
Addict
Posts: 2794
Joined: Fri Feb 13, 2004 12:45 am
Location: Bergen, Norway
Contact:

Post by GeoTrail »

Here's what I get when I try with my A60 and S700i

Endian
S700i returns: 0
A60 returns: 4949
I Stepped On A Cornflake!!! Now I'm A Cereal Killer!
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

hmmm.... can you post the hex for the first 16 bytes of an image from the S700i :?:
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
User avatar
GeoTrail
Addict
Addict
Posts: 2794
Joined: Fri Feb 13, 2004 12:45 am
Location: Bergen, Norway
Contact:

Post by GeoTrail »

Check your PM Sparkie.
I Stepped On A Cornflake!!! Now I'm A Cereal Killer!
traumatic
PureBasic Expert
PureBasic Expert
Posts: 1661
Joined: Sun Apr 27, 2003 4:41 pm
Location: Germany
Contact:

Post by traumatic »

Don't know if this helps but I'm getting correct values for my EOS 300d
images and "Sorry - Invalid file format!" with Finepix JPGs (little endian).
Good programmers don't comment their code. It was hard to write, should be hard to read.
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

@GeoTrail: S700i images are JFIF format and not Exif, therefore the header info is different. I'm not sure JFIF stores date info but I'm still looking into it.

@traumatic: Thanks for the info. :) I'm guessing your Finepix uses JFIF also. Take a look at bytes 06 - 09 and you'll probably see 4A 46 49 46 (JFIF)

The code I used here was just something I was using as a learning tool a while back. Since my images were in Little Endian and Exif, I didn't bother with Big Endian and JFIF. ;)
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

If JFIF stores image dates, I sure can't find any code to support it.

@GeoTrail: I'll put together a little GUI for changing the Exif dates and post it here this weekend (time permitting). ;)
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
User avatar
GeoTrail
Addict
Addict
Posts: 2794
Joined: Fri Feb 13, 2004 12:45 am
Location: Bergen, Norway
Contact:

Post by GeoTrail »

Cool, looking forward to it :)
I Stepped On A Cornflake!!! Now I'm A Cereal Killer!
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

Here's what I have so far. I was hoping to include a "batch change" feature, but I just didin't have the time to include here. :(

The batch change would come in handy for me, because at one point, my camera timestamp was off by -1 hour -6 minutes. The batch change will adjust/change dates on all selected files by adding/subtracting the time offset you choose, in my case +1 hour + 6 minutes.

This was tested using images from a Canon A75 and Olympus D550. It may or may not work with other cameras, so if it doesn't work for you, let me know the model of your camera and I'll see if I can get it to work for you. :)

Until this is code is perfected/debugged, please work with copies of your original image files. ;)

Code: Select all

UseJPEGImageDecoder() 
;--> Window Constants
Enumeration 1
  #Window_Main
EndEnumeration
;--> Gadget Constants
Enumeration 
  ;--> These must be 0, 1, 2
  #Date_Modified_Write
  #Date_Taken_Write
  #Date_Digitized_Write
  ;--> These can be any number
  #Date_All_Write
  #ExplorerTree_0
  #Frame3D_Thumb
  #ImageGad_Thumb
  #Frame3D_Modified
  #Text_Modified_Read
  #Text_New_0
  #Frame3D_Taken
  #Text_Taken_Read
  #Text_New_1
  #Frame3D_Digitized
  #Text_Digitized_Read
  #Text_New_2
  #Text_Date
  #Frame3D_All
  #Text_New_3
  #Button_Write
  #StatusBar_0
EndEnumeration
;--> Image Constants
#Image_No = 0
#Image_Thumb = 1
;--> DateGadget constants
#DTM_FIRST = $1000
#DTM_SETFORMATA = #DTM_FIRST + 5
#DTM_GETSYSTEMTIME = #DTM_FIRST + 1
#DTM_SETSYSTEMTIME = #DTM_FIRST + 2
#GDT_VALID = 0
;--> Exif Tag constants
#Exif_DT_Modified   = $132  ; 306 
#Exif_Sub           = $8769 ; 34665
#Exif_DT_Taken      = $9003 ; 36867
#Exif_DT_Digitized  = $9004 ; 36868
#Exif_Thumb_Offset  = $201  ; 513
#Exif_Thumb_Length  = $202  ; 514
#LittleEndian       = $4949 ; 18761
;--> Image Header size and Array constants
#Header             = 12 
#ModifiedDate       = 0
#TakenDate          = 1
#DigitizedDate      = 2
;--> Globals
Global dates
;--> Structures
Structure EXIF
  eDate.s
  eOffset.l
EndStructure
;--> Arrays
;--> This holds Exif data: The dates and their offsets
;--> We use this for writing new dates
Dim exifDate.EXIF(2)
;--> Procedure to reset Display
Procedure DisplayReset()
  SetGadgetState(#ImageGad_Thumb, UseImage(#Image_No))
  SetGadgetText(#Text_Modified_Read, "")
  SetGadgetText(#Text_Taken_Read, "")
  SetGadgetText(#Text_Digitized_Read, "")
  SetGadgetState(#Date_Modified_Write, 0)
  SetGadgetState(#Date_Taken_Write, 0)
  SetGadgetState(#Date_Digitized_Write, 0)
  DisableGadget(#Button_Write, 1)
  StatusBarText(#StatusBar_0, 0, "")
EndProcedure
;--> Procedure to set DateGadgets.
;--> PB doesn't support the seconds field so I use API
Procedure SetDate(gadget, date$)
  st.SYSTEMTIME
  st\wYear = Val(Left(date$, 4))
  st\wMonth = Val(Mid(date$, 6, 2))
  st\wDay = Val(Mid(date$, 9, 2))
  st\wHour = Val(Mid(date$, 12, 2))
  st\wMinute = Val(Mid(date$, 15, 2))
  st\wSecond = Val(Mid(date$, 18, 2))
  ;--> Set the text
  SendMessage_(GadgetID(gadget), #DTM_SETSYSTEMTIME, #GDT_VALID, st)
  ;--> Clear checkbox if All Dates is selected
  If GetGadgetState(#Date_All_Write) <> 0
    SetGadgetState(gadget, 0)
  EndIf
EndProcedure
;--> Procedure for reading Exif Dates
Procedure GetExif(ExifLoc)
  FileSeek(ExifLoc + #Header); + 2)
  exifEntries = ReadWord()
  For i = 1 To exifEntries
    tag = ReadWord() &$FFFF
    Select tag
      Case #Exif_DT_Taken
        ;--> We'll need to reset Loc after reading date string, so mark it.
        currentloc = Loc()
        ;--> By-pass tag type and length because we know it's
        ;--> Type = ASCII and Length = 20
        FileSeek(Loc() + 6)
        ;--> Get the offset to Date Taken string
        dateLoc = ReadLong()
        ;--> Move to that offset
        FileSeek(dateLoc + #Header)
        ;--> Put data into our Structure for future use
        exifDate(#TakenDate)\eOffset = Loc()
        exifDate(#TakenDate)\eDate = ReadString()
        ;--> Display Date Taken
        SetGadgetText(#Text_Taken_Read, exifDate(#TakenDate)\eDate)
        SetDate(#Date_Taken_Write, exifDate(#TakenDate)\eDate)
        dates = #True
        ;--> Move back to next tag
        FileSeek(currentloc + 10)
      Case #Exif_DT_Digitized
        ;--> We'll need to reset Loc after reading date string, so mark it.
        currentloc = Loc()
        ;--> By-pass tag type and length because we know it's
        ;--> Type = ASCII and Length = 20
        FileSeek(Loc() + 6)
        ;--> Get the offset to Date Digitized string
        dateLoc = ReadLong()
        ;--> Move to that offset
        FileSeek(dateLoc + #Header)
        ;--> Put data into our Structure for future use
        exifDate(#DigitizedDate)\eOffset = Loc()
        exifDate(#DigitizedDate)\eDate = ReadString()
        ;--> Display Date Digitized
        SetGadgetText(#Text_Digitized_Read, exifDate(#DigitizedDate)\eDate)
        SetDate(#Date_Digitized_Write, exifDate(#DigitizedDate)\eDate)
        dates = #True
        ;--> Move back to next tag
        FileSeek(currentloc + 10)
      Default
        ;--> We're skipping tags so move on to the next one
        FileSeek(Loc() + 10)
    EndSelect
  Next i
EndProcedure
;--> Proceure for reading thumbnail
Procedure GetThumb(thumbLoc)
  ;--> Go to thumbnail tags offset
  FileSeek(thumbLoc + #Header)
  ;--> get total entries
  entries = ReadWord()
  ;--> We're looking for thumbnail offset and size in bytes
  For i = 1 To entries
    tag = ReadWord() &$FFFF
    Select tag
      Case #Exif_Thumb_Offset
        ;--> Here's the starting offset for thumbnail
        FileSeek(Loc() + 6)
        thumbOffset = ReadLong()
      Case #Exif_Thumb_Length
        ;--> here's the length of thumbnail in bytes
        FileSeek(Loc() + 6)
        thumbLength = ReadLong()
      Default
        ;--> We're skipping some tags so move on to the next one
        FileSeek(Loc() + 10)
    EndSelect
  Next i
  FileSeek(thumbOffset + #Header)
  ;--> Read the thumbnail data into memory
  *thumb = AllocateMemory(thumbLength)
  ReadData(*thumb, thumbLength)
  ;--> Catch the thumbnail and put it into ImageGadget
  CatchImage(#Image_Thumb, *thumb)
  SetGadgetState(#ImageGad_Thumb, ImageID())
  FreeMemory(*thumb)
EndProcedure

Procedure GetInfo(jpg$, writeIt, newDateTime$) 
  OpenFile(0, jpg$) 
  ;--> Byte 0 of EXIF begins after JPEG header 
  FileSeek(#Header) 
  ;--> Bytes 0-1 is word order 18761 ($4949) is Intel and 19789 ($4D4D) is Motorola 
  byteOrder = ReadWord() 
  ;--> For now I only handle Little Endian
  If byteOrder = #LittleEndian 
    ; --> Bytes 2-3 is TIFF format, it's always 42 ($2A). If not, give up. 
    tifFormat = ReadWord()
    ;--> This is always $2A. If not, give up.
    If tifFormat = $2A 
      ;--> Bytes 4-7 is starting offset for IFD (Image File Directory) 
      ifd1 = ReadLong() 
      ;--> Move to start of IFD 
      FileSeek(ifd1 + #Header) 
      ;--> First 2 bytes of IFD is number of field entries 
      nFields = ReadWord() 
      ;--> Loop through all fields to find Date/Time stamp 
      For i = 1 To nFields 
        ;--> Bytes 0-1 contain the Tag for the field. 
        currentTag = ReadWord() &$FFFF
        Select currentTag
          Case #Exif_DT_Modified
            ;--> Bytes 2-3 contain the field Type. 
            ;--> We know this will be 2 (ASCII) For Date/Time 
            fieldType = ReadWord() 
            ;--> Bytes 4-7 contain the  Length of the field. 
            fieldLength = ReadLong() 
            ;--> We'll need to reset Loc after reading date string, so mark it.
            currentloc = Loc() 
            ;--> Bytes 8-11 contain a pointer to ASCII Date/Time 
            fieldValue = ReadLong() 
            ;--> Move to that pointer 
            FileSeek(fieldValue + #Header) 
            ;--> This is the start offset of Date/Time ASCII string 
            ;--> Put data into our Structure for future use
            exifDate(#ModifiedDate)\eOffset = Loc()
            exifDate(#ModifiedDate)\eDate = ReadString()
            ;--> Display date
            SetGadgetText(#Text_Modified_Read, exifDate(#ModifiedDate)\eDate)
            SetDate(#Date_Modified_Write, exifDate(#ModifiedDate)\eDate)
            dates = #True
            ;--> Go back to next tag
            FileSeek(currentloc + 4)
          Case #Exif_Sub
            ;--> Here's the offest to more Exif data tags
            FileSeek(Loc() + 6)
            exifStartLoc = ReadLong()
          Default
            ;--> Move to next field. Each field is 12 bytes. 
            ;--> currentTag (2 bytes) is current Loc() so we add 10 
            FileSeek(Loc() + 10) 
        EndSelect
      Next i
      ;--> Offset to thumbnail is after the last tag
      thumbStart = ReadLong()
      ;--> Go to Exif offset and get dates
      GetExif(exifStartLoc)
      ;--> Go to Thumbnail offset and read Thumbnail
      GetThumb(thumbStart)
      ;--> All done
      CloseFile(0) 
      exifResult = 1
    Else
      ;--> Wrong format, display Unavailable
      DisplayReset()
      exifResult = 0
    EndIf 
  Else
    ;--> Wrong byte order, display Unavailable
    DisplayReset()
    exifResult = 0
  EndIf
  ProcedureReturn exifResult
EndProcedure 
;--> Create image to display when no Exif found
CreateImage(#Image_No, 160, 120)
StartDrawing(ImageOutput())
DrawingMode(1)
FrontColor(255, 0, 0)
Locate(28, 50)
DrawText("Thumbnail n/a")
StopDrawing()
;--> Main window with gadgets
If OpenWindow(#Window_Main, 0, 0, 465, 500, #PB_Window_SystemMenu | #PB_Window_ScreenCentered, "Exif Dates") And CreateGadgetList(WindowID(#Window_Main))
  hSB = CreateStatusBar(#StatusBar_0, WindowID(#Window_Main))
  AddStatusBarField(WindowWidth())
  SendMessage_(hSB, #SB_GETRECT, 0, @sbRect.RECT)
  statusbarHeight = sbRect\bottom - sbRect\top
  ExplorerTreeGadget(#ExplorerTree_0, 0, 0, 220, 500 - statusbarHeight, "*.jpg;*.jpeg")
  SetWindowLong_(GadgetID(#ExplorerTree_0), #GWL_STYLE, GetWindowLong_(GadgetID(#ExplorerTree_0), #GWL_STYLE) | #TVS_SHOWSELALWAYS)
  ;--> Thumbnail
  Frame3DGadget(#Frame3D_Thumb, 230, 10, 225, 145, "Thumbnail")
  ImageGadget(#ImageGad_Thumb, 265, 25, 160, 120, UseImage(#Image_No))
  ;--> Date Modified
  Frame3DGadget(#Frame3D_Modified, 230, 160, 225, 75,"Date Modified")
  TextGadget(#Text_Modified_Read, 240, 180, 100, 22, "")
  TextGadget(#Text_New_0, 240, 210, 50, 22, "Change to")
  DateGadget(#Date_Modified_Write, 300, 205, 145, 22, "", Date(), #PB_Date_CheckBox|#PB_Date_UpDown)
  ;--> Date Taken
  Frame3DGadget(#Frame3D_Taken, 230, 240, 225, 75, "Date Taken")
  TextGadget(#Text_Taken_Read, 240, 260, 100, 22, "")
  TextGadget(#Text_New_1, 240, 290, 50, 22, "Change to")
  DateGadget(#Date_Taken_Write, 300, 285, 145, 22, "", Date(), #PB_Date_CheckBox | #PB_Date_UpDown)
  ;--> Date Digitized
  Frame3DGadget(#Frame3D_Digitized, 230, 320, 225, 75, "Date Digitized")
  TextGadget(#Text_Digitized_Read, 240, 340, 100, 22, "")
  TextGadget(#Text_New_2, 240, 370, 50, 22, "Change to")
  DateGadget(#Date_Digitized_Write, 300, 365, 145, 22, "", Date(), #PB_Date_CheckBox | #PB_Date_UpDown)
  ;--> All Dates
  Frame3DGadget(#Frame3D_All, 230, 400, 225, 45, "All Dates")
  TextGadget(#Text_New_3, 240, 420, 50, 22, "Change to")
  DateGadget(#Date_All_Write, 300, 415, 145, 22, "", Date(), #PB_Date_CheckBox | #PB_Date_UpDown)
  ;--> Write dates
  ButtonGadget(#Button_Write, 270, 455, 150, 20, "Write Selected Date(s)")
  DisableGadget(#Button_Write, 1)
  ;--> Clear checkboxes
  SetGadgetState(#Date_Modified_Write, 0)
  SetGadgetState(#Date_Taken_Write, 0)
  SetGadgetState(#Date_Digitized_Write, 0)
  SetGadgetState(#Date_All_Write, 0)
  ;--> Set format for DateGadgets
  dt$ = "yyyy':'MM':'dd HH':'mm':'ss"
  SendMessage_(GadgetID(#Date_Modified_Write), #DTM_SETFORMATA, 0, @dt$)
  SendMessage_(GadgetID(#Date_Taken_Write), #DTM_SETFORMATA, 0, @dt$)
  SendMessage_(GadgetID(#Date_Digitized_Write), #DTM_SETFORMATA, 0, @dt$)
  SendMessage_(GadgetID(#Date_All_Write), #DTM_SETFORMATA, 0, @dt$)
;-->Main Loop
quit = #False
  Repeat
    event = WaitWindowEvent()
    Select event
      Case #PB_Event_CloseWindow
        If EventWindowID() = #Window_Main
          quit = #True
        EndIf
      Case #PB_EventGadget
        Select EventGadgetID()
          Case #ExplorerTree_0
            currentFile$ = GetGadgetText(#ExplorerTree_0)
            fileExt$ = Left(LCase(GetExtensionPart(currentFile$)), 3)
            If EventType() = #PB_EventType_Change And fileExt$ = "jpg"
              dates = #False
              exif = GetInfo(currentFile$, 0, "") 
              If dates
                StatusBarText(#StatusBar_0, 0, currentFile$)
                DisableGadget(#Button_Write, 0)
              EndIf
            Else
              currentFile$ = ""
              DisplayReset()
            EndIf
          Case #Button_Write
            If currentFile$ And dates
              If OpenFile(0, currentFile$)
                For s = #Date_Modified_Write To #Date_Digitized_Write
                  If GetGadgetState(s) <> 0
                    newdate$ = GetGadgetText(s)
                    FileSeek(exifDate(s)\eOffset)
                    WriteString(newdate$)
                  ElseIf GetGadgetState(#Date_All_Write) <> 0
                    newdate$ = GetGadgetText(#Date_All_Write)
                    FileSeek(exifDate(s)\eOffset)
                    WriteString(newdate$)
                  EndIf
                Next s
                CloseFile(0)
              Else
                MessageRequester("Error", "Could not open requested file!", #MB_ICONEXCLAMATION)
              EndIf
            EndIf
            ;--> Sync date gadgets
            ;--> If All Dates is checked, dis-allow other DateGadgets being checked
          Case #Date_Modified_Write
            If GetGadgetState(#Date_All_Write) <> 0
              SetGadgetState(#Date_Modified_Write, 0)
            EndIf
          Case #Date_Taken_Write
            If GetGadgetState(#Date_All_Write) <> 0
              SetGadgetState(#Date_Taken_Write, 0)
            EndIf
          Case #Date_Digitized_Write
            If GetGadgetState(#Date_All_Write) <> 0
              SetGadgetState(#Date_Digitized_Write, 0)
            EndIf
          Case #Date_All_Write
            For g = #Date_Modified_Write To #Date_Digitized_Write
              If GetGadgetState(g) <> 0 
                SetGadgetState(g, 0)
              EndIf
              If GetGadgetState(#Date_All_Write) <> 0
                SetGadgetState(g, GetGadgetState(#Date_All_Write))
                SetDate(g, GetGadgetText(#Date_All_Write))
              EndIf
            Next g
        EndSelect
    EndSelect
  Until quit
EndIf
End
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
User avatar
GeoTrail
Addict
Addict
Posts: 2794
Joined: Fri Feb 13, 2004 12:45 am
Location: Bergen, Norway
Contact:

Post by GeoTrail »

Very nice work Sparkie.
It's working perfectly with both my A60 and my S700i pictures :)
A few images taken with the S700i doesn't get displayed in the preview though, but that's no biggie ;)

Again, thanks alot for all your work there bud :)
I Stepped On A Cornflake!!! Now I'm A Cereal Killer!
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

Thank you and you're welcome GeoTrail. :)

I'm surprised it works for the S700i but with only some thumbnails being displayed. :?

If you send me 1 pic that does show the thumbnail and 1 that does not, maybe I can see what's going wrong here.

My email at home is
sparkie-bark at sbcglobal.net
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
User avatar
GeoTrail
Addict
Addict
Posts: 2794
Joined: Fri Feb 13, 2004 12:45 am
Location: Bergen, Norway
Contact:

Post by GeoTrail »

Yes I'll do that.
Me, my girlfriend and my son is going to the Aquarium tomorrow, I'll take some pictures there and send you one that has thumbnail that works and one that doesn't work in the program :)
I Stepped On A Cornflake!!! Now I'm A Cereal Killer!
User avatar
GeoTrail
Addict
Addict
Posts: 2794
Joined: Fri Feb 13, 2004 12:45 am
Location: Bergen, Norway
Contact:

Post by GeoTrail »

Hi Sparkie. Just browsing through some old threads here.
Some of your codes here came in very handy tonight ;)

Thanks again for your work :)
I Stepped On A Cornflake!!! Now I'm A Cereal Killer!
Post Reply