Browse Source

Attempt at making frame metadata public

pull/1553/head
James Jackson-South 5 years ago
parent
commit
4094be1647
  1. 7
      src/ImageSharp/Formats/Tiff/MetadataExtensions.cs
  2. 33
      src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs
  3. 13
      src/ImageSharp/Formats/Tiff/TiffDecoderMetadataCreator.cs
  4. 60
      src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs
  5. 5
      src/ImageSharp/Formats/Tiff/TiffFormat.cs
  6. 66
      src/ImageSharp/Formats/Tiff/TiffFrameMetadata.cs
  7. 15
      tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs
  8. 10
      tests/ImageSharp.Tests/Formats/Tiff/TiffMetadataTests.cs

7
src/ImageSharp/Formats/Tiff/MetadataExtensions.cs

@ -17,5 +17,12 @@ namespace SixLabors.ImageSharp
/// <param name="metadata">The metadata this method extends.</param>
/// <returns>The <see cref="TiffMetadata"/>.</returns>
public static TiffMetadata GetTiffMetadata(this ImageMetadata metadata) => metadata.GetFormatMetadata(TiffFormat.Instance);
/// <summary>
/// Gets the tiff format specific metadata for the image frame.
/// </summary>
/// <param name="metadata">The metadata this method extends.</param>
/// <returns>The <see cref="TiffFrameMetadata"/>.</returns>
public static TiffFrameMetadata GetTiffMetadata(this ImageFrameMetadata metadata) => metadata.GetFormatMetadata(TiffFormat.Instance);
}
}

33
src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs

@ -110,15 +110,13 @@ namespace SixLabors.ImageSharp.Formats.Tiff
IEnumerable<ExifProfile> directories = reader.Read();
var frames = new List<ImageFrame<TPixel>>();
var tiffFramesMataData = new List<TiffFrameMetadata>();
foreach (ExifProfile ifd in directories)
{
ImageFrame<TPixel> frame = this.DecodeFrame<TPixel>(ifd, out TiffFrameMetadata frameMetadata);
ImageFrame<TPixel> frame = this.DecodeFrame<TPixel>(ifd);
frames.Add(frame);
tiffFramesMataData.Add(frameMetadata);
}
ImageMetadata metadata = TiffDecoderMetadataCreator.Create(frames, tiffFramesMataData, this.ignoreMetadata, reader.ByteOrder);
ImageMetadata metadata = TiffDecoderMetadataCreator.Create(frames, this.ignoreMetadata, reader.ByteOrder);
// TODO: Tiff frames can have different sizes
ImageFrame<TPixel> root = frames[0];
@ -139,24 +137,16 @@ namespace SixLabors.ImageSharp.Formats.Tiff
{
this.inputStream = stream;
var reader = new DirectoryReader(stream);
IEnumerable<ExifProfile> directories = reader.Read();
var framesMetadata = new List<TiffFrameMetadata>();
foreach (ExifProfile ifd in directories)
{
var meta = new TiffFrameMetadata(ifd);
meta.Initialize(ifd);
framesMetadata.Add(meta);
}
TiffFrameMetadata root = framesMetadata[0];
ExifProfile rootFrameExifProfile = directories.First();
ImageMetadata metadata = TiffDecoderMetadataCreator.Create(framesMetadata, reader.ByteOrder, rootFrameExifProfile);
var rootMetadata = TiffFrameMetadata.Parse(rootFrameExifProfile);
ImageMetadata metadata = TiffDecoderMetadataCreator.Create(reader.ByteOrder, rootFrameExifProfile);
int width = GetImageWidth(rootFrameExifProfile);
int height = GetImageHeight(rootFrameExifProfile);
return new ImageInfo(new PixelTypeInfo((int)root.BitsPerPixel), width, height, metadata);
return new ImageInfo(new PixelTypeInfo((int)rootMetadata.BitsPerPixel), width, height, metadata);
}
/// <summary>
@ -164,17 +154,18 @@ namespace SixLabors.ImageSharp.Formats.Tiff
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="tags">The IFD tags.</param>
/// <param name="tiffFrameMetaData">The tiff frame metadata.</param>
/// <returns>
/// The tiff frame.
/// </returns>
private ImageFrame<TPixel> DecodeFrame<TPixel>(ExifProfile tags, out TiffFrameMetadata tiffFrameMetaData)
private ImageFrame<TPixel> DecodeFrame<TPixel>(ExifProfile tags)
where TPixel : unmanaged, IPixel<TPixel>
{
ImageFrameMetadata imageFrameMetaData = this.ignoreMetadata ?
new ImageFrameMetadata() :
new ImageFrameMetadata { ExifProfile = tags, XmpProfile = tags.GetValue(ExifTag.XMP)?.Value };
tiffFrameMetaData = new TiffFrameMetadata(tags);
TiffFrameMetadata tiffFrameMetaData = imageFrameMetaData.GetTiffMetadata();
TiffFrameMetadata.Parse(tiffFrameMetaData, tags);
this.VerifyAndParse(tags, tiffFrameMetaData);
@ -220,9 +211,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff
}
int bytesPerRow = ((width * bitsPerPixel) + 7) / 8;
int stripBytes = bytesPerRow * height;
return stripBytes;
return bytesPerRow * height;
}
/// <summary>

13
src/ImageSharp/Formats/Tiff/TiffDecoderMetadataCreator.cs

@ -18,12 +18,10 @@ namespace SixLabors.ImageSharp.Formats.Tiff
/// </summary>
internal static class TiffDecoderMetadataCreator
{
public static ImageMetadata Create<TPixel>(List<ImageFrame<TPixel>> frames, List<TiffFrameMetadata> framesMetaData, bool ignoreMetadata, ByteOrder byteOrder)
public static ImageMetadata Create<TPixel>(List<ImageFrame<TPixel>> frames, bool ignoreMetadata, ByteOrder byteOrder)
where TPixel : unmanaged, IPixel<TPixel>
{
DebugGuard.IsTrue(frames.Count == framesMetaData.Count, nameof(frames), "Image frames and frames metadata should be the same size.");
if (framesMetaData.Count < 1)
if (frames.Count < 1)
{
TiffThrowHelper.ThrowImageFormatException("Expected at least one frame.");
}
@ -58,13 +56,8 @@ namespace SixLabors.ImageSharp.Formats.Tiff
return imageMetaData;
}
public static ImageMetadata Create(List<TiffFrameMetadata> framesMetaData, ByteOrder byteOrder, ExifProfile exifProfile)
public static ImageMetadata Create(ByteOrder byteOrder, ExifProfile exifProfile)
{
if (framesMetaData.Count < 1)
{
TiffThrowHelper.ThrowImageFormatException("Expected at least one frame.");
}
var imageMetaData = new ImageMetadata();
SetResolution(imageMetaData, exifProfile);

60
src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs

@ -12,7 +12,6 @@ using SixLabors.ImageSharp.Formats.Tiff.Compression;
using SixLabors.ImageSharp.Formats.Tiff.Constants;
using SixLabors.ImageSharp.Formats.Tiff.Writers;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.Metadata;
using SixLabors.ImageSharp.Metadata.Profiles.Exif;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
@ -110,18 +109,19 @@ namespace SixLabors.ImageSharp.Formats.Tiff
Guard.NotNull(stream, nameof(stream));
this.configuration = image.GetConfiguration();
ExifProfile rootFrameExifProfile = image.Frames.RootFrame.Metadata.ExifProfile;
TiffPhotometricInterpretation rootFramePhotometricInterpretation = GetRootFramePhotometricInterpretation(image);
TiffPhotometricInterpretation photometricInterpretation = this.Mode == TiffEncodingMode.ColorPalette
? TiffPhotometricInterpretation.PaletteColor : rootFramePhotometricInterpretation;
TiffBitsPerPixel? rootFrameBitsPerPixel = null;
if (rootFrameExifProfile != null)
{
rootFrameBitsPerPixel = new TiffFrameMetadata(rootFrameExifProfile).BitsPerPixel;
}
? TiffPhotometricInterpretation.PaletteColor
: rootFramePhotometricInterpretation;
this.SetMode(rootFrameBitsPerPixel, photometricInterpretation);
TiffBitsPerPixel? rootFrameBitsPerPixel = image.Frames.RootFrame.Metadata.GetTiffMetadata().BitsPerPixel;
// TODO: This isn't correct.
// We're overwriting explicit BPP based upon the Mode. It should be the other way around.
// BPP should also be nullable and based upon the current TPixel if not set.
this.SetBitsPerPixel(rootFrameBitsPerPixel);
this.SetMode(photometricInterpretation);
this.SetPhotometricInterpretation();
using (var writer = new TiffStreamWriter(stream))
@ -144,9 +144,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff
{
writer.Write(ByteOrderMarker);
writer.Write(TiffConstants.HeaderMagicNumber);
long firstIfdMarker = writer.PlaceMarker();
return firstIfdMarker;
return writer.PlaceMarker();
}
/// <summary>
@ -206,7 +204,17 @@ namespace SixLabors.ImageSharp.Formats.Tiff
int rowsPerStrip = TiffConstants.DefaultStripSize / bytesPerRow;
return rowsPerStrip > 0 ? (rowsPerStrip < height ? rowsPerStrip : height) : 1;
if (rowsPerStrip > 0)
{
if (rowsPerStrip < height)
{
return rowsPerStrip;
}
return height;
}
return 1;
}
/// <summary>
@ -219,6 +227,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff
{
if (entries.Count == 0)
{
// TODO: Perf. Throwhelper
throw new ArgumentException("There must be at least one entry per IFD.", nameof(entries));
}
@ -268,7 +277,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff
return nextIfdMarker;
}
private void SetMode(TiffBitsPerPixel? rootFrameBitsPerPixel, TiffPhotometricInterpretation photometricInterpretation)
private void SetMode(TiffPhotometricInterpretation photometricInterpretation)
{
// Make sure, that the fax compressions are only used together with the BiColor mode.
if (this.CompressionType == TiffCompression.CcittGroup3Fax || this.CompressionType == TiffCompression.Ccitt1D)
@ -286,19 +295,8 @@ namespace SixLabors.ImageSharp.Formats.Tiff
}
}
if (this.Mode == TiffEncodingMode.Default && rootFrameBitsPerPixel.HasValue)
{
// Preserve input bits per pixel, if no encoding mode was specified and the input image has a bits per pixel set.
this.SetModeWithBitsPerPixel(rootFrameBitsPerPixel, photometricInterpretation);
return;
}
if (this.BitsPerPixel != null)
{
// The user has specified a bits per pixel, so use that to determine the encoding mode.
this.SetModeWithBitsPerPixel(this.BitsPerPixel, photometricInterpretation);
}
// Use the bits per pixel to determine the encoding mode.
this.SetModeWithBitsPerPixel(this.BitsPerPixel, photometricInterpretation);
}
private void SetModeWithBitsPerPixel(TiffBitsPerPixel? bitsPerPixel, TiffPhotometricInterpretation photometricInterpretation)
@ -383,11 +381,9 @@ namespace SixLabors.ImageSharp.Formats.Tiff
private static TiffPhotometricInterpretation GetRootFramePhotometricInterpretation(Image image)
{
ExifProfile exifProfile = image.Frames.RootFrame.Metadata.ExifProfile;
TiffPhotometricInterpretation rootFramePhotometricInterpretation =
exifProfile?.GetValue(ExifTag.PhotometricInterpretation) != null
? (TiffPhotometricInterpretation)exifProfile?.GetValue(ExifTag.PhotometricInterpretation).Value
: TiffPhotometricInterpretation.WhiteIsZero;
return rootFramePhotometricInterpretation;
return exifProfile?.GetValue(ExifTag.PhotometricInterpretation) != null
? (TiffPhotometricInterpretation)exifProfile?.GetValue(ExifTag.PhotometricInterpretation).Value
: TiffPhotometricInterpretation.WhiteIsZero;
}
}
}

5
src/ImageSharp/Formats/Tiff/TiffFormat.cs

@ -10,7 +10,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff
/// <summary>
/// Encapsulates the means to encode and decode Tiff images.
/// </summary>
public class TiffFormat : IImageFormat<TiffMetadata>
public sealed class TiffFormat : IImageFormat<TiffMetadata, TiffFrameMetadata>
{
private TiffFormat()
{
@ -35,5 +35,8 @@ namespace SixLabors.ImageSharp.Formats.Tiff
/// <inheritdoc/>
public TiffMetadata CreateDefaultFormatMetadata() => new TiffMetadata();
/// <inheritdoc/>
public TiffFrameMetadata CreateDefaultFormatFrameMetadata() => new TiffFrameMetadata();
}
}

66
src/ImageSharp/Formats/Tiff/TiffFrameMetadata.cs

@ -9,7 +9,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff
/// <summary>
/// Provides Tiff specific metadata information for the frame.
/// </summary>
internal class TiffFrameMetadata : IDeepCloneable
public class TiffFrameMetadata : IDeepCloneable
{
/// <summary>
/// Initializes a new instance of the <see cref="TiffFrameMetadata"/> class.
@ -18,11 +18,11 @@ namespace SixLabors.ImageSharp.Formats.Tiff
{
}
/// <summary>
/// Initializes a new instance of the <see cref="TiffFrameMetadata"/> class.
/// </summary>
/// <param name="frameTags">The Tiff frame directory tags.</param>
public TiffFrameMetadata(ExifProfile frameTags) => this.Initialize(frameTags ?? new ExifProfile());
private TiffFrameMetadata(TiffFrameMetadata other)
{
this.BitsPerSample = other.BitsPerSample;
this.BitsPerPixel = other.BitsPerPixel;
}
/// <summary>
/// Gets or sets the number of bits per component.
@ -35,42 +35,54 @@ namespace SixLabors.ImageSharp.Formats.Tiff
public TiffBitsPerPixel BitsPerPixel { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="TiffFrameMetadata"/> class with a given ExifProfile.
/// Returns a new <see cref="TiffFrameMetadata"/> instance parsed from the given Exif profile.
/// </summary>
/// <param name="frameTags">The Tiff frame directory tags.</param>
public void Initialize(ExifProfile frameTags)
/// <param name="profile">The Exif profile containing tiff frame directory tags to parse.
/// If null, a new instance is created and parsed instead.</param>
/// <returns>The <see cref="TiffFrameMetadata"/>.</returns>
internal static TiffFrameMetadata Parse(ExifProfile profile)
{
TiffPhotometricInterpretation photometricInterpretation = frameTags.GetValue(ExifTag.PhotometricInterpretation) != null ?
(TiffPhotometricInterpretation)frameTags.GetValue(ExifTag.PhotometricInterpretation).Value : TiffPhotometricInterpretation.WhiteIsZero;
var meta = new TiffFrameMetadata();
Parse(meta, profile);
return meta;
}
ushort[] bits = frameTags.GetValue(ExifTag.BitsPerSample)?.Value;
/// <summary>
/// Parses the given Exif profile to populate the properties of the tiff frame meta data..
/// </summary>
/// <param name="meta">The tiff frame meta data.</param>
/// <param name="profile">The Exif profile containing tiff frame directory tags.</param>
internal static void Parse(TiffFrameMetadata meta, ExifProfile profile)
{
if (profile is null)
{
profile = new ExifProfile();
}
TiffPhotometricInterpretation photometricInterpretation = profile.GetValue(ExifTag.PhotometricInterpretation) != null
? (TiffPhotometricInterpretation)profile.GetValue(ExifTag.PhotometricInterpretation).Value
: TiffPhotometricInterpretation.WhiteIsZero;
ushort[] bits = profile.GetValue(ExifTag.BitsPerSample)?.Value;
if (bits == null)
{
if (photometricInterpretation == TiffPhotometricInterpretation.WhiteIsZero || photometricInterpretation == TiffPhotometricInterpretation.BlackIsZero)
if (photometricInterpretation == TiffPhotometricInterpretation.WhiteIsZero
|| photometricInterpretation == TiffPhotometricInterpretation.BlackIsZero)
{
this.BitsPerSample = TiffBitsPerSample.Bit1;
meta.BitsPerSample = TiffBitsPerSample.Bit1;
}
this.BitsPerSample = null;
meta.BitsPerSample = null;
}
else
{
this.BitsPerSample = bits.GetBitsPerSample();
meta.BitsPerSample = bits.GetBitsPerSample();
}
this.BitsPerPixel = (TiffBitsPerPixel)this.BitsPerSample.GetValueOrDefault().BitsPerPixel();
meta.BitsPerPixel = (TiffBitsPerPixel)meta.BitsPerSample.GetValueOrDefault().BitsPerPixel();
}
/// <inheritdoc/>
public IDeepCloneable DeepClone()
{
var clone = new TiffFrameMetadata
{
BitsPerSample = this.BitsPerSample,
BitsPerPixel = this.BitsPerPixel
};
return clone;
}
public IDeepCloneable DeepClone() => new TiffFrameMetadata(this);
}
}

15
tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs

@ -50,7 +50,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff
memStream.Position = 0;
using var output = Image.Load<Rgba32>(Configuration, memStream);
ExifProfile exifProfile = output.Frames.RootFrame.Metadata.ExifProfile;
var frameMetaData = new TiffFrameMetadata(exifProfile);
var frameMetaData = TiffFrameMetadata.Parse(exifProfile);
Assert.Equal(expectedBitsPerPixel, frameMetaData.BitsPerPixel);
Assert.Equal(TiffCompression.None, (TiffCompression)exifProfile.GetValue(ExifTag.Compression).Value);
}
@ -73,8 +73,9 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff
// assert
memStream.Position = 0;
using var output = Image.Load<Rgba32>(Configuration, memStream);
ExifProfile exifProfile = output.Frames.RootFrame.Metadata.ExifProfile;
var frameMetaData = new TiffFrameMetadata(exifProfile);
TiffFrameMetadata frameMetaData = output.Frames.RootFrame.Metadata.GetTiffMetadata();
Assert.Equal(bitsPerPixel, frameMetaData.BitsPerPixel);
Assert.Equal(TiffCompression.None, (TiffCompression)exifProfile.GetValue(ExifTag.Compression).Value);
}
@ -114,7 +115,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff
memStream.Position = 0;
using var output = Image.Load<Rgba32>(Configuration, memStream);
ExifProfile exifProfile = output.Frames.RootFrame.Metadata.ExifProfile;
var frameMetaData = new TiffFrameMetadata(exifProfile);
var frameMetaData = TiffFrameMetadata.Parse(exifProfile);
Assert.Equal(expectedBitsPerPixel, frameMetaData.BitsPerPixel);
Assert.Equal(expectedCompression, (TiffCompression)exifProfile.GetValue(ExifTag.Compression).Value);
}
@ -141,7 +142,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff
memStream.Position = 0;
using var output = Image.Load<Rgba32>(Configuration, memStream);
ExifProfile exifProfile = output.Frames.RootFrame.Metadata.ExifProfile;
var frameMetaData = new TiffFrameMetadata(exifProfile);
var frameMetaData = TiffFrameMetadata.Parse(exifProfile);
Assert.Equal(expectedBitsPerPixel, frameMetaData.BitsPerPixel);
}
@ -165,7 +166,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff
memStream.Position = 0;
using var output = Image.Load<Rgba32>(Configuration, memStream);
ExifProfile exifProfile = output.Frames.RootFrame.Metadata.ExifProfile;
var frameMetaData = new TiffFrameMetadata(exifProfile);
var frameMetaData = TiffFrameMetadata.Parse(exifProfile);
Assert.Equal(TiffBitsPerPixel.Bit1, frameMetaData.BitsPerPixel);
Assert.Equal(expectedCompression, (TiffCompression)exifProfile.GetValue(ExifTag.Compression).Value);
}
@ -341,7 +342,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff
using var memStream = new MemoryStream();
ExifProfile exifProfileInput = input.Frames.RootFrame.Metadata.ExifProfile;
var inputCompression = (TiffCompression)exifProfileInput.GetValue(ExifTag.Compression).Value;
var inputMeta = new TiffFrameMetadata(exifProfileInput);
var inputMeta = TiffFrameMetadata.Parse(exifProfileInput);
// act
input.Save(memStream, tiffEncoder);
@ -350,7 +351,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff
memStream.Position = 0;
using var output = Image.Load<Rgba32>(Configuration, memStream);
ExifProfile exifProfileOutput = output.Frames.RootFrame.Metadata.ExifProfile;
var outputMeta = new TiffFrameMetadata(exifProfileOutput);
var outputMeta = TiffFrameMetadata.Parse(exifProfileOutput);
ImageFrame<Rgba32> rootFrame = output.Frames.RootFrame;
Number rowsPerStrip = exifProfileOutput.GetValue(ExifTag.RowsPerStrip) != null ? exifProfileOutput.GetValue(ExifTag.RowsPerStrip).Value : TiffConstants.RowsPerStripInfinity;

10
tests/ImageSharp.Tests/Formats/Tiff/TiffMetadataTests.cs

@ -53,7 +53,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff
using (Image<TPixel> image = provider.GetImage(TiffDecoder))
{
ExifProfile exifProfile = image.Frames.RootFrame.Metadata.ExifProfile;
var meta = new TiffFrameMetadata(exifProfile);
var meta = TiffFrameMetadata.Parse(exifProfile);
var cloneSameAsSampleMetaData = (TiffFrameMetadata)meta.DeepClone();
Assert.NotNull(cloneSameAsSampleMetaData);
Assert.Equal(TiffBitsPerSample.Bit4, cloneSameAsSampleMetaData.BitsPerSample);
@ -196,10 +196,10 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff
Assert.NotNull(tiffMetaData);
Assert.Equal(ByteOrder.LittleEndian, tiffMetaData.ByteOrder);
var frameMetaData = new TiffFrameMetadata(exifProfile);
var frameMetaData = TiffFrameMetadata.Parse(exifProfile);
Assert.Equal(TiffBitsPerPixel.Bit4, frameMetaData.BitsPerPixel);
var tiffFrameMetadata = new TiffFrameMetadata(exifProfile);
var tiffFrameMetadata = TiffFrameMetadata.Parse(exifProfile);
Assert.NotNull(frameMetaData);
Assert.Equal(TiffBitsPerSample.Bit4, frameMetaData.BitsPerSample);
}
@ -238,7 +238,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff
using Image<TPixel> image = provider.GetImage(new TiffDecoder() { IgnoreMetadata = false });
ImageMetadata inputMetaData = image.Metadata;
var frameMetaInput = new TiffFrameMetadata(image.Frames.RootFrame.Metadata.ExifProfile);
var frameMetaInput = TiffFrameMetadata.Parse(image.Frames.RootFrame.Metadata.ExifProfile);
ImageFrame<TPixel> rootFrameInput = image.Frames.RootFrame;
byte[] xmpProfileInput = rootFrameInput.Metadata.XmpProfile;
ExifProfile exifProfileInput = rootFrameInput.Metadata.ExifProfile;
@ -257,7 +257,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff
ImageMetadata encodedImageMetaData = encodedImage.Metadata;
ImageFrame<Rgba32> rootFrameEncodedImage = encodedImage.Frames.RootFrame;
var tiffMetaDataEncodedRootFrame = new TiffFrameMetadata(rootFrameEncodedImage.Metadata.ExifProfile);
var tiffMetaDataEncodedRootFrame = TiffFrameMetadata.Parse(rootFrameEncodedImage.Metadata.ExifProfile);
ExifProfile encodedImageExifProfile = rootFrameEncodedImage.Metadata.ExifProfile;
byte[] encodedImageXmpProfile = rootFrameEncodedImage.Metadata.XmpProfile;

Loading…
Cancel
Save