Добавить кодом Source для Image с помощью .resx в WPF

220
03 октября 2017, 03:02

Я кодом создал новый Image в WPF:

var body = new Image();  

и, допустим, имеется файл ресурса, т.е. resx-файл изображения.
Как мне задать свойство

body.Source = ???

Это я хочу написать прямо в коде, а не в XAML

Answer 1

В проект, в котором будет находиться класс PictureConverter нужно добавить ссылку на библиотеку System.Drawing.

Добавляется так: выбираем в проекте курсором мыши References, жмём правую кнопку мыши, выбираем пункт Add Reference, там находим библиотеку System.Drawing и ставим галочку.

https://stackoverflow.com/questions/1546091/wpf-createbitmapsourcefromhbitmap-memory-leak/7035036#7035036

GdiNativeMethods.cs

using System;
using System.Runtime.InteropServices;
namespace WpfApp1
{
    /// <summary>
    /// FxCop requires all Marshalled functions to be in a class called NativeMethods.
    /// </summary>
    internal static class GdiNativeMethods
    {
        [DllImport("gdi32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool DeleteObject(IntPtr hObject);
    }
}

PictureConverter.cs

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Media.Imaging;
namespace WpfApp1
{
    public static class PictureConverter
    {
        public static BitmapSource ConvertToBitmapSource(Bitmap bitmap)
        {
            IntPtr handle = IntPtr.Zero;
            try
            {
                handle = bitmap.GetHbitmap();
                return Imaging.CreateBitmapSourceFromHBitmap(
                   handle,
                   IntPtr.Zero,
                   Int32Rect.Empty,
                   BitmapSizeOptions.FromWidthAndHeight(bitmap.Width, bitmap.Height));
            }
            finally
            {
                if (handle != IntPtr.Zero)
                {
                    GdiNativeMethods.DeleteObject(handle);
                }
            }
        }
        public static BitmapSource ConvertToBitmapImage(Bitmap bitmap)
        {
            using (MemoryStream memory = new MemoryStream())
            {
                bitmap.Save(memory, ImageFormat.Png);
                memory.Position = 0;
                BitmapImage bitmapImage = new BitmapImage();
                bitmapImage.BeginInit();
                bitmapImage.StreamSource = memory;
                bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
                bitmapImage.EndInit();
                return bitmapImage;
            }
        }
    }
}

MainWindow.xaml.cs

using System.Windows;
using Image = System.Windows.Controls.Image;
namespace WpfApp1
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            Image image = new Image();
            image.Source = PictureConverter.ConvertToBitmapSource(Properties.Resources._111);
            rootGrid.Children.Add(image);
        }
    }
}

Решил я затестить вариант преобразования вот таким методом:

using System;
using System.Diagnostics;
using System.Text;
using System.Windows;
namespace WpfApp1
{
    public partial class App : Application
    {
        public App()
        {
            // Вызовем по одному разу, чтобы JIT скопилировал код
            PictureConverter.ConvertToBitmapImage(WpfApp1.Properties.Resources._111);
            PictureConverter.ConvertToBitmapSource(WpfApp1.Properties.Resources._111);
            StringBuilder sb = new StringBuilder();
            const int Iterations = 100;
            Stopwatch sw = new Stopwatch();
            sw.Start();
            for (int i = 0; i < Iterations; i++)
            {
                PictureConverter.ConvertToBitmapImage(WpfApp1.Properties.Resources._111);
            }
            sw.Stop();
            sb.AppendFormat("ConvertToBitmapImage.ElapsedTicks: {1}{0}", Environment.NewLine, sw.ElapsedTicks);
            sw.Restart();
            for (int i = 0; i < Iterations; i++)
            {
                PictureConverter.ConvertToBitmapSource(WpfApp1.Properties.Resources._111);
            }
            sw.Stop();
            sb.AppendFormat("ConvertToBitmapSource.ElapsedTicks: {1}{0}", Environment.NewLine, sw.ElapsedTicks);
            string result = sb.ToString();
            Debug.Write(result);
        }
    }
}

И получил результаты:

  • ConvertToBitmapImage.ElapsedTicks: 9919067
  • ConvertToBitmapSource.ElapsedTicks: 2498690
READ ALSO
Удаление константных столбцов в C#

Удаление константных столбцов в C#

Есть матрица List<double[]>Нужно удалить столбцы, которые не изменяются у каждой строки, например есть матрица:

228
Как отрисовывать по пикселям в opengl?

Как отрисовывать по пикселям в opengl?

Использую библиотеку SharpGL в WPF приложении, как можно нарисовать линию с нужными размерами и отступами в пикселях? И как сделать так, чтобы...

258
Массив из цифр каждого разряда даного числа

Массив из цифр каждого разряда даного числа

Подскажите,пожалуйста, как сделать из числа integer массив, элементами которого будут цифры каждого разряда данного числа в C#? (Число нам нада...

319
Почему EAP не быстрее APM?

Почему EAP не быстрее APM?

Здравствуйте

213