https://foro.gambas-es.org/viewtopic.php?f=17&t=7851&p=47345#p47345
-----------------------------------
tincho
Viernes, 03 Enero 2020, 00:49

Re: Alguna Libreria Para Leer Metadatos De Fotos.
-----------------------------------
Bueno ya esta, logre adaptar el código paara poder usarlo instanciado en otros programas.
[code linenumbers=false syntax=gambas]
' Gambas class file

Export

Private content_count As Integer
Private ifd As Integer

Public ctn As New Collection
'Private entry_count As Integer

Library "libexif:12.3.3"

Public Struct ExifData
  ifd[5] As Pointer
  data As Pointer
  size As Integer
  priv As Pointer
End Struct

Public Struct ExifEntry
  tag As Integer
  format_ As Integer
  components As Long
  data As Pointer
  size As Integer
  parent As Pointer
  priv As Pointer
End Struct

' ExifData *exif_data_new_from_file (const char *path)
' Allocate a new #Pointer and load EXIF data from a JPEG file.
Private Extern exif_data_new_from_file(path As String) As ExifData

' ExifByteOrder exif_data_get_byte_order  (ExifData *data)
' Return the byte order in use by this EXIF structure.
Private Extern exif_data_get_byte_order(data As ExifData) As Integer

' const char *exif_byte_order_get_name (ExifByteOrder order)
' Return a short, localized, textual name for the given byte order.
Private Extern exif_byte_order_get_name(order As Integer) As String

' void exif_data_foreach_content (ExifData *data, PointerForeachContentFunc func, void *user_data)
' Execute a function on each IFD in turn.
Private Extern exif_data_foreach_content(data As ExifData, func As Pointer, user_data As Pointer)

' void exif_content_foreach_entry (ExifContent *content, ExifContentForeachEntryFunc func, void *user_data)
' Executes function on each EXIF tag in this IFD in turn.
Private Extern exif_content_foreach_entry(content As Pointer, func As Pointer, user_data As Pointer)

' ExifIfd exif_content_get_ifd (ExifContent *c)
' Return the IFD number in which the given #ExifContent is found.
Private Extern exif_content_get_ifd(c As Pointer) As Integer

' const char *exif_entry_get_value (ExifEntry *entry, char *val, unsigned int maxlen)
' Return a localized textual representation of the value of the EXIF entry.
Private Extern exif_entry_get_value(entry As ExifEntry, _val As Pointer, maxlen As Integer) As String

' const char *exif_tag_get_name_in_ifd(ExifTag tag, ExifIfd ifd)
' Return a textual name of the given tag when found in the given IFD.
Private Extern exif_tag_get_name_in_ifd(tag As Integer, ifd As Integer) As String

' const char *exif_format_get_name (ExifFormat format)
' Return a textual representation of the given EXIF data type.
Private Extern exif_format_get_name(format_ As Integer) As String

' void exif_data_unref (ExifData *data)
Private Extern exif_data_unref(data As ExifData)

Public Sub _new()

End

Public Sub exifdat(f As String) As Collection

  Dim ed As ExifData
  'Dim jpg As String
  Dim callback_data As Pointer

  ctn.Clear

  'jpg = "/ruta/del/archivo.jpg"
  'Print "File immagine:   "; jpg
  If Exist(f) Then
    ed = exif_data_new_from_file(f)
    If IsNull(ed) Then Error.Raise("Errore !")
    '    Print "Ordine dei byte: "; exif_byte_order_get_name(exif_data_get_byte_order(ed))
    exif_data_foreach_content(ed, data_foreach_func, callback_data)
    exif_data_unref(ed)
  Endif

  Return Normalize(ctn)

End

Private Function Normalize(cn As Collection) As Collection

  Dim tg As Variant
  Dim co As New Collection

  For Each tg In cn
    Select cn.Key
      Case "Model"
        co.Add(tg, "CameraModel")
      Case "Make"
        co.Add(tg, "CameraMaker")
      Case "DateTimeOriginal", "Date/Time"
        co.Add(tg, "DateTimeOriginal")
      Case Else
        co.Add(tg, cn.Key)
    End Select
  Next

  If co.Exist("Resolution") = False Then
    If co.Exist("PixelXDimension") And co.Exist("PixelYDimension") Then
      co.Add(co["PixelXDimension"] & "X" & co["PixelYDimension"], "Resolution")
    Endif
  Endif

  Return co

End

Private Function data_foreach_func(content As Pointer, callback_data As Pointer)

  ifd = exif_content_get_ifd(content)
  'Print "  Content :"; content_count, "ifd= "; ifd

  exif_content_foreach_entry(content, content_foreach_func, callback_data)

  'Inc content_count

End

Private Function content_foreach_func(entry As Pointer, callback_data As Pointer)

  Dim buf As New Byte[2000]
  Dim ent As ExifEntry

  ent = entry

  exif_entry_get_value(entry, buf.Data, buf.Count)

  'Print "   Entry"; entry_count; ": "; exif_tag_get_name_in_ifd(ent.tag, ifd); "("; exif_format_get_name(ent.format_); ")"
  'Print "      Size, Comps: "; ent.size; ", "; ent.components
  'Print "      Value: "; exif_entry_get_value(ent, buf.Data, buf.Count)

  ctn.Add(exif_entry_get_value(ent, buf.Data, buf.Count), exif_tag_get_name_in_ifd(ent.tag, ifd))

  'Inc entry_count

End
[/code]
Le modifique algunas nombres de tag para que sea compatible con mis programas.
Al intentar leer metadatos de archivos de video no funciono. Supongo que la librería libexif no soportam mas que JPEG.
En este sitio dice que solo es para JPEG
https://libexif.github.io/api/exif-data_8h.html#ac3c2d86223d3b219bad7ab2d28d8b8d2
Así que de momento para otros formatos de archivo seguire usando la herramienta [b]Exiftool[/b] a travez de la terminal.
Uso shell ya que como es una libreria perl no se puede usar como [b]Extern[/b] verdad? o si se puede?

Saludos.


