Skip to content

Commit f74b6ac

Browse files
Read resolution from EXIF metadata in WebP
1 parent 0d1296f commit f74b6ac

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed

src/ImageSharp/Formats/Webp/WebpDecoderCore.cs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System.Buffers;
55
using System.Buffers.Binary;
6+
using SixLabors.ImageSharp.Common.Helpers;
67
using SixLabors.ImageSharp.Formats.Webp.Lossless;
78
using SixLabors.ImageSharp.Formats.Webp.Lossy;
89
using SixLabors.ImageSharp.IO;
@@ -339,10 +340,33 @@ private void ReadExifProfile(BufferedReadStream stream, ImageMetadata metadata,
339340
return;
340341
}
341342

342-
metadata.ExifProfile = new ExifProfile(exifData);
343+
ExifProfile exifProfile = new(exifData);
344+
345+
// Set the resolution from the metadata.
346+
double horizontalValue = GetExifResolutionValue(exifProfile, ExifTag.XResolution);
347+
double verticalValue = GetExifResolutionValue(exifProfile, ExifTag.YResolution);
348+
349+
if (horizontalValue > 0 && verticalValue > 0)
350+
{
351+
metadata.HorizontalResolution = horizontalValue;
352+
metadata.VerticalResolution = verticalValue;
353+
metadata.ResolutionUnits = UnitConverter.ExifProfileToResolutionUnit(exifProfile);
354+
}
355+
356+
metadata.ExifProfile = exifProfile;
343357
}
344358
}
345359

360+
private static double GetExifResolutionValue(ExifProfile exifProfile, ExifTag<Rational> tag)
361+
{
362+
if (exifProfile.TryGetValue(tag, out IExifValue<Rational>? resolution))
363+
{
364+
return resolution.Value.ToDouble();
365+
}
366+
367+
return 0;
368+
}
369+
346370
/// <summary>
347371
/// Reads the XMP profile the stream.
348372
/// </summary>

tests/ImageSharp.Tests/Formats/WebP/WebpDecoderTests.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Runtime.Intrinsics.X86;
55
using SixLabors.ImageSharp.Formats;
66
using SixLabors.ImageSharp.Formats.Webp;
7+
using SixLabors.ImageSharp.Metadata;
78
using SixLabors.ImageSharp.PixelFormats;
89
using SixLabors.ImageSharp.Tests.TestUtilities;
910
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
@@ -493,4 +494,32 @@ private static void RunDecodeLossyWithComplexFilterTest()
493494

494495
[Fact]
495496
public void DecodeLossyWithComplexFilterTest_WithoutHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunDecodeLossyWithComplexFilterTest, HwIntrinsics.DisableHWIntrinsic);
497+
498+
[Theory]
499+
[InlineData(Lossy.BikeWithExif)]
500+
public void Decode_VerifyRatio(string imagePath)
501+
{
502+
TestFile testFile = TestFile.Create(imagePath);
503+
using MemoryStream stream = new(testFile.Bytes, false);
504+
using Image image = WebpDecoder.Instance.Decode(DecoderOptions.Default, stream);
505+
ImageMetadata meta = image.Metadata;
506+
507+
Assert.Equal(37.8, meta.HorizontalResolution);
508+
Assert.Equal(37.8, meta.VerticalResolution);
509+
Assert.Equal(PixelResolutionUnit.PixelsPerCentimeter, meta.ResolutionUnits);
510+
}
511+
512+
[Theory]
513+
[InlineData(Lossy.BikeWithExif)]
514+
public void Identify_VerifyRatio(string imagePath)
515+
{
516+
TestFile testFile = TestFile.Create(imagePath);
517+
using MemoryStream stream = new(testFile.Bytes, false);
518+
ImageInfo image = WebpDecoder.Instance.Identify(DecoderOptions.Default, stream);
519+
ImageMetadata meta = image.Metadata;
520+
521+
Assert.Equal(37.8, meta.HorizontalResolution);
522+
Assert.Equal(37.8, meta.VerticalResolution);
523+
Assert.Equal(PixelResolutionUnit.PixelsPerCentimeter, meta.ResolutionUnits);
524+
}
496525
}

0 commit comments

Comments
 (0)