This project has moved and is read-only. For the latest updates, please go here.

Support for additional IPTC metadata records

Dec 7, 2016 at 12:39 PM
Edited Dec 7, 2016 at 12:47 PM
I was wondering if we could expand the support for custom IPTC fields. News agencies and editing software often override existing fields or use additional IPTC records for many purposes, i.e. "original filename" (from photographer) or "negative number" (scanned photos). I personally use up to 40 of these custom records. Until now, I was using either my custom IPTC library or ExifTool with custom configuration. Magick seems to work really well in .NET applications and the only problem is how it handles these non-standard IPTC.

Let's say we have a picture that has these 7 IPTC records:
2.5 (0x05 title),
2.80 (0x50 by-line),
2.120 (0x78 caption),
2.183 (0xB7 FotoWare character encoding),
2.215 (0xD7 CustomField16),
2.222 (0xDE Custom-222),
2.224 (0xE0 Custom-224), 2.22

ImageMagick/Magick.NET does not recognize some of them. The non-standard fields that are not listed in IptcTag enum all have 0xFF tag, instead of appropriate one. Because of this, after being edited by Magick.NET they are not recognized by other software. This is how IptcProfile looks after opening such file:
1C 02 00 00 02 00 02 
1C 02 05 00 05 74 69 74 6C 65 
1C 02 50 00 06 61 75 74 68 6F 72 
1C 02 78 00 07 63 61 70 74 69 6F 6E 
1C 02 FF 00 07 43 50 5F 31 32 35 30 <-- should be 0xB7
1C 02 D7 00 07 67 61 6C 6C 65 72 79 
1C 02 FF 00 02 6E 6F <-- should be 0xDE
1C 02 FF 00 0D 6F 72 69 67 69 6E 61 6C 20 6E 61 6D 65 <-- should be 0xE0
Perhaps it would be enough to add all missing IptcTag enum values, like: IptcTag183 = 183, IptcTag224 = 224 etc. up until 254. Even if these records are not in IPTC standard, it would allow other applications to read files modified by Magick.NET. At this moment it's impossible to integrate apps with Magick.NET into our workflow because of this.

This sample image was edited by FotoWare FotoStation and can be downloaded from: here (for the above example I have deleted one IPTC tag 2.240, added by default by FotoStation). Also this entire question is strictly about IPTC, not XMP.
Dec 7, 2016 at 5:28 PM
I think the issue is on this line: https://github.com/dlemstra/Magick.NET/blob/7a3d0fa6ecf0ba2a75e2224acab954be338c11f3/Magick.NET/Core/Profiles/Iptc/IptcProfile.cs#L48. Instead of parsing the enum I should just cast it to an IptcTag. I will try to this fix tomorrow but feel free to send me a pull request for this change here: https://github.com/dlemstra/Magick.NET/pulls.
Dec 9, 2016 at 2:03 PM
I would love to help, but not sure if I understand. If the resulting object in this line is IptcTag then they're limited to whatever values IptcTag enum has listed. I believe it would require adding non-standard tags to IptcTag (i.e IptcTag.Undefined224 - which is what I'll try to do now). Otherwise it needs a bit more changes... like maybe changing IptcTag enum to IptcTag class without limited set of values.
Dec 9, 2016 at 2:37 PM
An enumeration is simply an integer that you can represent with a name. And enumerations are not limited to the known values. The following example will demonstrate this:
using System;
                    
public class Program
{
    private enum IptcTag
    {
        Title = 5
    }
    
    public static void Main()
    {
        Write(5);
        Write(6);
    }
    
    private static void Write(byte value)
    {       
        IptcTag tag = (IptcTag) value;
        Console.WriteLine("{0} = {1}", (int)tag, tag.ToString());
    }
}
It will produce the following output:
5 = Title
6 = 6
This means that changing IptcTag tag = EnumHelper.Parse((int)Data[i++], IptcTag.Unknown); to IptcTag tag = (IptcTag)Data[i++]; should solve your issue.
Dec 9, 2016 at 3:54 PM
Edited Dec 9, 2016 at 3:55 PM
I see you made the changes on github. Thanks for helping me out. I will merge your changes if you send me pull request.
Dec 12, 2016 at 11:02 AM
Edited Dec 12, 2016 at 11:03 AM
I've made change, but uploaded it too early. New to git.

Either way, I'm unable to build Magick.NET with VSExpress 2015. Checkout.cmd ends with asking me to "TYPE:" something, followed by errors no matter what. Alternatively, unzipping libs from Dropbox also doesn't seem to help. Building entire solution results in 3 successes and 1 fail - for Magick.NET.Native I get "LNK1104: cannot open file CORE_RL_bzlib_.lib" even though the file exists. I have tried putting CORE_RL_bzlib_.lib etc. in 3 places: ImageMagick/lib/CORE_RL_bzlib_.lib, ImageMagick/lib/x86/CORE_RL_bzlib_.lib and ImageMagick/lib/lib/x86/CORE_RL_bzlib_.lib and neither of these seemed to work. Magick.NET.Native fails, however Magick.NET-Q16-x86.dll seems to build, but if I use it in other project I get: System.DllNotFoundException - can't load DLL 'Magick.NET-Q16-x86.Native.dll' can't find module. I don't know what I'm doing wrong here.
Dec 12, 2016 at 11:15 AM
It seems I was using the wrong folder structure when copying the files to and from DropBox. You should download the zip file again and copy it to the ImageMagick folder.
Dec 12, 2016 at 2:25 PM
Edited Dec 12, 2016 at 2:26 PM
It compiles now, thanks!

Now I was able to build Native dll, but encountered some other problems - can't build AnyCPU and attached x86-Q16.dll still results in DllNotFoundException for Native.dll, which can't be attached. Is it OK for me to post details here or should I perhaps put it in another thread? I don't know if it's me doing something wrong or some minor issues with project. Either way it could help someone else.
Dec 12, 2016 at 3:24 PM
AnyCPU works a bit different. You will need to run Tools\GenerateAnyCPU.cmd before you compile it. I have merged your pull request and your fix will be available in the next version of Magick.NET.
Dec 12, 2016 at 3:49 PM
I've tried referencing Magick.NET-Q16-x86.dll in my project and I can use the library, but the moment I try to build it, I get:
An unhandled exception of type 'System.DllNotFoundException' occurred in Magick.NET-Q16-x86.dll
Additional information: Unable to load DLL 'Magick.NET-Q16-x86.Native.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
I thought I wouldn't need Native anymore, but I also can't add reference to Magick.NET-Q16-x86.Native.dll, because it returns:
A reference to the "C:\...\bin\Release\Q16\Win32\Magick.NET-Q16-x86.Native.dll" could not be added.Please make sure that the file is accessible and that it is a valid assembly or COM component.
On the other hand, running GenerateAnyCPU.cmd ends with http://imgur.com/a/vqG8M and press any key to continue. After that I can't load AnyCPU project in Visual Studio: Magick.NET.AnyCPU.csproj : error : The required attribute "Include" is empty or missing from the element <Compile>.

Sorry for taking so much of your time here. I'm just really optimistic about this library, but it's also a little complicated :)
Dec 12, 2016 at 4:12 PM
Ok, it seems manually putting Magick.NET-Q16-x86.Native.dll in Debug/Release folders solved the error and it runs now.