예제 #1
0
        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));
        }
예제 #2
0
        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);
                }
            }
        }
예제 #3
0
        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;
 }
예제 #5
0
        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);
        }