Exemple #1
0
        static async Task ConvertFile(string filename)
        {
            try
            {
                await Task.CompletedTask;

                filename = System.IO.Path.GetFullPath(filename);
                var imagingFactory = new WIC.WICImagingFactory();
                var decoder        = imagingFactory.CreateDecoderFromFilename(filename, Guid.Empty, WIC.StreamAccessMode.GENERIC_READ,
                                                                              WIC.WICDecodeOptions.WICDecodeMetadataCacheOnLoad);

                //ShowMetadata(decoder.GetFrame(0));
                if (decoder.GetDecoderInfo().GetCLSID() == WIC.Decoder.Jpeg)
                {
                    Console.WriteLine($"'{filename}' is already a JPEG file.");
                    return;
                }

                var output = imagingFactory.CreateStream();
                output.InitializeFromFilename(System.IO.Path.ChangeExtension(filename, ".jpg"), WIC.StreamAccessMode.GENERIC_WRITE);
                var encoder = imagingFactory.CreateEncoder(ContainerFormat.Jpeg);
                encoder.Initialize(output, WICBitmapEncoderCacheOption.WICBitmapEncoderNoCache);

                for (int i = 0; i < decoder.GetFrameCount(); i++)
                {
                    var frame = decoder.GetFrame(i);
                    encoder.CreateNewFrame(out var frameJpg, null);
                    frameJpg.Initialize(null);
                    frameJpg.SetSize(frame.GetSize());
                    frameJpg.SetResolution(frame.GetResolution());
                    frameJpg.SetPixelFormat(frame.GetPixelFormat());


                    var reader = frame.AsMetadataBlockReader();
                    var count  = reader.GetCount();

                    //Get the EXIF data from the original photo.
                    var metadataReader = frame.GetMetadataQueryReader();
                    var metadataWriter = frameJpg.GetMetadataQueryWriter();
                    foreach (var name in metadataReader.GetNamesRecursive())
                    {
                        try {
                            var val = metadataReader.GetMetadataByName(name);
                            if (name.StartsWith("/ifd/"))
                            {
                                metadataWriter.SetMetadataByName("/app1" + name.Replace("/ifd/{ushort=34665}/", "/ifd/exif/").Replace("/ifd/{ushort=34853}/", "/ifd/gps/"), val);
                            }
                            else if (name.StartsWith("/xmp/"))
                            {
                                metadataWriter.SetMetadataByName(name, val);
                            }
                        }
                        catch {
                            System.Diagnostics.Trace.WriteLine($"Error setting '{name}'");
                        }
                    }
                    var photoProperties = SystemProperties.Concat(SystemPhotoProperties.Concat(SystemGpsProperties));
                    foreach (var photoProp in photoProperties)
                    {
                        var action = "getting";
                        try
                        {
                            var val = metadataReader.GetMetadataByName(photoProp);
                            //System.Diagnostics.Trace.WriteLine($"{photoProp} = {val}");
                            action = "setting";
                            metadataWriter.SetMetadataByName(photoProp, val);
                        }
                        catch (Exception ex)
                        {
                            System.Diagnostics.Trace.WriteLine($"Error {action} '{photoProp}': " + ex.Message);
                        }
                    }

                    frameJpg.WriteSource(frame);

                    frameJpg.Commit();

                    frame    = null;
                    frameJpg = null;
                }
                encoder.Commit();
                output.Commit(WIC.STGC.STGC_DEFAULT);
                encoder = null;
                output  = null;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error converting file '{filename}': {ex.Message}");
                System.Diagnostics.Trace.WriteLine($"Error converting file '{filename}': {ex.ToString()}");
            }
        }