Beispiel #1
0
        public void Execute()
        {
            string path;

            using (var inputStream = _fileSystem.File.OpenRead(_file))
            {
                var decoder = BitmapDecoder.Create(
                    inputStream,
                    BitmapCreateOptions.PreservePixelFormat,
                    BitmapCacheOption.None);

                var encoder = BitmapEncoder.Create(decoder.CodecInfo.ContainerFormat);
                if (!encoder.CanEncode())
                {
                    encoder = BitmapEncoder.Create(_settings.FallbackEncoder);
                }

                ConfigureEncoder(encoder);

                if (decoder.Metadata != null)
                {
                    try
                    {
                        encoder.Metadata = decoder.Metadata;
                    }
                    catch (InvalidOperationException)
                    {
                    }
                }

                if (decoder.Palette != null)
                {
                    encoder.Palette = decoder.Palette;
                }

                foreach (var originalFrame in decoder.Frames)
                {
                    BitmapMetadata metadata = (BitmapMetadata)originalFrame.Metadata;
                    if (metadata != null)
                    {
                        try
                        {
#if DEBUG
                            Debug.WriteLine($"### Processing metadata of file {_file}");
                            metadata.PrintsAllMetadataToDebugOutput();
#endif

                            // read all metadata and build up metadata object from the scratch. Discard invalid (unreadable/unwritable) metadata.
                            var newMetadata    = new BitmapMetadata(metadata.Format);
                            var listOfMetadata = metadata.GetListOfMetadata();
                            foreach (var(metadataPath, value) in listOfMetadata)
                            {
                                if (value is BitmapMetadata bitmapMetadata)
                                {
                                    var innerMetadata = new BitmapMetadata(bitmapMetadata.Format);
                                    newMetadata.SetQuerySafe(metadataPath, innerMetadata);
                                }
                                else
                                {
                                    newMetadata.SetQuerySafe(metadataPath, value);
                                }
                            }

                            if (newMetadata.IsMetadataObjectValid())
                            {
                                metadata = newMetadata;
                            }
                            else
                            {
                                // Seems like we build an invalid metadata object. ImageResizer will fail when trying to write the image to disk. We discard all metadata to be able to save the image.
                                metadata = null;
                            }
                        }
                        catch (ArgumentException ex)
                        {
                            metadata = null;

                            Debug.WriteLine(ex);
                        }
                    }

                    if (_settings.RemoveMetadata && metadata != null)
                    {
                        // strip any metadata that doesn't affect rendering
                        var newMetadata = new BitmapMetadata(metadata.Format);

                        metadata.CopyMetadataPropertyTo(newMetadata, "System.Photo.Orientation");
                        metadata.CopyMetadataPropertyTo(newMetadata, "System.Image.ColorSpace");

                        metadata = newMetadata;
                    }

                    encoder.Frames.Add(
                        BitmapFrame.Create(
                            Transform(originalFrame),
                            thumbnail: null, /* should be null, see #15413 */
                            metadata,
                            colorContexts: null /* should be null, see #14866 */));
                }

                path = GetDestinationPath(encoder);
                _fileSystem.Directory.CreateDirectory(_fileSystem.Path.GetDirectoryName(path));
                using (var outputStream = _fileSystem.File.Open(path, FileMode.CreateNew, FileAccess.Write))
                {
                    encoder.Save(outputStream);
                }
            }

            if (_settings.KeepDateModified)
            {
                _fileSystem.File.SetLastWriteTimeUtc(path, _fileSystem.File.GetLastWriteTimeUtc(_file));
            }

            if (_settings.Replace)
            {
                var backup = GetBackupPath();
                _fileSystem.File.Replace(path, _file, backup, ignoreMetadataErrors: true);
                FileSystem.DeleteFile(backup, UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin);
            }
        }
Beispiel #2
0
        public void Execute()
        {
            string path;

            using (var inputStream = _fileSystem.File.OpenRead(_file))
            {
                var decoder = BitmapDecoder.Create(
                    inputStream,
                    BitmapCreateOptions.PreservePixelFormat,
                    BitmapCacheOption.None);

                var containerFormat = decoder.CodecInfo.ContainerFormat;

                var encoder = CreateEncoder(containerFormat);

                if (decoder.Metadata != null)
                {
                    try
                    {
                        encoder.Metadata = decoder.Metadata;
                    }
                    catch (InvalidOperationException)
                    {
                    }
                }

                if (decoder.Palette != null)
                {
                    encoder.Palette = decoder.Palette;
                }

                foreach (var originalFrame in decoder.Frames)
                {
                    var transformedBitmap = Transform(originalFrame);

                    // if the frame was not modified, we should not replace the metadata
                    if (transformedBitmap == originalFrame)
                    {
                        encoder.Frames.Add(originalFrame);
                    }
                    else
                    {
                        BitmapMetadata originalMetadata = (BitmapMetadata)originalFrame.Metadata;

    #if DEBUG
                        Debug.WriteLine($"### Processing metadata of file {_file}");
                        originalMetadata.PrintsAllMetadataToDebugOutput();
    #endif

                        var metadata = GetValidMetadata(originalMetadata, transformedBitmap, containerFormat);

                        if (_settings.RemoveMetadata && metadata != null)
                        {
                            // strip any metadata that doesn't affect rendering
                            var newMetadata = new BitmapMetadata(metadata.Format);

                            metadata.CopyMetadataPropertyTo(newMetadata, "System.Photo.Orientation");
                            metadata.CopyMetadataPropertyTo(newMetadata, "System.Image.ColorSpace");

                            metadata = newMetadata;
                        }

                        var frame = CreateBitmapFrame(transformedBitmap, metadata);

                        encoder.Frames.Add(frame);
                    }
                }

                path = GetDestinationPath(encoder);
                _fileSystem.Directory.CreateDirectory(_fileSystem.Path.GetDirectoryName(path));
                using (var outputStream = _fileSystem.File.Open(path, FileMode.CreateNew, FileAccess.Write))
                {
                    encoder.Save(outputStream);
                }
            }

            if (_settings.KeepDateModified)
            {
                _fileSystem.File.SetLastWriteTimeUtc(path, _fileSystem.File.GetLastWriteTimeUtc(_file));
            }

            if (_settings.Replace)
            {
                var backup = GetBackupPath();
                _fileSystem.File.Replace(path, _file, backup, ignoreMetadataErrors: true);
                FileSystem.DeleteFile(backup, UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin);
            }
        }