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

ぃ、小莉子 提交于 2019-12-02 07:55:48

问题


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?


回答1:


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.




回答2:


Now it works fine.

if (Clipboard.ContainsImage())
{
    // ImageUIElement.Source = Clipboard.GetImage(); // does not work
    System.Windows.Forms.IDataObject clipboardData = System.Windows.Forms.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);
            ImageUIElement.Source =  System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(bitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty,BitmapSizeOptions.FromEmptyOptions());
            Console.WriteLine("Clipboard copied to UIElement");
        }
    }
}


来源:https://stackoverflow.com/questions/25749843/wpf-image-source-clipboard-getimage-is-not-displayed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!