Ejemplo n.º 1
0
        /// <summary>
        /// Returns the EXIF data.
        /// </summary>
        /// <returns>
        /// The <see cref="T:byte[]"/>.
        /// </returns>
        public byte[] GetData()
        {
            const uint startIndex = 0;

            IExifValue exifOffset = GetOffsetValue(this.ifdValues, this.exifValues, ExifTag.SubIFDOffset);
            IExifValue gpsOffset  = GetOffsetValue(this.ifdValues, this.gpsValues, ExifTag.GPSIFDOffset);

            uint ifdLength  = this.GetLength(this.ifdValues);
            uint exifLength = this.GetLength(this.exifValues);
            uint gpsLength  = this.GetLength(this.gpsValues);

            uint length = ifdLength + exifLength + gpsLength;

            if (length == 0)
            {
                return(Array.Empty <byte>());
            }

            // two bytes for the byte Order marker 'II' or 'MM', followed by the number 42 (0x2A) and a 0, making 4 bytes total
            length += (uint)ExifConstants.LittleEndianByteOrderMarker.Length;

            // first IFD offset
            length += 4;

            byte[] result = new byte[length];

            int i = 0;

            // The byte order marker for little-endian, followed by the number 42 and a 0
            ExifConstants.LittleEndianByteOrderMarker.CopyTo(result.AsSpan(start: i));
            i += ExifConstants.LittleEndianByteOrderMarker.Length;

            uint ifdOffset = (uint)i - startIndex + 4U;

            exifOffset?.TrySetValue(ifdOffset + ifdLength);
            gpsOffset?.TrySetValue(ifdOffset + ifdLength + exifLength);

            i = WriteUInt32(ifdOffset, result, i);
            i = this.WriteHeaders(this.ifdValues, result, i);
            i = this.WriteData(startIndex, this.ifdValues, result, i);

            if (exifLength > 0)
            {
                i = this.WriteHeaders(this.exifValues, result, i);
                i = this.WriteData(startIndex, this.exifValues, result, i);
            }

            if (gpsLength > 0)
            {
                i = this.WriteHeaders(this.gpsValues, result, i);
                i = this.WriteData(startIndex, this.gpsValues, result, i);
            }

            return(result);
        }
Ejemplo n.º 2
0
        public void SetValue(TestImageWriteFormat imageFormat)
        {
            Image <Rgba32> image = TestFile.Create(TestImages.Jpeg.Baseline.Floorplan).CreateRgba32Image();

            image.Metadata.ExifProfile.SetValue(ExifTag.Software, "ImageSharp");

            IExifValue <string> software = image.Metadata.ExifProfile.GetValue(ExifTag.Software);

            Assert.Equal("ImageSharp", software.Value);

            // ExifString can set integer values.
            Assert.True(software.TrySetValue(15));
            Assert.False(software.TrySetValue(15F));

            image.Metadata.ExifProfile.SetValue(ExifTag.ShutterSpeedValue, new SignedRational(75.55));

            IExifValue <SignedRational> shutterSpeed = image.Metadata.ExifProfile.GetValue(ExifTag.ShutterSpeedValue);

            Assert.Equal(new SignedRational(7555, 100), shutterSpeed.Value);
            Assert.False(shutterSpeed.TrySetValue(75));

            image.Metadata.ExifProfile.SetValue(ExifTag.XResolution, new Rational(150.0));

            // We also need to change this value because this overrides XResolution when the image is written.
            image.Metadata.HorizontalResolution = 150.0;

            IExifValue <Rational> xResolution = image.Metadata.ExifProfile.GetValue(ExifTag.XResolution);

            Assert.Equal(new Rational(150, 1), xResolution.Value);

            Assert.False(xResolution.TrySetValue("ImageSharp"));

            image.Metadata.ExifProfile.SetValue(ExifTag.ReferenceBlackWhite, null);

            IExifValue <Rational[]> referenceBlackWhite = image.Metadata.ExifProfile.GetValue(ExifTag.ReferenceBlackWhite);

            Assert.Null(referenceBlackWhite.Value);

            var expectedLatitude = new Rational[] { new Rational(12.3), new Rational(4.56), new Rational(789.0) };

            image.Metadata.ExifProfile.SetValue(ExifTag.GPSLatitude, expectedLatitude);

            IExifValue <Rational[]> latitude = image.Metadata.ExifProfile.GetValue(ExifTag.GPSLatitude);

            Assert.Equal(expectedLatitude, latitude.Value);

            int profileCount = image.Metadata.ExifProfile.Values.Count;

            image = WriteAndRead(image, imageFormat);

            Assert.NotNull(image.Metadata.ExifProfile);

            // Should be 3 less.
            // 1 x due to setting of null "ReferenceBlackWhite" value.
            // 2 x due to use of non-standard padding tag 0xEA1C listed in EXIF Tool. We can read those values but adhere
            // strictly to the 2.3.1 specification when writing. (TODO: Support 2.3.2)
            // https://exiftool.org/TagNames/EXIF.html
            Assert.Equal(profileCount - 3, image.Metadata.ExifProfile.Values.Count);

            software = image.Metadata.ExifProfile.GetValue(ExifTag.Software);
            Assert.Equal("15", software.Value);

            shutterSpeed = image.Metadata.ExifProfile.GetValue(ExifTag.ShutterSpeedValue);
            Assert.Equal(new SignedRational(75.55), shutterSpeed.Value);

            xResolution = image.Metadata.ExifProfile.GetValue(ExifTag.XResolution);
            Assert.Equal(new Rational(150.0), xResolution.Value);

            referenceBlackWhite = image.Metadata.ExifProfile.GetValue(ExifTag.ReferenceBlackWhite);
            Assert.Null(referenceBlackWhite);

            latitude = image.Metadata.ExifProfile.GetValue(ExifTag.GPSLatitude);
            Assert.Equal(expectedLatitude, latitude.Value);

            image.Metadata.ExifProfile.Parts = ExifParts.ExifTags;

            image = WriteAndRead(image, imageFormat);

            Assert.NotNull(image.Metadata.ExifProfile);
            Assert.Equal(8, image.Metadata.ExifProfile.Values.Count);

            Assert.NotNull(image.Metadata.ExifProfile.GetValue(ExifTag.ColorSpace));
            Assert.True(image.Metadata.ExifProfile.RemoveValue(ExifTag.ColorSpace));
            Assert.False(image.Metadata.ExifProfile.RemoveValue(ExifTag.ColorSpace));
            Assert.Null(image.Metadata.ExifProfile.GetValue(ExifTag.ColorSpace));

            Assert.Equal(7, image.Metadata.ExifProfile.Values.Count);
        }
Ejemplo n.º 3
0
        public void SetValue(TestImageWriteFormat imageFormat, int expectedProfileValueCount)
        {
            Image <Rgba32> image = TestFile.Create(TestImages.Jpeg.Baseline.Floorplan).CreateRgba32Image();

            image.Metadata.ExifProfile.SetValue(ExifTag.Software, "ImageSharp");

            IExifValue <string> software = image.Metadata.ExifProfile.GetValue(ExifTag.Software);

            Assert.Equal("ImageSharp", software.Value);

            // ExifString can set integer values.
            Assert.True(software.TrySetValue(15));
            Assert.False(software.TrySetValue(15F));

            image.Metadata.ExifProfile.SetValue(ExifTag.ShutterSpeedValue, new SignedRational(75.55));

            IExifValue <SignedRational> shutterSpeed = image.Metadata.ExifProfile.GetValue(ExifTag.ShutterSpeedValue);

            Assert.Equal(new SignedRational(7555, 100), shutterSpeed.Value);
            Assert.False(shutterSpeed.TrySetValue(75));

            image.Metadata.ExifProfile.SetValue(ExifTag.XResolution, new Rational(150.0));

            // We also need to change this value because this overrides XResolution when the image is written.
            image.Metadata.HorizontalResolution = 150.0;

            IExifValue <Rational> xResolution = image.Metadata.ExifProfile.GetValue(ExifTag.XResolution);

            Assert.Equal(new Rational(150, 1), xResolution.Value);

            Assert.False(xResolution.TrySetValue("ImageSharp"));

            image.Metadata.ExifProfile.SetValue(ExifTag.ReferenceBlackWhite, null);

            IExifValue <Rational[]> referenceBlackWhite = image.Metadata.ExifProfile.GetValue(ExifTag.ReferenceBlackWhite);

            Assert.Null(referenceBlackWhite.Value);

            var expectedLatitude = new Rational[] { new Rational(12.3), new Rational(4.56), new Rational(789.0) };

            image.Metadata.ExifProfile.SetValue(ExifTag.GPSLatitude, expectedLatitude);

            IExifValue <Rational[]> latitude = image.Metadata.ExifProfile.GetValue(ExifTag.GPSLatitude);

            Assert.Equal(expectedLatitude, latitude.Value);

            // todo: duplicate tags
            Assert.Equal(2, image.Metadata.ExifProfile.Values.Count(v => (ushort)v.Tag == 59932));

            image = WriteAndRead(image, imageFormat);

            Assert.NotNull(image.Metadata.ExifProfile);
            Assert.Equal(0, image.Metadata.ExifProfile.Values.Count(v => (ushort)v.Tag == 59932));

            Assert.Equal(expectedProfileValueCount, image.Metadata.ExifProfile.Values.Count);

            software = image.Metadata.ExifProfile.GetValue(ExifTag.Software);
            Assert.Equal("15", software.Value);

            shutterSpeed = image.Metadata.ExifProfile.GetValue(ExifTag.ShutterSpeedValue);
            Assert.Equal(new SignedRational(75.55), shutterSpeed.Value);

            xResolution = image.Metadata.ExifProfile.GetValue(ExifTag.XResolution);
            Assert.Equal(new Rational(150.0), xResolution.Value);

            referenceBlackWhite = image.Metadata.ExifProfile.GetValue(ExifTag.ReferenceBlackWhite);
            Assert.Null(referenceBlackWhite);

            latitude = image.Metadata.ExifProfile.GetValue(ExifTag.GPSLatitude);
            Assert.Equal(expectedLatitude, latitude.Value);

            image.Dispose();
        }