Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF Image: .Source = Clipboard.GetImage() is not displayed

This simple program does not work, the image does not appear in the Window.

namespace ClipBoardTest
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
        private void CopyButton_Click(object sender, RoutedEventArgs e)
        {
            if (Clipboard.ContainsImage())
            {
                ImageUIElement.Source = Clipboard.GetImage();
                Console.WriteLine("Clipboard copied to UIElement");
            }
            else
            {
                Console.WriteLine("No image in Clipboard");
            }
        }
    }
 }

Output is "Clipboard copied to UIElement", but the image does not appear in the Window.

XAML:

 <Window x:Class="ClipBoardTest.MainWindow"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         Title="MainWindow" Height="350" Width="525">
     <Grid>
         <Button x:Name="CopyButton" Content="Copy" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="75" Click="CopyButton_Click"/>
         <Image x:Name="ImageUIElement" Margin="90,10,10,10"/>
     </Grid>
 </Window>

Is there anybody, who understands, what is wrong?

like image 781
Torsten Crull Avatar asked Oct 21 '25 05:10

Torsten Crull


2 Answers

Use Clipboard.GetDataObject to get bitmap and convert it into bitmapSource. Also, be aware that Bitmap.GetHbitmap() leaks memory unless you call DeleteObject on it.

So, correct solution would be to dispose the IntPtr after use. Declare the method at class level and use it from your code:

// at class level
[System.Runtime.InteropServices.DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);

if (Clipboard.ContainsImage())
{
    IDataObject clipboardData = Clipboard.GetDataObject();
    if (clipboardData != null)
    {
        if (clipboardData.GetDataPresent(System.Windows.Forms.DataFormats.Bitmap))
        {
            System.Drawing.Bitmap bitmap = (System.Drawing.Bitmap)clipboardData.GetData(System.Windows.Forms.DataFormats.Bitmap);
            IntPtr hBitmap = bitmap.GetHbitmap();
            try
            {
                ImageUIElement.Source = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(hBitmap, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
                Console.WriteLine("Clipboard copied to UIElement");
            }
            finally 
            {
                DeleteObject(hBitmap)
            }
        }
    }
}

Source - MSDN and Memory leak in Bitmap.

like image 111
Rohit Vats Avatar answered Oct 23 '25 19:10

Rohit Vats


Visual Studio 2019, WPF C# project targeting .NET Core 3.1, the following works (or, at least, it does for me):

myImage.Source = GetImageFromClipBoard();

where:

public static ImageSource GetImageFromClipBoard ()
        {
        if (Clipboard.ContainsImage())
            {
            return Clipboard.GetImage();
            }
        else
            return null;
        }
like image 41
Andrea Antonangeli Avatar answered Oct 23 '25 19:10

Andrea Antonangeli



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!