Ресурсы изображений WPF - PullRequest
       21

Ресурсы изображений WPF

382 голосов
/ 07 декабря 2008

Я пришел в основном из Интернета и немного из Windows Forms. Для нового проекта мы будем использовать WPF. Приложению WPF понадобится от 10 до 20 маленьких иконок и изображений для иллюстративных целей. Я думаю о том, чтобы хранить их в сборке как встроенные ресурсы. Это правильный путь?

Как указать в XAML, что элемент управления Image должен загружать изображение из встроенного ресурса?

Ответы [ 10 ]

453 голосов
/ 03 марта 2009

Если вы будете использовать изображение в нескольких местах, то стоит загрузить данные изображения только один раз в память и затем разделить их между всеми Image элементами.

Для этого создайте BitmapSource в качестве ресурса где-то:

<BitmapImage x:Key="MyImageSource" UriSource="../Media/Image.png" />

Затем в вашем коде используйте что-то вроде:

<Image Source="{StaticResource MyImageSource}" />

В моем случае я обнаружил, что для файла Image.png нужно настроить действие сборки Resource, а не просто Content. Это приводит к переносу изображения в скомпилированную сборку.

162 голосов
/ 10 марта 2010

Я обнаружил, что лучшая практика использования изображений, видео и т. Д .:

  • Измените ваши файлы "Создайте действие" на "Содержимое" . Обязательно отметьте Копировать в директорию сборки .
    • Найдено в меню «Правый клик» в окне обозревателя решений.
  • Источник изображения в следующем формате:
    • "/ «YourAssemblyName»; компонент /«YourPath»/ «YourImage.png»"

Пример * * одна тысяча тридцать одна <Image Source="/WPFApplication;component/Images/Start.png" /> Преимущества: Файлы не встроены в сборку. Диспетчер ресурсов вызовет некоторые проблемы переполнения памяти из-за слишком большого количества ресурсов (во время сборки). Может вызываться между сборками.

44 голосов
/ 13 февраля 2011

Некоторые люди спрашивают об этом в коде и не получают ответа.

Проведя много часов в поисках, я нашел очень простой метод, не нашел ни одного примера и поэтому делюсь своим здесь который работает с изображениями. (у меня был .gif)

Резюме:

Возвращает BitmapFrame, который, по-видимому, нравится «получателям» ImageSource.

Использование:

doGetImageSourceFromResource ("[YourAssemblyNameHere]", "[YourResourceNameHere]");

Метод:

static internal ImageSource doGetImageSourceFromResource(string psAssemblyName, string psResourceName)
{
    Uri oUri = new Uri("pack://application:,,,/" +psAssemblyName +";component/" +psResourceName, UriKind.RelativeOrAbsolute);
    return BitmapFrame.Create(oUri);
}

Усвоение:

Исходя из моего опыта, строка пакета не является проблемой, проверьте ваши потоки и особенно, если при чтении в первый раз установлен указатель до конца файла, и вам нужно сбросить его на ноль, прежде чем читать снова.

Надеюсь, это спасет вас от многих часов, которые я хотел бы получить для меня!

39 голосов
/ 16 марта 2012

В коде для загрузки ресурса в исполняющую сборку, где мое изображение Freq.png было в папке Icons и определено как Resource:

this.Icon = new BitmapImage(new Uri(@"pack://application:,,,/" 
    + Assembly.GetExecutingAssembly().GetName().Name 
    + ";component/" 
    + "Icons/Freq.png", UriKind.Absolute)); 

Я также сделал функцию:

/// <summary>
/// Load a resource WPF-BitmapImage (png, bmp, ...) from embedded resource defined as 'Resource' not as 'Embedded resource'.
/// </summary>
/// <param name="pathInApplication">Path without starting slash</param>
/// <param name="assembly">Usually 'Assembly.GetExecutingAssembly()'. If not mentionned, I will use the calling assembly</param>
/// <returns></returns>
public static BitmapImage LoadBitmapFromResource(string pathInApplication, Assembly assembly = null)
{
    if (assembly == null)
    {
        assembly = Assembly.GetCallingAssembly();
    }

    if (pathInApplication[0] == '/')
    {
        pathInApplication = pathInApplication.Substring(1);
    }
    return new BitmapImage(new Uri(@"pack://application:,,,/" + assembly.GetName().Name + ";component/" + pathInApplication, UriKind.Absolute)); 
}

Использование (при условии, что вы поместили функцию в класс ResourceHelper):

this.Icon = ResourceHelper.LoadBitmapFromResource("Icons/Freq.png");

Примечание : см. URI пакета MSDN в WPF :
pack://application:,,,/ReferencedAssembly;component/Subfolder/ResourceFile.xaml

36 голосов
/ 07 декабря 2008

Да, это правильный путь.

Вы можете использовать изображение в файле ресурсов, просто используя путь:

<Image Source="..\Media\Image.png" />

Вы должны установить для действия по сборке файла образа значение «Ресурс».

13 голосов
/ 13 апреля 2010

Полное описание использования ресурсов: Ресурсы, содержимое и файлы приложений WPF

А как ссылаться на них, читайте "Упаковать URI в WPF".

Короче говоря, есть даже средства для ссылки на ресурсы из ссылочных / ссылающихся сборок.

4 голосов
/ 23 августа 2011
  1. Visual Studio 2010 Professional с пакетом обновления 1 (SP1).
  2. Профиль клиента .NET Framework 4.
  3. Изображение PNG добавлено в качестве ресурса в свойствах проекта.
  4. Новый файл в папке ресурсов создается автоматически.
  5. Действие по созданию ресурса.

Это сработало для меня:

<BitmapImage x:Key="MyImageSource" UriSource="Resources/Image.png" />
3 голосов
/ 24 апреля 2018

Да, это правильный путь. Вы можете использовать изображения в файле ресурсов, используя путь:

<StackPanel Orientation="Horizontal">
    <CheckBox  Content="{Binding Nname}" IsChecked="{Binding IsChecked}"/>
    <Image Source="E:\SWorking\SharePointSecurityApps\SharePointSecurityApps\SharePointSecurityApps.WPF\Images\sitepermission.png"/>
    <TextBlock Text="{Binding Path=Title}"></TextBlock>
</StackPanel>
3 голосов
/ 08 декабря 2008

Если вы используете Blend , чтобы сделать его более простым и не иметь проблем с получением правильного пути для атрибута Source , просто перетащите изображение из проекта панель на конструктор.

0 голосов
/ 09 января 2015

Следующее сработало и изображения должны быть установлены в свойствах:

    var bitmapSource = Imaging.CreateBitmapSourceFromHBitmap(MyProject.Properties.Resources.myImage.GetHbitmap(),
                                      IntPtr.Zero,
                                      Int32Rect.Empty,
                                      BitmapSizeOptions.FromEmptyOptions());
    MyButton.Background = new ImageBrush(bitmapSource);
img_username.Source = bitmapSource;
...