Menu

Visual Basic 6 - Anyone with metadata sample?

Help
Don Juane
2011-10-12
2013-02-20
  • Don Juane

    Don Juane - 2011-10-12

    I have spent a lot of time downloading and trying to use various VB6 examples
    to obtain photo metadata. I have downloaded and tested literally every example
    that exists online today and I have never found one that works on 100% of the
    JPG files I encounter. Most of these JPG files are from newer Canon & Nikon
    cameras and some of them have been edited and saved with Photoshop will a call
    to enter Copyright information into the JPG. Sometimes my routine that calls
    these API xxxxx.bas modules will run weeks without encountering a problem JPG
    and sometimes only a few days. But time is irrelevant because eventually there
    is always one rouge JPG that will cause one of the API calls to abend. The
    strange thing is that programs such as iRfanView always show the correct EXIF
    information even when the user contributed API module abends. I am not good
    enough with API debugging or with understanding the structure of EXIF to debug
    API classes and modules that extract or edit the EXIF data.

    I also tried using the windows shell to extract "Date Picture Taken" metadata
    from a JPG and my tests failed. I am assuming that one must have configured
    the viewer for the particular folder being scanned to display these attributes
    or the data is not available via a shell call either.

    This frustration has led me to search for something else, maybe a DLL that is
    more reliable for extracting EXIF data. I first found a GDI+ wrapper for VB6
    but with no examples written in VB6 I was not able extract "Date Picture
    Taken" or any photo metadata. Examples in Visual Basic 6 seem non existent for
    GDI+ (GDIPlus).

    Recently I finally found FreeImage with a VB6 wrapper with high hopes. It
    support for EXIF but I am in the same situation as GDI+ because I can only
    find one example written in VB6 and all it has included is 3 lines of code,
    one to open FreeImage, another to convert a TIFF to a PNG file, and a third
    line to close FreeImage.

    Can someone supply me with more VB6 examples to extract metadata from a JPG. I
    will take any other examples you have as well. I found the .NET sample to
    enumerate metadata but I am not understanding .NET well enough to translate
    that to VB6.

    Thanks in advance for any examples or hints. (Please posters requesting I
    switch to .NET - I am holding off for a little longer thanks.)

     
  • Carsten Klein

    Carsten Klein - 2011-10-12

    Hi Don Juane,

    basically, it is very easy to get an image's metadata with the FreeImage VB6
    wrapper. However, interpreting and so actually using EXIF metadata is much
    more complicated.

    With the VB6 wrapper, you have a VB-friendly structure FREE_IMAGE_TAG, which
    provides you the metadata information, one for each metadata tag. Basically,
    with FreeImage, a single metadata tag corresponds to a single line in
    IrfanView's EXIF information window. Each tag has several fields, that contain
    its type, value(s), key (name), description and id.

    Especially with EXIF metadata, most of the information is stored by means of
    reference numbers. I recommend having a look at the EXIF 2.2 specifiaction at
    http://www.exif.org/specifications.html
    However, this document does not directly relate to FreeImage's metadata
    models, but can give you hints on how to interpret the values of the tags.

    The fields Description, Key and Id or FREE_IMAGE_TAG correspondent to 'Tag
    Name', 'Field Name' and 'Tag ID' of the various tables in the EXIF
    specification (Table 4 at 4.6.5 Exif IFD Attribute Information for example)
    respectively.

    Field StringValue of FREE_IMAGE_TAG is the result of function
    FreeImage_TagToString, which interprets most of the tags accordingly. However,
    this only results in a string value, which may make it difficult to work with
    in an application (read more about FreeImage_TagToString in the FreeImage API
    documentation).

    It depends on field 'Type', which of the various value fields are filled with
    data. Expect for tags of type FIDT_ASCII (String type), field 'Count' contains
    the number of values of the tag. If 'Count' is greater than 1, the actual
    value is an array from 0 to 'Count' - 1. For FIDT_ASCII typed tags, 'Count'
    contains the length of the string.

    Field 'Value' is a Variant in VB and contains the properly typed value of the
    tag for most tag types (expect for types FIDT_PALETTE and FIDT_(S)RATIONAL).

    Tag of type FIDT_(S)RATIONAL are always represented as an array (even if
    'Count' is 1, which results in an array with only one member with index 0).
    Field 'RationalValue', which is an array of FIRATIONAL, which in turn contains
    both numerator and denominator of the value. In that case, field 'Value' also
    contains an array of of type Double which holds an approximated value of the
    rational (expressed as an IEEE double precision floating value, Double in VB).

    Also in FreeImage, metadata is divided into several metadata models. Each
    model represents a number of tags, that belong to a certain type of metadata.

    FIMD_COMMENTS = 0 single comment or keywords*)
    FIMD_EXIF_MAIN = 1 Exif-TIFF metadata
    FIMD_EXIF_EXIF = 2 Exif-specific metadata
    FIMD_EXIF_GPS = 3 Exif GPS metadata
    FIMD_EXIF_MAKERNOTE = 4 Exif maker note metadata
    FIMD_EXIF_INTEROP = 5 Exif interoperability metadata
    FIMD_IPTC = 6 IPTC/NAA metadata
    FIMD_XMP = 7 Abobe XMP metadata
    FIMD_GEOTIFF = 8 GeoTIFF metadata
    FIMD_ANIMATION = 9 Animation metadata
    FIMD_CUSTOM = 10 Used to attach other metadata types to an image
    FIMD_EXIF_RAW = 11 Exif metadata as a raw buffer

    Not all of these models contain real metadata. For example, FIMD_ANIMATION is
    contains an animated GIF's animation data. Read more about FreeImage's
    metadata handling in the official FreeImage API documentation.

    *) Image comment: you can use the FreeImage_Get/SetimageComment functions to access an image's comment more convenient than using the metadata functions explained below.

    Actually, the information you are interested in, is stored in the
    FIMD_EXIF_EXIF model. In EXIF as well as in FreeImage, the tag is named
    "DateTimeOriginal" and has the id 36867. It is of type FIDT_ASCII, so the date
    actually is encoded as a string value. According to the EXIF 2.2
    specification, the date's format is "YYYY:MM:DD HH:MM:SS" with time shown in
    24-hour format.

    Getting all the tags for a certain metadata model with the FreeImage VB6
    wrapper is easy. I'll give you a short example, that you could use to get the
    creation date of the image.

    Dim hBitmap As Long
    Dim Tags() As FREE_IMAGE_TAG
    Dim i As Long
    
       Call FreeImage_InitErrorHandler
    
       ' Load the image
       hBitmap = FreeImage_LoadEx("C:\images\MyExifImage.jpg")
    
       ' Get all the tags of model FIMD_EXIF_EXIF. Returns the number of tags found.
       If (FreeImage_GetAllMetadataTags(FIMD_EXIF_EXIF, hBitmap, Tags) > 0) Then
    
          ' We got some tags. Iterate over the tags and watch out for tag "DateTimeOriginal"
          For i = 0 To UBound(Tags)
             With Tags(i)
                If (.Key = "DateTimeOriginal") Then
                   Debug.Print "Image created date: " & .Value
                End If
             End With
          Next i
       End If
    
       ' Don't forget to unload the image.
       Call FreeImage_UnloadEx(hBitmap)
    

    Hope this helps.

    Carsten

     
  • Don Juane

    Don Juane - 2011-10-13

    Excellent!!! Thank you! This was frustrating and I apologize for missing this.
    My problem is that I am a learn by example programmer, but maybe that makes me
    not a programmer after all but a hacker or some such euphemism :-) What would
    be a better word for that, maybe Structure Plagiarist or Cliff Notes Scholar,
    or any number of good ones :-) . Thanks again.

    Now that I hope you have accepted my apology, would you be up for an iteration
    of FIMD_EXIF_MAKERNOTE? I spent the whole day and came up with nothing. I
    don't think that all the definitions are in the MFreeImage.bas but I am quite
    often wrong :-) :-)

     
  • Don Juane

    Don Juane - 2013-02-20

    I am now working on another project. I still need to find the camera model from the exif data. These are the only keys that I find available from the GetAllMetaTags call in your example:

    CameraOwnerName
    ColorSpace
    ComponentsConfiguration
    CompressedBitsPerPixel
    CustomRendered
    DateTimeDigitized
    DateTimeOriginal
    DigitalZoomRatio
    ExifVersion
    ExposureBiasValue
    ExposureMode
    ExposureTime
    FNumber
    FileSrc
    Flash
    FlashPixVersion
    FocalLength
    FocalPlaneResolutionUnit
    FocalPlaneXResolution
    FocalPlaneYResolution
    ISOSpeedRatings
    MaxApertureValue
    MeteringMode
    PixelXDimension
    PixelYDimension
    SceneCaptureType
    SensingMethod
    ShutterSpeedValue
    Tag 0x8830
    UserComment
    WhiteBalance

    The JPG is created with Canon S100. irFanview shows the data OK. I tried some of the ExifReader.cls files I found here and they crash on the new Canon JPG. Old model Canons are OK as well as Nikon.

    UPDATE!!!!!!!!!!!!!!!!

    I got it! Coming into using this from the bottom side up and the help here from the topside down (:-), I finally figured out to change the call above to FIMD_EXIF_MAIN and I printed out the results from 3 model cameras JPG examples .... (iteration through the key chain)

    DateTime = 2013:01:27 20:15:16
    ImageDescription =
    Make = Canon
    Model = Canon PowerShot S100
    Orientation = 6
    ResolutionUnit = 2
    YCbCrPositioning = 2
    ===========
    Artist =
    Copyright =
    DateTime = 2012:12:09 19:39:41
    Make = NIKON CORPORATION
    Model = NIKON D7000
    Orientation = 1
    ResolutionUnit = 2
    Software = Ver.1.02
    YCbCrPositioning = 2
    ===========
    DateTime = 2010:10:05 16:24:47
    Make = Canon
    Model = Canon PowerShot SD850 IS
    Orientation = 1
    ResolutionUnit = 2
    YCbCrPositioning = 1
    ===========

    'Code to produce above: __
    On Error Resume Next
    Dim workPath as string
    Dim dib As Long
    Dim Tags() As FREE_IMAGE_TAG

    workPath = "C:\yourfolder\yourfile.jpg"

    'Assumed: MFreeImage.bas is named in our "Module" list
    'Optional: We could iterate through a folder of files
    'with the block below using FSO:
    'Send subject image name and location to freeimage dll:
    dib = FreeImage_Load(FIF_JPEG, workPath, 0)
    'Get all the tags of FIMD_EXIF_MAIN. Returns the number of tags found.
    If (FreeImage_GetAllMetadataTags(FIMD_EXIF_MAIN, dib, Tags) > 0) Then
    ' We got some tags. List them all out
    For i = 0 To UBound(Tags)
    With Tags(i)
    Debug.Print " >>>> " & .Key & " = " & .Value
    If .key = "Model" Then Msgbox "Model is: " & .value
    End With
    Next i
    Debug.Print "============="
    End If
    FreeImage_Unload (dib)

     

    Last edit: Don Juane 2013-02-20

Log in to post a comment.

Auth0 Logo