private static AvifMetadata CreateAvifMetadata(Document doc) { byte[] exifBytes = null; byte[] iccProfileBytes = null; byte[] xmpBytes = null; Dictionary <MetadataKey, MetadataEntry> exifMetadata = GetExifMetadataFromDocument(doc); if (exifMetadata != null) { Exif.ExifColorSpace exifColorSpace = Exif.ExifColorSpace.Srgb; MetadataKey iccProfileKey = MetadataKeys.Image.InterColorProfile; if (exifMetadata.TryGetValue(iccProfileKey, out MetadataEntry iccProfileItem)) { iccProfileBytes = iccProfileItem.GetData(); exifMetadata.Remove(iccProfileKey); exifColorSpace = Exif.ExifColorSpace.Uncalibrated; } exifBytes = new ExifWriter(doc, exifMetadata, exifColorSpace).CreateExifBlob(); } XmpPacket xmpPacket = doc.Metadata.TryGetXmpPacket(); if (xmpPacket != null) { string packetAsString = xmpPacket.ToString(XmpPacketWrapperType.ReadOnly); xmpBytes = System.Text.Encoding.UTF8.GetBytes(packetAsString); } return(new AvifMetadata(exifBytes, iccProfileBytes, xmpBytes)); }
private static void AddAvifMetadataToDocument(Document doc, AvifReader reader, IByteArrayPool arrayPool) { byte[] exifBytes = reader.GetExifData(); if (exifBytes != null) { ExifValueCollection exifValues = ExifParser.Parse(exifBytes, arrayPool); if (exifValues != null) { exifValues.Remove(MetadataKeys.Image.InterColorProfile); // The HEIF specification states that the EXIF orientation tag is only // informational and should not be used to rotate the image. // See https://github.com/strukturag/libheif/issues/227#issuecomment-642165942 exifValues.Remove(MetadataKeys.Image.Orientation); foreach (MetadataEntry entry in exifValues) { doc.Metadata.AddExifPropertyItem(entry.CreateExifPropertyItem()); } } } CICPColorData?imageColorData = reader.ImageColorData; if (imageColorData.HasValue) { string serializedValue = CICPSerializer.TrySerialize(imageColorData.Value); if (serializedValue != null) { doc.Metadata.SetUserValue(CICPMetadataName, serializedValue); } } ImageGridMetadata imageGridMetadata = reader.ImageGridMetadata; if (imageGridMetadata != null) { string serializedValue = imageGridMetadata.SerializeToString(); if (serializedValue != null) { doc.Metadata.SetUserValue(ImageGridName, serializedValue); } } byte[] iccProfileBytes = reader.GetICCProfile(); if (iccProfileBytes != null) { doc.Metadata.AddExifPropertyItem(ExifSection.Image, unchecked ((ushort)ExifTagID.IccProfileData), new ExifValue(ExifValueType.Undefined, iccProfileBytes)); } byte[] xmpBytes = reader.GetXmpData(); if (xmpBytes != null) { XmpPacket xmpPacket = XmpPacket.TryParse(xmpBytes); if (xmpPacket != null) { doc.Metadata.SetXmpPacket(xmpPacket); } } }
private static WebPNative.MetadataParams CreateWebPMetadata(Document doc) { byte[] iccProfileBytes = null; byte[] exifBytes = null; byte[] xmpBytes = null; string colorProfile = doc.Metadata.GetUserValue(WebPMetadataNames.ColorProfile); if (!string.IsNullOrEmpty(colorProfile)) { iccProfileBytes = Convert.FromBase64String(colorProfile); } string exif = doc.Metadata.GetUserValue(WebPMetadataNames.EXIF); if (!string.IsNullOrEmpty(exif)) { exifBytes = Convert.FromBase64String(exif); } string xmp = doc.Metadata.GetUserValue(WebPMetadataNames.XMP); if (!string.IsNullOrEmpty(xmp)) { xmpBytes = Convert.FromBase64String(xmp); } if (iccProfileBytes == null || exifBytes == null) { Dictionary <ExifPropertyPath, ExifValue> propertyItems = GetMetadataFromDocument(doc); if (propertyItems != null) { ExifColorSpace exifColorSpace = ExifColorSpace.Srgb; if (propertyItems.TryGetValue(ExifPropertyKeys.Photo.ColorSpace.Path, out ExifValue value)) { propertyItems.Remove(ExifPropertyKeys.Photo.ColorSpace.Path); if (MetadataHelpers.TryDecodeShort(value, out ushort colorSpace)) { exifColorSpace = (ExifColorSpace)colorSpace; } } if (iccProfileBytes != null) { exifColorSpace = ExifColorSpace.Uncalibrated; } else { ExifPropertyPath iccProfileKey = ExifPropertyKeys.Image.InterColorProfile.Path; if (propertyItems.TryGetValue(iccProfileKey, out ExifValue iccProfileItem)) { iccProfileBytes = iccProfileItem.Data.ToArrayEx(); propertyItems.Remove(iccProfileKey); exifColorSpace = ExifColorSpace.Uncalibrated; } } if (iccProfileBytes != null) { // Remove the InteroperabilityIndex and related tags, these tags should // not be written if the image has an ICC color profile. propertyItems.Remove(ExifPropertyKeys.Interop.InteroperabilityIndex.Path); propertyItems.Remove(ExifPropertyKeys.Interop.InteroperabilityVersion.Path); } if (exifBytes == null) { exifBytes = new ExifWriter(doc, propertyItems, exifColorSpace).CreateExifBlob(); } } } if (xmpBytes == null) { XmpPacket xmpPacket = doc.Metadata.TryGetXmpPacket(); if (xmpPacket != null) { string xmpPacketAsString = xmpPacket.ToString(); xmpBytes = System.Text.Encoding.UTF8.GetBytes(xmpPacketAsString); } } if (iccProfileBytes != null || exifBytes != null || xmpBytes != null) { return(new WebPNative.MetadataParams(iccProfileBytes, exifBytes, xmpBytes)); } return(null); }
public JpegXmpPackets(XmpPacket main, XmpPacket extended, XmpPacket merged) { Main = main; Extended = extended; Merged = merged; }
protected override Document OnLoad(Stream input) { byte[] bytes = new byte[input.Length]; input.ProperRead(bytes, 0, (int)input.Length); Surface surface = GetOrientedSurface(bytes, out ExifValueCollection exifMetadata); bool disposeSurface = true; Document doc = null; try { doc = new Document(surface.Width, surface.Height); byte[] colorProfileBytes = WebPFile.GetColorProfileBytes(bytes); if (colorProfileBytes != null) { doc.Metadata.AddExifPropertyItem(ExifSection.Image, unchecked ((ushort)ExifTagID.IccProfileData), new ExifValue(ExifValueType.Undefined, colorProfileBytes)); } if (exifMetadata != null && exifMetadata.Count > 0) { ExifValue xResProperty = exifMetadata.GetAndRemoveValue(ExifPropertyKeys.Image.XResolution.Path); ExifValue yResProperty = exifMetadata.GetAndRemoveValue(ExifPropertyKeys.Image.YResolution.Path); ExifValue resUnitProperty = exifMetadata.GetAndRemoveValue(ExifPropertyKeys.Image.ResolutionUnit.Path); if (xResProperty != null && yResProperty != null && resUnitProperty != null) { if (MetadataHelpers.TryDecodeRational(xResProperty, out double xRes) && MetadataHelpers.TryDecodeRational(yResProperty, out double yRes) && MetadataHelpers.TryDecodeShort(resUnitProperty, out ushort resUnit)) { if (xRes > 0.0 && yRes > 0.0) { switch (resUnit) { case TiffConstants.ResolutionUnit.Centimeter: doc.DpuUnit = MeasurementUnit.Centimeter; doc.DpuX = xRes; doc.DpuY = yRes; break; case TiffConstants.ResolutionUnit.Inch: doc.DpuUnit = MeasurementUnit.Inch; doc.DpuX = xRes; doc.DpuY = yRes; break; } } } } foreach (KeyValuePair <ExifPropertyPath, ExifValue> item in exifMetadata) { ExifPropertyPath path = item.Key; doc.Metadata.AddExifPropertyItem(path.Section, path.TagID, item.Value); } } byte[] xmpBytes = WebPFile.GetXmpBytes(bytes); if (xmpBytes != null) { XmpPacket xmpPacket = XmpPacket.TryParse(xmpBytes); if (xmpPacket != null) { doc.Metadata.SetXmpPacket(xmpPacket); } } doc.Layers.Add(Layer.CreateBackgroundLayer(surface, takeOwnership: true)); disposeSurface = false; } finally { if (disposeSurface) { surface?.Dispose(); } } return(doc); }