Author Topic: .NET "wrapper" dll  (Read 21145 times)

brain2cpu

  • Newbie
  • *
  • Posts: 8
.NET "wrapper" dll
« on: September 13, 2013, 08:27:20 AM »
Hi all,
I'd like to add my little contribution to this wonderful project, so here comes ExiftoolWrapper, a .NET dll with source code (C#), to bring a step closer exiftool to .NET developers.
The main goal was to use the "-stay_open” flag in the most transparent way. 
The simplest usage example would be:

Code: [Select]
#using BBCSharp;

using(ExifToolWrapper extw = new ExifToolWrapper())
{
    extw.Start();
    Dictionary<string, string> d = extw.FetchExifFrom(@"d:\Temp\D800-DSC_8059.NEF");
}

The dictionary above will contain all data exfitool can extract. The Start method loads exiftool(-k).exe (must be in your application's startup folder in case of the parameterless constructor), Dispose will stop it. Start needs some time, so this approach is advised when you need to extract exif from multiple files.
Binary and source code are free to use in any way you like (though I'll appreciate an email just to let me know).

After download please replace the empty exiftool(-k).exe files in the archive with the real one, posting the full zip (around 7MB) fails.

PH Edit: See this post for the most recent version of the wrapper.
« Last Edit: January 10, 2017, 07:05:25 AM by Phil Harvey »

Phil Harvey

  • ExifTool Author
  • Administrator
  • ExifTool Freak
  • *****
  • Posts: 11830
    • ExifTool Home Page
Re: .NET "wrapper" dll
« Reply #1 on: September 13, 2013, 08:37:17 AM »
Nice!  I have added a link from the ExifTool home page.

- Phil
...where DIR is the name of a directory containing the images.  On Mac/Linux, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

rajesh

  • Newbie
  • *
  • Posts: 1
Re: .NET "wrapper" dll
« Reply #2 on: January 03, 2014, 04:19:02 AM »
I have to updated exif keywords but not able to update IPTC keywords using C#.
Please let me know to can get Exif keyword's value and add to IPTC keywords?

thanks

iaremrsir

  • Newbie
  • *
  • Posts: 4
Re: .NET "wrapper" dll
« Reply #3 on: December 20, 2014, 11:29:53 PM »
Hello, I've tried using your wrapper with success in reading metadata, but I'd like to be able to write metadata as well, which I'm having a hard time with. I've easily used your FetchExifFrom function. But now I'm trying to write metadata using the SendCommand function and it does nothing when I send strings to it.

Here's what my code block looks like now. Reading works fine, but I just can't write anything. My goal is to edit 3 tags of all DNG files in a directory. Any advice?
Code: [Select]
using (ExifToolWrapper exiftool = new ExifToolWrapper())
{
  exiftool.Start();
  foreach (string dir in workingDir)
  {
    // Get first DNG to check for ISO 100
    string[] dng = System.IO.Directory.GetFiles(dir, "*.dng");
    if (dng.Length == 0) continue;

    Dictionary<string, string> exif = exiftool.FetchExifFrom(dng[0]);

    // Build EXIF write command
    string command = "\n-Exif:BaselineExposure=2.4 " + dir + "\\*.dng\n-Exif:CalibrationIlluminant1=\"Standard Light A\" " + dir + "\\*.dng\n-Exif:CalibrationIlluminant2=\"D65\" " + dir + "\\*.dng\n";
    if (100 == Convert.ToInt32(exif["Exposure Index"]))
      command += "-Exif:WhiteLevel=3660 " + dir + "\\*.dng\n-stay_open\nFalse\n";

    exiftool.SendCommand(command);
  }
}

Phil Harvey

  • ExifTool Author
  • Administrator
  • ExifTool Freak
  • *****
  • Posts: 11830
    • ExifTool Home Page
Re: .NET "wrapper" dll
« Reply #4 on: December 21, 2014, 09:45:21 AM »
I have no idea what you are trying to do, and I don't know how the DLL API works, but you are not being consistent in the arguments you are sending exiftool.  Either the API takes arguments from a -argfile intput separated by newlines (likely), or as a command line separated by spaces.  You have done both.  I suspect that the code should look more like this (but I am just guessing):

Code: [Select]
    string command = dir + "\\*.dng\n-Exif:BaselineExposure=2.4\n-Exif:CalibrationIlluminant1=\"Standard Light A\"\n-Exif:CalibrationIlluminant2=\"D65\"\n";
    if (100 == Convert.ToInt32(exif["Exposure Index"]))
      command += "-Exif:WhiteLevel=3660\n";

    exiftool.SendCommand(command);

Also, I'm not sure why you were doing -stay_open False, and why this was only if the exposure index was 100, but I have removed this.

- Phil
...where DIR is the name of a directory containing the images.  On Mac/Linux, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

iaremrsir

  • Newbie
  • *
  • Posts: 4
Re: .NET "wrapper" dll
« Reply #5 on: January 01, 2015, 04:26:37 PM »
I have no idea what you are trying to do, and I don't know how the DLL API works, but you are not being consistent in the arguments you are sending exiftool.  Either the API takes arguments from a -argfile intput separated by newlines (likely), or as a command line separated by spaces.  You have done both.  I suspect that the code should look more like this (but I am just guessing):

Code: [Select]
    string command = dir + "\\*.dng\n-Exif:BaselineExposure=2.4\n-Exif:CalibrationIlluminant1=\"Standard Light A\"\n-Exif:CalibrationIlluminant2=\"D65\"\n";
    if (100 == Convert.ToInt32(exif["Exposure Index"]))
      command += "-Exif:WhiteLevel=3660\n";

    exiftool.SendCommand(command);

Also, I'm not sure why you were doing -stay_open False, and why this was only if the exposure index was 100, but I have removed this.

- Phil

I'm trying to add metadata to a directory of Cinema DNG files, but I haven't been able to write a string to send to the wrapper that actually does anything. So thanks for the suggestion, I'll try it to see how it works.

iaremrsir

  • Newbie
  • *
  • Posts: 4
Re: .NET "wrapper" dll
« Reply #6 on: January 01, 2015, 04:39:03 PM »
Okay so the string you gave me worked for a single command. The string only added -Exif:BaselineExposure, and it ignored the rest of the commands. So I think I'll have to split the command calling into loop of some sort. Anyway that fixed the problem of writing metadata, but now I have a new problem. Writing to the DNG files caused exiftool to automatically create a .dng_original file for each dng. I read the documentation and remember seeing the command line argument -overwrite_original. Would I want to add this to the command I send to stay open or could I just add it to the argument list that starts the exiftool process?

iaremrsir

  • Newbie
  • *
  • Posts: 4
Re: .NET "wrapper" dll
« Reply #7 on: January 01, 2015, 05:04:24 PM »
Okay, so adding -overwrite_original to the arguments list of the wrapper worked. But splitting the string that Phil suggested into singular commands didn't work. I'm going to fiddle around some more and update if I figure something out. Thanks for the help.

brain2cpu

  • Newbie
  • *
  • Posts: 8
Re: .NET "wrapper" dll
« Reply #8 on: January 26, 2015, 06:00:55 AM »
I'd like to post ExiftoolWrapper v2; main changes: direct get/set for orientation, get creation date as DateTime, the SetExifInto method, thread-safe communication with the exiftool process; you can find more in the attached source code.

PH Edit: See this post for the most recent version of the wrapper.
« Last Edit: January 10, 2017, 07:05:46 AM by Phil Harvey »

CodeWorks

  • Newbie
  • *
  • Posts: 2
Re: .NET "wrapper" dll
« Reply #9 on: May 22, 2015, 04:46:47 PM »
SetExifInto isn't working.   What am i doing wrong?    The code executes with no errors but the metadata doesn't update.

            using (ExifToolWrapper extw = new ExifToolWrapper())
            {
                // Start ExifTool
                extw.Start();
                // Get Metadata
                Dictionary<string, string> d = extw.FetchExifFrom(Application.StartupPath + "/photos/SAI01.jpg");
                // Remove existing Lens Model
                d.Remove("Lens Model");
                // Add new Lens Model
                d.Add("Lens Model", "lens1234");
                //Write new Metadata
                extw.SetExifInto(Application.StartupPath + "/photos/SAI01.jpg", d, true);
            }

Thanks

Phil Harvey

  • ExifTool Author
  • Administrator
  • ExifTool Freak
  • *****
  • Posts: 11830
    • ExifTool Home Page
Re: .NET "wrapper" dll
« Reply #10 on: May 22, 2015, 10:21:38 PM »
I'm no expert on this interface, but I would guess that it should use tag names, in which case you should use "LensModel" and not "Lens Model" (ie. remove the space).  If this is the problem, reading ExifTool FAQ 2 may help in determining the appropriate tag names to use.

- Phil
...where DIR is the name of a directory containing the images.  On Mac/Linux, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

brain2cpu

  • Newbie
  • *
  • Posts: 8
Re: .NET "wrapper" dll
« Reply #11 on: May 26, 2015, 02:45:51 AM »
Dictionary<string, string> d = extw.FetchExifFrom(Application.StartupPath + "/photos/SAI01.jpg");
.........
d.Add("Lens Model", "lens1234");
extw.SetExifInto(Application.StartupPath + "/photos/SAI01.jpg", d, true);
You can see existing tags as keys of dictionary d, you should check if you really have "Lens Model". Arbitrary keys and values can not be set as exif tags!
SetExifInto returns true if succeeded, please check returned value.
If you want to modify a single key the
SetExifInto(string path, string key, string val, bool overwriteOriginal = true)
method should be used, the override above will try to overwrite all tags with existing values.

CodeWorks

  • Newbie
  • *
  • Posts: 2
Re: .NET "wrapper" dll
« Reply #12 on: May 26, 2015, 05:26:01 PM »
Thanks Phil and brain2cpu.   Removing the space between "Lens Model" worked.

I put a space in it because all the existing tags as Keys (such as "Lens Model") in dictionary d have a space.   Weird.  Perhaps FetchExifFrom isn't using the exact spelling of the Tag name for the Key name.

Thanks again


SarahC

  • Newbie
  • *
  • Posts: 5
Re: .NET "wrapper" dll
« Reply #13 on: May 27, 2015, 04:03:50 AM »
brain2cpu, could you spare half an hour to help me work through this hanging problem I've got?   :)

I'm using your wonderful wrapper with my cataloging system - but I've got a hanging problem I've not been able to trace.

Would you be able to give me some pointers about what may be happening?

Thank you so much!   :D


http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,6524.0.html


(I've just noticed you've released a V2 of it - I've not had a chance to try that one.)

brain2cpu

  • Newbie
  • *
  • Posts: 8
Re: .NET "wrapper" dll
« Reply #14 on: May 27, 2015, 05:51:22 AM »
SarahC, I just downloaded your source code and noticed you converted the C# code to vb, did you tried using the dll instead? I'm using it in my mp3Manager without problems.

SarahC

  • Newbie
  • *
  • Posts: 5
Re: .NET "wrapper" dll
« Reply #15 on: June 02, 2015, 03:45:15 AM »
SarahC, I just downloaded your source code and noticed you converted the C# code to vb, did you tried using the dll instead? I'm using it in my mp3Manager without problems.

Sorry, I've been away from my dev environment!

I'll try that, for sure! That may have cured it - but the error only occurs on huge lists - is your MP3 collection large?

(and how do I get notifications on here?! I'm off to check "properties".)

rkamarowski

  • Newbie
  • *
  • Posts: 2
Re: .NET "wrapper" dll
« Reply #16 on: January 23, 2016, 01:49:31 PM »
I'm getting the following error when the Start() method is executed:

The specified executable is not a valid application for this OS platform.

Code: [Select]
                ExifToolWrapper etw = new ExifToolWrapper();

                etw.Start();

I'm running VS 2015 on Windows 10

brain2cpu

  • Newbie
  • *
  • Posts: 8
Re: .NET "wrapper" dll
« Reply #17 on: January 23, 2016, 03:16:57 PM »
Did you replaced the dummy exiftool exe with the real one?

rkamarowski

  • Newbie
  • *
  • Posts: 2
Re: .NET "wrapper" dll
« Reply #18 on: January 23, 2016, 04:47:51 PM »
ugh... thank you!

lyrico

  • Newbie
  • *
  • Posts: 1
Re: .NET "wrapper" dll
« Reply #19 on: November 16, 2016, 03:11:59 PM »
Sorry to resurrect an old thread.  I've been playing around with the tool and it works great :)  However, I was wondering if there's any way to pass in a stream to a file instead of the physical file itself?  Often case, the only thing I get is a byte array of the file.  So instead of saving all the bytes to a temporary file, I would like to just pass in that byte array as a stream.

Thanks!

Phil Harvey

  • ExifTool Author
  • Administrator
  • ExifTool Freak
  • *****
  • Posts: 11830
    • ExifTool Home Page
Re: .NET "wrapper" dll
« Reply #20 on: November 16, 2016, 03:41:54 PM »
This is a basic functionality for the Image::ExifTool Perl library, but unfortunately the .NET wrapper goes through the exiftool application.  Here, the only thing you could possibly do would be to create some sort of pipe from your bytes array (which may be possible with .NET, I don't know), but then you would probably run into troubles with the .NET wrapper not supporting pipes (I'm guessing the wrapper probably uses pipes for the command-line arguments, and if so you probably can't pipe the images too).

So without knowing how the .NET wrapper works, I am guessing that it won't do what you want.

You could, however, launch ExifTool directly piping the image if you can figure out how to do that, without the ExifTool .NET wrapper.

- Phil
...where DIR is the name of a directory containing the images.  On Mac/Linux, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

brain2cpu

  • Newbie
  • *
  • Posts: 8
Re: .NET "wrapper" dll
« Reply #21 on: November 17, 2016, 04:22:03 AM »
Unfortunately the wrapper does not support byte array, it works with filenames only.

macdonnie

  • Newbie
  • *
  • Posts: 1
Re: .NET "wrapper" dll
« Reply #22 on: December 05, 2016, 08:59:44 PM »
Fantastic Tool and Wrapper!

I'm using the wrapper and the code executes until I call SetExifInto(). At that point my C# code pauses and will not continue. Am I doing something wrong? Do I need to call the function in a different manner or is it something else?

Some notes:
1) I can see that d is being populated and changed properly.
2) The SetExifInto is working and changing the 'Make' in the image's properties
3) When I call Start() two different exittool(-k).exes start up. And remain open the whole time. The first one has a memory footprint of 44MBs and the 2nd has a memory footprint of 0.6MBs


Code: [Select]
        public static void writeTag5()
        {
            using (BBCSharp.ExifToolWrapper extw = new ExifToolWrapper())
            {
                // Start ExifTool
                extw.Start();
                // Get Metadata
                Dictionary<string, string> d = extw.FetchExifFrom("C:\\Users\\donal\\Desktop\\P1020661_Fixed_b_w2.jpg");
                // Remove existing Lens Model
                d.Remove("Make");
                // Add new Lens Model
                d.Add("Make", "testing");
                //Write new Metadata
                extw.SetExifInto("C:\\Users\\donal\\Desktop\\P1020661_Fixed_b_w2.jpg", d, true);

            }
        }

Thanks,
-Don

brain2cpu

  • Newbie
  • *
  • Posts: 8
Re: .NET "wrapper" dll
« Reply #23 on: December 06, 2016, 03:40:48 AM »
Everything seems alright in your code and notes, but it is not the best way to do it. You should send to SetExifInto() only things you want to change:
Code: [Select]
extw.SetExifInto("C:\\Users\\donal\\Desktop\\P1020661_Fixed_b_w2.jpg", new Dictionary<string, string> { ["Make"] = "testing" }, true);
however the code should not stop.

brain2cpu

  • Newbie
  • *
  • Posts: 8
Re: .NET "wrapper" dll
« Reply #24 on: January 10, 2017, 05:48:07 AM »
Please use this new version, a possible stall in SetExifInto is fixed.