saucecontrol / PhotoSauce

MagicScaler high-performance, high-quality image processing pipeline for .NET
http://photosauce.net/
MIT License
602 stars 49 forks source link

Metadata not copied from Camera RAW source image to JPEG output #60

Open marnilss opened 3 years ago

marnilss commented 3 years ago

Hi, Just found your nuget package and am trying to generate thumbnails of my Sony ARW (RAW) photos. The thumbnail stuff is working great, but I would also like to copy some of the metadata to the resulting JPEG file. I've tried with

var settings = new ProcessImageSettings
{
    Width = 300,
    Height = 300,
    DpiX = 96,
    DpiY = 96,
    SaveFormat = FileFormat.Jpeg,
    ResizeMode = CropScaleMode.Contain,
    JpegQuality = 60,
    MetadataNames = new[] { "System.Comment",
                            "System.Keywords",
                            "System.Rating",
                            "System.Subject",
                            "System.Title",
                            "System.Photo.CameraManufacturer",
                            "System.Photo.CameraModel",
                            "System.Photo.DateTaken" }
};

And the output file never gets any of the metadata I know is in the ARW file (file properties in Explorer is able to display them).

Running Windows 10 1909

Thanks in advance

Marcus Nilsson

marnilss commented 3 years ago

Here is a zipped ARW file you can test with. DSC00002.zip

saucecontrol commented 3 years ago

Hey Marcus, thanks for the detailed repro. It appears this is a limitation of the way Windows Photo Metadata Policies are defined per-codec. I can see that at least some of the requested metadata is present in your sample image, which uses a basic TIFF metadata layout.

Unfortunately, it seems the paths defined by a given policy apply only to the codecs explicitly listed in that policy. For example, System.Photo.CameraManufacturer lists a TIFF path of /ifd/{ushort=271}, and while the data is present in your raw file under that path, it is not retrieved when using the policy name. I assume this is because the camera raw codec doesn't subscribe to that policy. The values can, however, be retrieved by the explicit path. For example, the following values are all present:

MetadataNames = new[] {
    "/ifd/{ushort=271}",       // camera make
    "/ifd/{ushort=272}",       // camera model
    "/ifd/exif/{ushort=36867}" // date taken
}

The second issue is that when using explicit paths to reference metadata items, the path must be valid in both the source and destination formats. The above example paths work when saving to TIFF output since the paths are valid for both the camera raw and TIFF containers, but when saving to JPEG, the paths above must be prefixed with /app1 to be valid. For the most part, the Photo Metadata Policies obscure these differences, but of course that only works when both formats have the policy defined.

I am currently in the process of reworking MagicScaler to support codecs other than those shipping in Windows, and redefining metadata reading and writing is part of that. In the meantime, I can only suggest using another tool (like exiftool) to post-process your thumbnails if you need the metadata preserved.