0

I am trying to modify / write to property items that are rational. One Exif property that is rational is the Exposure Time:

enter image description here

Information from EXIF Tags: 0x829a, ExposureTime, rational64u, ExifIFD

I have however run into a roadblock and don't know how to continue. I have managed to read the Exposure time from an image. Unfortunatly I am having some issues understanding how I would change the value and set it.

Code for reading the Exposure Time:

Public Class Class1
    Private Image As Bitmap ' I have code to get the filepath of the image, which I didn't include here.

    Public Function RationalRead()
        Dim item = Image.GetPropertyItem(&H829A)

        Dim Num = BitConverter.ToUInt32(item.Value, 0)
        Dim Denom = BitConverter.ToUInt32(item.Value, 4)
        Dim expostime = Num & "/" & Denom
        Return expostime
    End Function

End Class

Code I have so far to write the Exposure Time:

Public Class Class1
    Private Image As Bitmap ' I have code to get the filepath of the image, which I didn't include here.

    Public Sub RationalWrite()

        Dim item = Image.PropertyItems(&H829A)
        Dim Num = BitConverter.ToUInt32(item.Value, 0) ' I would need to be able to change the value inside the first bit here to something different.
        Dim Denom = BitConverter.ToUInt32(item.Value, 4) ' I would need to be able to change the value inside the fourth bit here to something different.

        Dim ImageProperty As Imaging.PropertyItem = Image.PropertyItems(0)
        ImageProperty.Id = &HA404 ' The Metatag ID to modify (in our case ExposureTime)
        ImageProperty.Value = ' Here I would need to combine Num and Denom so that ImageProperty.Value can read the bits.
        ImageProperty.Type = 5 ' The 5 stands for UnsignedRational
        ImageProperty.Len = 8 ' I don't know if this should be 7 or 8.
        Image.SetPropertyItem(ImageProperty)

    End Sub

End Class

Any help with my "chaos" will be appreciated!

  • 1
    The U-Rational is a 8-bytes value in platform specific order. Right after the EXIF header, you need to read the *Endianness* (JPEG uses Motorola - Bid Endian- byte order, for example) If the value is `II` (double `I`) means Intel (LittleEndian), if it's `MM` (double `M`) then it's Motorola (Big Endian). For this reason, you usually read the values as 2 byte arrays (HI-Lo), then reverse the arrays content if not based on the current Platform endianness (you can use `BitConverter.IsLittleEndian`). The final U-Rational `.Value` is a double. In VB.Net can be `CDbl(numerator) / CDbl(denominator)` – Jimi Aug 29 '19 at 12:30
  • 1
    BTW1, I didn't get this: `ImageProperty.Id = &HA404`. BTW2, you can create a new PropertyItem with `Dim propItem = DirectCast(System.Runtime.Serialization.FormatterServices.GetUninitializedObject(GetType(PropertyItem)), PropertyItem)`. – Jimi Aug 29 '19 at 12:37
  • That cleared it up a bit. I am still quite new to working with bytes. I just have trouble understanding how, for instance &HA404 stores the values and how to retrieve them and modify them. Super thankful for the answer. –  Aug 29 '19 at 12:39
  • The `ImageProperty.Id = &HA404` code is used to set the ID for when I am overwriting the Exif Metadata. It does work. I have managed to get the code overwriting Strings, however there is no luck with Rationals. –  Aug 29 '19 at 12:40
  • What I want to do is actually "rather simple", I essentially want to modify the Exif Metadata Value of (&HA404). The problem is that I really don't understand how to write new data into the byte array. –  Aug 29 '19 at 12:42
  • 1
    There's no `0xA404` PropertyItem. Are you mixing Value and ID? --- You know that the `Numerator` is stored in the first 4 bytes, the `Denominator` in the other 4 (as 2 `UInt32` values). Stuff these 2 values in 2 byte arrays and verify the *Endianness*: if it's the opposite of the current, use `Array.Reverse()` to change the order. – Jimi Aug 29 '19 at 12:55
  • Wow, you are teaching me a whole bunch of things I didn't know. Oh I see, you are indeed correct 0xA404 is not a propertyItem. I must have removed "Get" from the line before posting, this is `Image.GetPropertyItem(&H829A)` what I meant. –  Aug 29 '19 at 12:58
  • Would you mind giving me an example on how I can set the value modify the values that &H829A in the byte array, and create a new byte array? –  Aug 29 '19 at 13:00
  • 1
    Update: I solved it thanks to your guidance! Incredible! Thank you for all the help! –  Aug 29 '19 at 14:01

0 Answers0