internal void AddTag(ImageTag tag) { if ((tag.TagTypes & AllowedTypes) != tag.TagTypes) { throw new Exception(String.Format("Attempted to add {0} to an image, but the only allowed types are {1}", tag.TagTypes, AllowedTypes)); } if (tag is IFDTag) { Exif = tag as IFDTag; } else if (tag is XmpTag) { // we treat a IPTC-IIM tag as a XMP tag. However, we prefer the real XMP tag. // See comments in Jpeg/File.cs for what we should do to deal with this properly. if (Xmp != null && (tag is IIM.IIMTag || Xmp is IIM.IIMTag)) { var iimTag = tag as IIM.IIMTag; if (iimTag == null) { iimTag = Xmp as IIM.IIMTag; Xmp = tag as XmpTag; } if (string.IsNullOrEmpty(Xmp.Title)) { Xmp.Title = iimTag.Title; } if (string.IsNullOrEmpty(Xmp.Creator)) { Xmp.Creator = iimTag.Creator; } if (string.IsNullOrEmpty(Xmp.Copyright)) { Xmp.Copyright = iimTag.Copyright; } if (string.IsNullOrEmpty(Xmp.Comment)) { Xmp.Comment = iimTag.Comment; } if (Xmp.Keywords == null) { Xmp.Keywords = iimTag.Keywords; } } else { Xmp = tag as XmpTag; } } else { OtherTags.Add(tag); } all_tags = null; }
internal void AddTag(ImageTag tag) { if ((tag.TagTypes & AllowedTypes) != tag.TagTypes) { throw new Exception(String.Format("Attempted to add {0} to an image, but the only allowed types are {1}", tag.TagTypes, AllowedTypes)); } if (tag is IFDTag) { Exif = tag as IFDTag; } else if (tag is XmpTag) { if (Xmp != null && (tag is IIM.IIMTag || Xmp is IIM.IIMTag)) { var iimTag = tag as IIM.IIMTag; if (iimTag == null) { iimTag = Xmp as IIM.IIMTag; Xmp = tag as XmpTag; } if (string.IsNullOrEmpty(Xmp.Title)) { Xmp.Title = iimTag.Title; } if (string.IsNullOrEmpty(Xmp.Creator)) { Xmp.Creator = iimTag.Creator; } if (string.IsNullOrEmpty(Xmp.Copyright)) { Xmp.Copyright = iimTag.Copyright; } if (string.IsNullOrEmpty(Xmp.Comment)) { Xmp.Comment = iimTag.Comment; } if (Xmp.Keywords == null) { Xmp.Keywords = iimTag.Keywords; } } else { Xmp = tag as XmpTag; } } else { OtherTags.Add(tag); } all_tags = null; }
/// <summary> /// Gets a tag of a specified type from the current instance, /// optionally creating a new tag if possible. /// </summary> /// <param name="type"> /// A <see cref="TagLib.TagTypes" /> value indicating the /// type of tag to read. /// </param> /// <param name="create"> /// A <see cref="bool" /> value specifying whether or not to /// try and create the tag if one is not found. /// </param> /// <returns> /// A <see cref="Tag" /> object containing the tag that was /// found in or added to the current instance. If no /// matching tag was found and none was created, <see /// langword="null" /> is returned. /// </returns> public override TagLib.Tag GetTag(TagLib.TagTypes type, bool create) { foreach (Tag tag in ImageTag.AllTags) { if ((tag.TagTypes & type) == type) { return(tag); } } if (!create || (type & ImageTag.AllowedTypes) == 0) { return(null); } ImageTag new_tag = null; switch (type) { case TagTypes.JpegComment: new_tag = new JpegCommentTag(); break; case TagTypes.GifComment: new_tag = new GifCommentTag(); break; case TagTypes.Png: new_tag = new PngTag(); break; case TagTypes.TiffIFD: new_tag = new IFDTag(); break; case TagTypes.XMP: new_tag = new XmpTag(); break; } if (new_tag != null) { ImageTag.AddTag(new_tag); return(new_tag); } throw new NotImplementedException(String.Format("Adding tag of type {0} not supported!", type)); }
internal void RemoveTag(ImageTag tag) { if (tag is IFDTag) { Exif = null; } else if (tag is XmpTag) { Xmp = null; } else { OtherTags.Remove(tag); } all_tags = null; }
internal void AddTag(ImageTag tag) { if ((tag.TagTypes & AllowedTypes) != tag.TagTypes) { throw new Exception(String.Format("Attempted to add {0} to an image, but the only allowed types are {1}", tag.TagTypes, AllowedTypes)); } if (tag is IFDTag) { Exif = tag as IFDTag; } else if (tag is XmpTag) { Xmp = tag as XmpTag; } else { OtherTags.Add(tag); } all_tags = null; }
/// <summary> /// Load the properties of the specified MetaData object from the specified ImageTag. /// tagMain may be a CombinedImageTag (when working with a real image file) or an XmpTag (when working with an XMP file). /// Most of the data is read simply from the XmpTag (which is the Xmp property of the combined tag, if it is not tagMain itself). /// But, we don't want to pass combinedTag.Xmp when working with a file, because some files may have CopyRightNotice or Creator /// stored (only) in some other tag; /// and we need to handle the case where we only have an XmpTag, because there appears to be no way to create a /// combinedTag that just has an XmpTag inside it (or indeed any way to create any combinedTag except as part of /// reading a real image file). /// </summary> private static void LoadProperties(ImageTag tagMain, Metadata destinationMetadata) { destinationMetadata.CopyrightNotice = tagMain.Copyright; destinationMetadata.Creator = tagMain.Creator; XmpTag xmpTag = tagMain as XmpTag; if (xmpTag == null) xmpTag = ((CombinedImageTag) tagMain).Xmp; var licenseProperties = new Dictionary<string, string>(); if (xmpTag != null) { destinationMetadata.CollectionUri = xmpTag.GetTextNode(kNsCollections, "CollectionURI"); destinationMetadata.CollectionName = xmpTag.GetTextNode( kNsCollections, "CollectionName"); destinationMetadata.AttributionUrl = xmpTag.GetTextNode(kNsCc, "attributionURL"); var licenseUrl = xmpTag.GetTextNode(kNsCc, "license"); if (!string.IsNullOrWhiteSpace(licenseUrl)) licenseProperties["license"] = licenseUrl; var rights = GetRights(xmpTag); if (rights != null) licenseProperties["rights (en)"] = rights; } destinationMetadata.License = LicenseInfo.FromXmp(licenseProperties); //NB: we're loosing non-ascii somewhere... the copyright symbol is just the most obvious if (!string.IsNullOrEmpty(destinationMetadata.CopyrightNotice)) { destinationMetadata.CopyrightNotice = destinationMetadata.CopyrightNotice.Replace("Copyright �", "Copyright ©"); } //clear out the change-setting we just caused, because as of right now, we are clean with respect to what is on disk, no need to save. destinationMetadata.HasChanges = false; }
/// <summary> /// Set the copyright. This is tricky because when we do tagMain.Copyright = value, /// this sets the rights:default langauge to that string (as we wish), as well as setting /// copyright in any other tag that may be present and support it. We don't want to bypass /// setting copyright on other tags, so we need to set it on tagMain, not just do something /// to the xmp. /// However, taglib clears all other alternatives of rights when it does this. /// We don't want that, because it might include our rights statement, which we store in the /// English language alternative. /// This is probably excessively cautious for right now, since the only client of this method /// sets rights AFTER setting copyright; but I wanted a method that would be safe for any /// future use. /// (Though...it will need enhancing if we store yet more information in yet other alternatives.) /// </summary> /// <param name="file"></param> /// <param name="copyright"></param> void SetCopyright(ImageTag tagMain, string copyright) { XmpTag xmp = tagMain as XmpTag; if (xmp == null) xmp = ((CombinedImageTag)tagMain).Xmp; var oldRights = GetRights(xmp); tagMain.Copyright = copyright; if (oldRights != null) SetRights(xmp, oldRights); }
/// <summary> /// Save the properties of this in tagMain in a suitable form for writing to a file which we can read and LoadProperties from /// to recover the current state of this object. /// tagMain may be a CombinedImageTag (when working with a real image file) or an XmpTag (when working with an XMP file). /// Most of the data is stored simply in the XmpTag (which is the Xmp property of the combined tag, if it is not tagMain itself). /// But, we don't want to pass combinedTag.Xmp when working with a file, because setting CopyRightNotice and Creator directly /// on the combinedTag may save it in additional places that may be useful; /// and we need to handle the case where we only have an XmpTag, because there appears to be no way to create a /// combinedTag that just has an XmpTag inside it (or indeed any way to create any combinedTag except as part of /// reading a real file). /// </summary> void SaveInImageTag(ImageTag tagMain) { // Taglib doesn't care what namespace prefix is used for these namespaces (which it doesn't already know about). // It will happily assign them to be ns1 and ns2 and successfully read back the data. // However, exiftool and its clients, including older versions of this library, will only recognize the // cc data if the namespace has the 'standard' abbreviation. // I'm not sure whether the pdf one is necessary, but minimally it makes the xmp more readable and less unusual. // This is a bit of a kludge...I'm using a method that TagLib says is only meant for unit tests, // and modifying what is meant to be an internal data structure, bypassing the (internal) method normally used // to initialize it. But it gets the job done without requiring us to fork taglib. XmpTag.NamespacePrefixes["http://creativecommons.org/ns#"] = "cc"; XmpTag.NamespacePrefixes["http://ns.adobe.com/pdf/1.3/"] = "pdf"; XmpTag xmp = tagMain as XmpTag; if (xmp == null) xmp = ((CombinedImageTag) tagMain).Xmp; SetCopyright(tagMain, CopyrightNotice); tagMain.Creator = Creator; AddOrModify(xmp, kNsCollections, "CollectionURI", CollectionUri); AddOrModify(xmp, kNsCollections, "CollectionName", CollectionName); AddOrModify(xmp, kNsCc, "attributionURL", AttributionUrl); if (License != null && !string.IsNullOrWhiteSpace(License.Url)) AddOrModify(xmp, kNsCc, "license", License.Url); SetRights(xmp, License == null ? null : License.RightsStatement); }
internal void RemoveTag (ImageTag tag) { if (tag is IFDTag) Exif = null; else if (tag is XmpTag) Xmp = null; else OtherTags.Remove (tag); all_tags = null; }
internal void AddTag (ImageTag tag) { if ((tag.TagTypes & AllowedTypes) != tag.TagTypes) throw new Exception (String.Format ("Attempted to add {0} to an image, but the only allowed types are {1}", tag.TagTypes, AllowedTypes)); if (tag is IFDTag) Exif = tag as IFDTag; else if (tag is XmpTag) { // we treat a IPTC-IIM tag as a XMP tag. However, we prefer the real XMP tag. // See comments in Jpeg/File.cs for what we should do to deal with this properly. if (Xmp != null && (tag is IIM.IIMTag || Xmp is IIM.IIMTag)) { var iimTag = tag as IIM.IIMTag; if (iimTag == null) { iimTag = Xmp as IIM.IIMTag; Xmp = tag as XmpTag; } if (string.IsNullOrEmpty (Xmp.Title)) Xmp.Title = iimTag.Title; if (string.IsNullOrEmpty (Xmp.Creator)) Xmp.Creator = iimTag.Creator; if (string.IsNullOrEmpty (Xmp.Copyright)) Xmp.Copyright = iimTag.Copyright; if (string.IsNullOrEmpty (Xmp.Comment)) Xmp.Comment = iimTag.Comment; if (Xmp.Keywords == null) Xmp.Keywords = iimTag.Keywords; } else { Xmp = tag as XmpTag; } } else OtherTags.Add (tag); all_tags = null; }
internal void AddTag (ImageTag tag) { if ((tag.TagTypes & AllowedTypes) != tag.TagTypes) throw new Exception (String.Format ("Attempted to add {0} to an image, but the only allowed types are {1}", tag.TagTypes, AllowedTypes)); if (tag is IFDTag) Exif = tag as IFDTag; else if (tag is XmpTag) Xmp = tag as XmpTag; else OtherTags.Add (tag); all_tags = null; }