From 82987b0848b0dee5dc18726bb91f4f0f57df032e Mon Sep 17 00:00:00 2001 From: ema Date: Mon, 30 Dec 2024 05:22:58 +0800 Subject: [PATCH] Fix image viewer copy without transparency support --- .../ImagePanel.xaml.cs | 5 +- .../MetaProvider.cs | 2 +- .../NativeMethods/ClipboardEx.cs | 65 +++++++++++++++++++ .../QuickLook.Plugin.ImageViewer.csproj | 1 + 4 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 QuickLook.Plugin/QuickLook.Plugin.ImageViewer/NativeMethods/ClipboardEx.cs diff --git a/QuickLook.Plugin/QuickLook.Plugin.ImageViewer/ImagePanel.xaml.cs b/QuickLook.Plugin/QuickLook.Plugin.ImageViewer/ImagePanel.xaml.cs index b780624..a107d1e 100644 --- a/QuickLook.Plugin/QuickLook.Plugin.ImageViewer/ImagePanel.xaml.cs +++ b/QuickLook.Plugin/QuickLook.Plugin.ImageViewer/ImagePanel.xaml.cs @@ -19,6 +19,7 @@ using QuickLook.Common.Annotations; using QuickLook.Common.ExtensionMethods; using QuickLook.Common.Helpers; using QuickLook.Common.Plugin; +using QuickLook.Plugin.ImageViewer.NativeMethods; using System; using System.ComponentModel; using System.Diagnostics; @@ -293,13 +294,13 @@ public partial class ImagePanel : UserControl, INotifyPropertyChanged, IDisposab { if (_source is not null) { - Clipboard.SetImage(_source); + ClipboardEx.SetClipboardImage(_source); return; } if (viewPanelImage.Source is BitmapSource bitmapSource) { - Clipboard.SetImage(bitmapSource); + ClipboardEx.SetClipboardImage(bitmapSource); return; } } diff --git a/QuickLook.Plugin/QuickLook.Plugin.ImageViewer/MetaProvider.cs b/QuickLook.Plugin/QuickLook.Plugin.ImageViewer/MetaProvider.cs index 91446c3..4de291f 100644 --- a/QuickLook.Plugin/QuickLook.Plugin.ImageViewer/MetaProvider.cs +++ b/QuickLook.Plugin/QuickLook.Plugin.ImageViewer/MetaProvider.cs @@ -106,7 +106,7 @@ public class MetaProvider } } -internal static class NativeMethods +file static class NativeMethods { private static readonly bool Is64 = Environment.Is64BitProcess; diff --git a/QuickLook.Plugin/QuickLook.Plugin.ImageViewer/NativeMethods/ClipboardEx.cs b/QuickLook.Plugin/QuickLook.Plugin.ImageViewer/NativeMethods/ClipboardEx.cs new file mode 100644 index 0000000..13e14f4 --- /dev/null +++ b/QuickLook.Plugin/QuickLook.Plugin.ImageViewer/NativeMethods/ClipboardEx.cs @@ -0,0 +1,65 @@ +using System.Drawing; +using System.Drawing.Imaging; +using System.IO; +using System.Runtime.InteropServices; +using System.Threading; +using System.Windows; +using System.Windows.Media.Imaging; +using Clipboard = System.Windows.Forms.Clipboard; + +namespace QuickLook.Plugin.ImageViewer.NativeMethods; + +internal static class ClipboardEx +{ + public static void SetClipboardImage(this BitmapSource img) + { + if (img == null) + { + return; + } + + var thread = new Thread((img) => + { + if (img == null) + { + return; + } + + var image = (BitmapSource)img; + + try + { + Clipboard.Clear(); + } + catch (ExternalException) { } + + try + { + using var pngMemStream = new MemoryStream(); + using var bitmpa = image.ToBitmap(); + var data = new DataObject(); + + bitmpa.Save(pngMemStream, ImageFormat.Png); + data.SetData("PNG", pngMemStream, false); + + Clipboard.SetDataObject(data, true); + } + catch { } + }); + thread.SetApartmentState(ApartmentState.STA); + thread.Start(img); + } + + private static Bitmap ToBitmap(this BitmapSource source) + { + using (var outStream = new MemoryStream()) + { + BitmapEncoder enc = new PngBitmapEncoder(); + enc.Frames.Add(BitmapFrame.Create(source)); + enc.Save(outStream); + var bitmap = new Bitmap(outStream); + + return new Bitmap(bitmap); + } + } +} diff --git a/QuickLook.Plugin/QuickLook.Plugin.ImageViewer/QuickLook.Plugin.ImageViewer.csproj b/QuickLook.Plugin/QuickLook.Plugin.ImageViewer/QuickLook.Plugin.ImageViewer.csproj index 31afaaa..2f9ab42 100644 --- a/QuickLook.Plugin/QuickLook.Plugin.ImageViewer/QuickLook.Plugin.ImageViewer.csproj +++ b/QuickLook.Plugin/QuickLook.Plugin.ImageViewer/QuickLook.Plugin.ImageViewer.csproj @@ -8,6 +8,7 @@ 512 false true + true latest false true