avatare Posted November 27, 2009 Posted November 27, 2009 I'm trying to write a file type plugin basically another raw to paint.net plugin but this one using WIC. I got the part of opening the image just working fine but i'm having issued getting the metadata to pass with the image since the Document.Metadata takes Property items has parameters and that object has no public constructor. This is the info i got for the exif data Title - /ifd/{ushort=270} Subject - /ifd/{ushort=270} Camera Maker - /ifd/{ushort=271} Camera Model -/ifd/{ushort=272} F-Stop - /ifd/{ushort=34665}/{ushort=34850} Exposure time - /ifd/{ushort=34665}/{ushort=33434} Exposure program - /ifd/{ushort=34665}/{ushort=34850} Exposure bias - /ifd/{ushort=34665}/{ushort=37380} Focal Lenght - /ifd/{ushort=34665}/{ushort=37386} Flash mode - /ifd/{ushort=34665}/{ushort=37385} Date Taken - /ifd/{ushort=306} Program Name - /ifd/{ushort=305} Width - /ifd/{ushort=256} Height - /ifd/{ushort=257} Resolution unit - /ifd/{ushort=296} iso - /ifd/{ushort=34665}/{ushort=34855} Quote My blog http://www.alfredoalvarez.com/blog My pictures http://avatare.deviantart.com
Rick Brewster Posted November 27, 2009 Posted November 27, 2009 The way that Paint.NET has to do this internally is to store a small image resource in its DLL which has an EXIF tag in it. Then, any time there is a need to construct a custom PropertyItem, we load the image, yank out a PropertyItem (any PropertyItem), then set the values to what's needed. So, you simply have to do the same thing yourself. (Do NOT use the methods in SystemLayer -- they are not for plugins. They do change, and your plugin will break.) I hadn't looked at this code in a loooooong time (the Metadata class). It's clearly showing its age. // System.Drawing.Imaging.PropertyItem does not have a public constructor // So, as per the documentation, we have to "steal" one. // Quite ridiculous. // This depends on PropertyItem.png being an embedded resource in this assembly. private static Image propertyItemImage; [MethodImpl(MethodImplOptions.Synchronized)] private static PropertyItem GetPropertyItem() { if (propertyItemImage == null) { Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("PaintDotNet.SystemLayer.PropertyItem.png"); propertyItemImage = Image.FromStream(stream); } PropertyItem pi = propertyItemImage.PropertyItems[0]; // this works because the PropertyItems property returns a copy pi.Id = 0; pi.Len = 0; pi.Type = 0; pi.Value = ArrayUtil.Empty(); return pi; } Quote The Paint.NET Blog: https://blog.getpaint.net/ Donations are always appreciated! https://www.getpaint.net/donate.html
avatare Posted November 27, 2009 Author Posted November 27, 2009 I've seen this hack (sorry to call it that but is weird tactic) before i'm going to see if there are any other options and will let you knwo what i ended up doing in my plugin. Btw the wrapper for WIC in .net seems rather incomplete which kind of disapointed me a bit. Alright an update on the current progress in case anyone is interested I can now insert string of any types and it works with the current metadata system. Retrieving the Property Item. ConstructorInfo[] constructor = typeof(PropertyItem).GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance); object[] objects = new object[0]; PropertyItem item = (PropertyItem)constructor[0].Invoke(objects); Passing the data for a string goes something like this string title = (string)metaData.GetQuery(@"/ifd/{ushort=270}"); //18 + (2 * number of characters) string lenght ASCIIEncoding encoding = new ASCIIEncoding(); itemList.Add(new ExifValue(270, encoding.GetByteCount(title), 2, encoding.GetBytes(title))); And then finally into document metadata Document currentDoc = Document.FromImage(; List items = new List(); foreach (ExifValue e in properties) { ConstructorInfo[] constructor = typeof(PropertyItem).GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance); object[] objects = new object[0]; PropertyItem item = (PropertyItem)constructor[0].Invoke(objects); item.Id = e.id; item.Len = e.len; item.Type = e.type; item.Value = e.value; items.Add(item); } currentDoc.Metadata.AddExifValues(items.ToArray()); I will keep going and see if i can pass all the data i'm interested on hopefully put a beta of this out tonight. Thanks for the help. Quote My blog http://www.alfredoalvarez.com/blog My pictures http://avatare.deviantart.com
Rick Brewster Posted November 27, 2009 Posted November 27, 2009 Oh I agree, it's a hack. System.Drawing and GDI+ are honestly not that great in many ways. Quote The Paint.NET Blog: https://blog.getpaint.net/ Donations are always appreciated! https://www.getpaint.net/donate.html
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.