Blog

  • First Steps Toward ExIf35 on Mac

    My first attempt to convert ExIf35 from .NET to Mono to run on Mac has not gone very well…

    Unhandled Exception: System.Reflection.TargetInvocationException:
    Exception has been thrown by the target of an invocation. —>
    System.OverflowException: Number overflow.
     at (wrapper managed-to-native)
    object:__icall_wrapper_mono_array_new_specific (intptr,int)
     at System.Drawing.Icon.InitFromStreamWithSize (System.IO.Stream
    stream, Int32 width, Int32 height) [0x00000]
     at System.Drawing.Icon..ctor
    (System.Runtime.Serialization.SerializationInfo info, StreamingContext
    context) [0x00000]
     at (wrapper managed-to-native)
    System.Reflection.MonoCMethod:InternalInvoke
    (object,object[],System.Exception&)
     at System.Reflection.MonoCMethod.Invoke (System.Object obj,
    BindingFlags invokeAttr, System.Reflection.Binder binder,
    System.Object[] parameters, System.Globalization.CultureInfo culture)
    [0x00000]
     — End of inner exception stack trace —
     at System.Reflection.MonoCMethod.Invoke (System.Object obj,
    BindingFlags invokeAttr, System.Reflection.Binder binder,
    System.Object[] parameters, System.Globalization.CultureInfo culture)
    [0x00000]
     at System.Reflection.MethodBase.Invoke (System.Object obj,
    System.Object[] parameters) [0x00000]
     at System.Runtime.Serialization.ObjectRecord.LoadData
    (System.Runtime.Serialization.ObjectManager manager,
    ISurrogateSelector selector, StreamingContext context) [0x00000]
     at System.Runtime.Serialization.ObjectManager.DoFixups () [0x00000]
     at System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadNextObject
    (System.IO.BinaryReader reader) [0x00000]
     at System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadObjectGraph
    (System.IO.BinaryReader reader, Boolean readHeaders, System.Object&
    result, System.Runtime.Remoting.Messaging.Header[]& headers) [0x00000]
     at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.NoCheckDeserialize
    (System.IO.Stream serializationStream,
    System.Runtime.Remoting.Messaging.HeaderHandler handler) [0x00000]
     at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize
    (System.IO.Stream serializationStream) [0x00000]
     at System.Resources.ResourceReader.ReadNonPredefinedValue
    (System.Type exp_type) [0x00000]
     at System.Resources.ResourceReader.ReadValueVer2 (Int32 type_index) [0x00000]
     at System.Resources.ResourceReader.LoadResourceValues
    (.ResourceCacheItem[] store) [0x00000]
     at System.Resources.ResourceReader+ResourceEnumerator.FillCache () [0x00000]
     at System.Resources.ResourceReader+ResourceEnumerator..ctor
    (System.Resources.ResourceReader readerToEnumerate) [0x00000]
     at System.Resources.ResourceReader.GetEnumerator () [0x00000]
     at System.Resources.ResourceSet.ReadResources () [0x00000]
     at System.Resources.ResourceSet.GetObjectInternal (System.String
    name, Boolean ignoreCase) [0x00000]
     at System.Resources.ResourceSet.GetObject (System.String name,
    Boolean ignoreCase) [0x00000]
     at System.Resources.RuntimeResourceSet.GetObject (System.String
    name, Boolean ignoreCase) [0x00000]
     at System.Resources.ResourceManager.GetObject (System.String name,
    System.Globalization.CultureInfo culture) [0x00000]
     at System.Resources.ResourceManager.GetObject (System.String name) [0x00000]
     at ExIF35.Form2.InitializeComponent () [0x00d04] in
    /home/curtis/Development/ExIF35/ExIF35/Form2.Designer.cs:334
     at ExIF35.Form2..ctor () [0x0002a] in
    /home/curtis/Development/ExIF35/ExIF35/Form2.cs:21
     at (wrapper remoting-invoke-with-check) ExIF35.Form2:.ctor ()
     at ExIF35.Program.Main () [0x0000b] in
    /home/curtis/Development/ExIF35/ExIF35/Program.cs:18

  • ExIf 35

    With all that has been going on with ExIf 35 and the amount I have blogged about it, it has occurred to me that I haven’t really introduced the app on my blog at all, outside of the problems I have been having with getting things working exactly the way that I want.

    First, a screenshot:

    The application is designed for film photographers (me) to store information about each exposure on a roll. The original intent of the application was to simply store the information into an XML file, but after that portion of the application was finished being written I added the ability for the application to write the information in the image file for the scanned negative or print. At some point I also decided that I wanted to keep up with lens information, which of course required me to learn a new skill of putting information into the files using XMP, what a joyful experience that was. Now the application is on the path to fully utilizing XMP, including contact information (I still have to put that feature in). I am also working on utilizing some custom fields in XMP that will store the information that is specific to the film process, such as the film type, developing chemicals used and the date the roll was developed. I intend to in the future (when the application has a web presence) to post the specifications for the custom fields that I utilize. In the future I may also add functionality for managing the rolls and not just the images on the rolls.

    This is the form used to add or edit images on a roll.

    This form is used to manage the lenses available to the exposures.

    Finally, this form will be used to write the information to the JPEG files. As you can see, it also allows the inclusion or not of other information.

     

    SourceForge Project: https://sourceforge.net/projects/exif35/

    Download From: https://sourceforge.net/projects/exif35/files/ (latest has Windows icon beside it)

  • Lens Information Stored

    Finally, I have managed to store lens information in my JPEG files! It isn’t using ExIf though, because honestly, it’s way too hard and would require me learning way too much information about how the Makernote segment of ExIf works. As an alternative, I am using XMP. XMP is an Adobe developed standard based on XML that is embedded into JPG files (or as a standalone beside RAW). I am so far using two fields of XMP that come from Microsoft’s standards used for Windows Vista/7’s image management tools, those are /xmp/MicrosoftPhoto:LensManufacturer and /xmp/MicrosoftPhoto:LensModel as well as /xmp/xmp:lens and /xmp/aux:Lens. I’ve gone from having 0 places for lens information to having 3 places for lens information. At this point I am just happy it’s in there, but now that I am using XMP, I have more places to put information which means I can allow for the option of storing more information in the files. I now have intentions on letting ExIf 35 store contact information in the files when the option is selected. Additional things I would like to store is things like the chemicals used in developing and a better way to do the film information, other than just a user comment area that states “Shot on ____ film”. Because things are moving more digital, I am likely to have to write my own schema addition to XMP and store the information. It’s likely that the only thing that will read those fields is ExIf 35 itself, but I’m hopeful that if it has to be done, I might be able to convince Flickr to adopt my schema addition as well, since it is quite likely it would be the only one anywhere near supporting film information. All of this information is relevant to the image, and it would be great to get it all in.

  • ExIf Lens Information

    I think I have managed to accomplish all that I wanted with ExIf except for one thing. I still want to store lens information in the ExIf info. Unfortunately, the only place to do that is MakerNotes, and I don’t know how to work with them. It is my understanding that I would have to pick a specific set of makernotes to use for this, but I’m not even sure how to go about that. Because of the nature of my project I am not tied down to one particular set of notes, but that also means that I don’t need all of the tags included in a full set. I can’t make heads or tails out of how makernotes function. Do I have to somehow specify what the notes are? Are there internal references between the notes that tell photo viewers what each tag is? I don’t have a clue and its starting to get to me. Is it possible to create my own maker notes? My guess on that is no, since everyone seems to be desperate to track down makernotes for every major camera ever created. I feel like I am Googling in circles at the moment trying to make things work.

  • What is deserving of film?

    What images are deserving of being stored on film? As I have only taken 7 exposures of film so far I have found myself thinking about this a good bit. I don’t think I would want to us film for special occasions, as there are way too many things that could go wrong, and yet, I don’t want to use film for frivolous photography because film is expensive. I suppose this puts film in the category of “serious art photography”, but I don’t like that, as I don’t think “serious” and “art” go together, one pollutes the other. I do believe I want to use film only for art photography and not for the other purposes mentioned. I still question what I should shoot as I don’t think I have ever thought about photography in this way. With clay I have to put a lot of effort and focus into what I do because the clay is precious. When thinking about it, film is even more precious because while you can make a bowl, even though it may be a bad bowl, it still has all of the basic properties of a bowl, it can hold things. With film, a bad exposure is just that, a bad exposure. I suspect my problem here in the question of what deserves film is more or less about my compositional skill, which at the moment is pretty non-existent. With digital I shoot until things look right, with film I don’t have that option. Perhaps it’s time for me to wander around with a viewfinder to my head and answer my own question.

  • The Many Ways to Flash (or Not to Flash)

    Just thought of adding some of the more fun flash codes to my ExIf tool, but have decided against it for now unless someone directly requests it. I am perfectly happy with the binary choice of 0 (Flash did not fire) or 1 (Flash fired). All of the other options are roughly as easy from a logical standpoint, but they are much harder to pass into my existing code for encoding into the ExIf of image files.

    0000.H = Flash did not fire.

    0001.H = Flash fired.

    0005.H = Strobe return light not detected.

    0007.H = Strobe return light detected.

    0009.H = Flash fired, compulsory flash mode

    000D.H = Flash fired, compulsory flash mode, return light not detected

    000F.H = Flash fired, compulsory flash mode, return light detected

    0010.H = Flash did not fire, compulsory flash mode

    0018.H = Flash did not fire, auto mode

    0019.H = Flash fired, auto mode

    001D.H = Flash fired, auto mode, return light not detected

    001F.H = Flash fired, auto mode, return light detected

    0020.H = No flash function

    0041.H = Flash fired, red-eye reduction mode

    0045.H = Flash fired, red-eye reduction mode, return light not detected

    0047.H = Flash fired, red-eye reduction mode, return light detected

    0049.H = Flash fired, compulsory flash mode, red-eye reduction mode

    004D.H = Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected

    004F.H = Flash fired, compulsory flash mode, red-eye reduction mode, return light detected

    0059.H = Flash fired, auto mode, red-eye reduction mode

    005D.H = Flash fired, auto mode, return light not detected, red-eye reduction mode

    005F.H = Flash fired, auto mode, return light detected, red-eye reduction mode

    On the other hand, I have decided to add all 21 types of light, since that seems more useful (and is less likely to give me a headache)

    1 = Daylight

    2 = Fluorescent

    3 = Tungsten (incandescent light)

    4 = Flash

    9 = Fine weather

    10 = Cloudy weather

    11 = Shade

    12 = Daylight fluorescent (D 5700 – 7100K)

    13 = Day white fluorescent (N 4600 – 5400K)

    14 = Cool white fluorescent (W 3900 – 4500K)

    15 = White fluorescent (WW 3200 – 3700K)

    17 = Standard light A

    18 = Standard light B

    19 = Standard light C

    20 = D55

    21 = D65

    22 = D75

    23 = D50

    24 = ISO studio tungsten

    255 = other light source

  • ExIf Bliss

    After a little more fighting, I finally got things about as far as I think I can. I do not have any lens information in yet, but as far as I can tell there is no officially supported tag for it, only things like Nikon’s maker note fields for it. It sucks, but unfortunately I am limited by the complexities of ExIf itself. I am starting to feel a bit like I am doing a lot of work for nothing, because in general I feel like I have no real results. I have not developed any of my own film and scanned it, so I won’t be able to do this with real images until I do.

    Camera: Nikon N80QD
    Exposure: 0.001 sec (1/1000)
    Aperture: f/2.8
    Focal Length: 50 mm
    ISO Speed: 400
    Flash: No Flash
    File Size: 5.7 kB
    File Type: JPEG
    MIME Type: image/jpeg
    Image Width: 554
    Image Height: 267
    Encoding Process: Baseline DCT, Huffman coding
    Bits Per Sample: 8
    Color Components: 3
    X-Resolution: 96 dpi
    Y-Resolution: 96 dpi
    Image Description: Test image for the Nikon N80QD
    Orientation: Horizontal (normal)
    Software: ExIf 35
    Date and Time (Modified): 2010:03:05 14:00:00
    Artist: Curtis M. Kularski
    Exposure Program: Aperture-priority AE
    Date and Time (Original): 2010:03:05 14:00:00
    Date and Time (Digitized): 2010:03:08 21:53:53
    Metering Mode: Average
    User Comment: Shot on Fujifilm Neopan 400
    Focal Length In35mm Format: 50 mm
  • ExIf Bytes

    I am victorious over ExIf! The documentation for ExIf overcomplicates things. While ExIf uses a lot of different types (0x1 through 0xA), it is possible to interact with most common values utilizing only 2 of these, 0x2 and 0x5. 0x2 is the null terminated string, and 0x5 is the 2 pair of Long Ints, acting as a rational. It would also seem that even though the documentation suggests that length only matters for 0x2, it cares for all of them, so it is a must to give the length of the byte array used to carry the long ints. A small error on my part was trying to convert directly from String (because I used System.Window.Forms.TextBox to get the information) to byte[] without passing through the intermediate int, or trying to convert to byte[] from double, which was very nasty. I learned these little tricks about things by reading in ExIf information in the application itself without the aid of any little helper apps that try to clean things up, it make the structure a lot more clear.

    For anyone else trying a similar exercise in futility, here is a bit of my code:


    if (Type == 0x2)

    {

    tmpProp.Len = value.Length + 1;

    value = value + nullChar;

    tmpProp.Value = ASCIIEncoding.ASCII.GetBytes(value);

    }

    else
    if (Type == 0x5)

    {

     


    Byte[] tmp1 = BitConverter.GetBytes(Convert.ToInt32(value.Split(‘/’)[0]));


    Byte[] tmp2 = BitConverter.GetBytes(Convert.ToInt32(value.Split(‘/’)[1]));


    Byte[] tmp3 = new
    Byte[tmp1.Length + tmp2.Length];

    tmp1.CopyTo(tmp3,0);

    tmp2.CopyTo(tmp3, tmp1.Length);

     

    tmpProp.Value = tmp3;

    tmpProp.Len = tmp3.Length;

    }

    I love C#, so simple, but yet such a pain in the ass, all at once.

  • The Downfall of Distance Education

    When I first started distance education (online) courses back in 2004 things were different than they are now. From that statement you might gather that things have improved, you know, something technical, so it has to have gotten better. The situation is quite the opposite. When I started online courses, I liked them better than lecture courses because they were better on many different aspects. Online instructors used to be specialized in what they did, they had a special affection for the online course delivery method. Often instructors would use such tools as web based chat, interactive websites and sometimes even video to keep students engaged in courses. The point being that the courses were actually web based courses, using the Internet as a key part of the instructional process and not just as the delivery method for the course. Now courses seem to be more structured like independent study courses that merely utilize the Internet as a method for sending in papers or taking quizzes. There is no instruction and often instructors are primarily lecturers looking to pick up a few extra hours on their schedule. To students, these instructors barely exist. I have a hard time remembering the names of my instructors because of their lack of interaction. I remember a time when I took online courses and I had a message in my inbox from an instructor at least once a week, sometimes more. Instructors would do things like send out links that may be of interest, or some little personal observation about course performance. Now the courses are pretty much forced to run themselves. It is quite a sad change. I feel as though the changes in the way online courses have been treated will eventually cause the online method to either be terminated, or force them into a completely different accreditation status.

    I believe the change in the way distance education courses have been taught in recent years has a lot to do with adult learners wanting to complete degrees. Those adult students do not want a lot of a materials to handle, or any type of interaction, they just want to do the reading for the course, take the test, and then get a meaningless piece of paper to stick on the wall. I do not believe those students truly want an education, they want a degree. With that downturn of academic ambition there isn’t a lot of reason for instructors to be involved or to do much more than a copy/paste online course in Blackboard. The courses are technically capable of running themselves, they can grade a lot of their own material and they can handle operating on a schedule, no intervention required, but do we really want to change the way academic institutions are structured to have students interacting with a course and not an instructor? If this pattern continues, that’s what will happen, no more instructors, just courses and “course designers” (the people that presently prepare courses for instructors).

    I hope that when I begin my masters program I won’t find the same thing in graduate courses as I am finding in undergrad courses.

  • Still an ExIf No Go

    I am still trying to wrap my head around everything in ExIf. The Strings are no big deal, they just convert cleanly to byte arrays and go into the file, but I don’t even know where to begin making things the right format for everything else. If anyone can make any sense of this, please see the documents below, and if you think you can help, request to be added to the project on SourceForge so you can have SVN access to active code.

    http://msdn.microsoft.com/en-us/library/system.drawing.imaging.propertyitem.type.aspx Defines the types I am forced into using

    http://www.exif.org/samples/nikon-e950.html Gives some examples of the fields and their values (still not helpful, since it doesn’t give me the raw input form)

    http://msdn.microsoft.com/en-us/library/ms534418%28VS.85%29.aspx The tags, in order, that VS supports.

    http://exif35.svn.sourceforge.net/viewvc/exif35/ExIF35/ My source code. Feel free to poke around.

     

    The problem:

    Everything has to be converted to an array of bytes (byte[]). I do not know how to get things like 1/100, 2.8/1 and 50/1 into the proper forms (see first link above) to put them into the byte array. I am just so incredibly frustrated at this point.