diff --git a/QuickLook.Plugin/QuickLook.Plugin.ImageViewer/AnimatedImage/Providers/CursorProvider.cs b/QuickLook.Plugin/QuickLook.Plugin.ImageViewer/AnimatedImage/Providers/CursorProvider.cs index 15e98df..8e804d3 100644 --- a/QuickLook.Plugin/QuickLook.Plugin.ImageViewer/AnimatedImage/Providers/CursorProvider.cs +++ b/QuickLook.Plugin/QuickLook.Plugin.ImageViewer/AnimatedImage/Providers/CursorProvider.cs @@ -97,7 +97,7 @@ internal class CursorProvider : ImageMagickProvider { OutputColor = DngOutputColor.SRGB, UseCameraWhiteBalance = true, - DisableAutoBrightness = false + DisableAutoBrightness = false, } }; diff --git a/QuickLook.Plugin/QuickLook.Plugin.ImageViewer/AnimatedImage/Providers/ImageMagickProvider.cs b/QuickLook.Plugin/QuickLook.Plugin.ImageViewer/AnimatedImage/Providers/ImageMagickProvider.cs index 9da9978..d73189a 100644 --- a/QuickLook.Plugin/QuickLook.Plugin.ImageViewer/AnimatedImage/Providers/ImageMagickProvider.cs +++ b/QuickLook.Plugin/QuickLook.Plugin.ImageViewer/AnimatedImage/Providers/ImageMagickProvider.cs @@ -87,23 +87,34 @@ internal class ImageMagickProvider : AnimationProvider { OutputColor = DngOutputColor.SRGB, UseCameraWhiteBalance = true, - DisableAutoBrightness = false + DisableAutoBrightness = false, } }; + IMagickImage mi = null; + var isImageOwned = false; // Track whether this provider owns the Magick image instance and must dispose it. + try { - using var layers = new MagickImageCollection(Path.LocalPath, settings); - IMagickImage mi; - // Only flatten multi-layer gimp xcf files. - if (Path.LocalPath.ToLower().EndsWith(".xcf") && layers.Count > 1) + // Only flatten multi-layer gimp xcf files. Other formats (e.g. PSD) should avoid + // loading all layers via MagickImageCollection for performance. + if (Path.LocalPath.ToLower().EndsWith(".xcf")) { - // Flatten crops layers to canvas - mi = layers.Flatten(MagickColor.FromRgba(0, 0, 0, 0)); + using var layers = new MagickImageCollection(Path.LocalPath, settings); + if (layers.Count > 1) + { + mi = layers.Flatten(MagickColor.FromRgba(0, 0, 0, 0)); + isImageOwned = true; // Flatten creates a new image instance we must dispose. + } + else + { + mi = layers[0]; + } } else { - mi = layers[0]; + mi = new MagickImage(Path.LocalPath, settings); + isImageOwned = true; // New MagickImage created here must be disposed by this provider. } if (SettingHelper.Get("UseColorProfile", false, "QuickLook.Plugin.ImageViewer")) { @@ -133,6 +144,11 @@ internal class ImageMagickProvider : AnimationProvider ProcessHelper.WriteLog(e.ToString()); return null!; } + finally + { + if (isImageOwned) + mi?.Dispose(); + } } public override void Dispose() diff --git a/QuickLook.Plugin/QuickLook.Plugin.ImageViewer/AnimatedImage/Providers/WebPProvider.cs b/QuickLook.Plugin/QuickLook.Plugin.ImageViewer/AnimatedImage/Providers/WebPProvider.cs index 3b249a9..d793ef3 100644 --- a/QuickLook.Plugin/QuickLook.Plugin.ImageViewer/AnimatedImage/Providers/WebPProvider.cs +++ b/QuickLook.Plugin/QuickLook.Plugin.ImageViewer/AnimatedImage/Providers/WebPProvider.cs @@ -52,7 +52,7 @@ internal class WebPProvider : ImageMagickProvider { OutputColor = DngOutputColor.SRGB, UseCameraWhiteBalance = true, - DisableAutoBrightness = false + DisableAutoBrightness = false, } };