Настройка источника изображения WPF в коде - PullRequest
304 голосов
/ 08 декабря 2008

Я пытаюсь установить источник изображения WPF в коде. Изображение внедрено как ресурс в проект. Просматривая примеры, я пришел к следующему коду. По какой-то причине это не работает - изображение не отображается.

При отладке я вижу, что поток содержит данные изображения. Так что не так?

Assembly asm = Assembly.GetExecutingAssembly();
Stream iconStream = asm.GetManifestResourceStream("SomeImage.png");
PngBitmapDecoder iconDecoder = new PngBitmapDecoder(iconStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
ImageSource iconSource = iconDecoder.Frames[0];
_icon.Source = iconSource;

Значок определяется примерно так: <Image x:Name="_icon" Width="16" Height="16" />

Ответы [ 17 ]

394 голосов
/ 30 октября 2009

После того, как у вас возникла та же проблема, что и у вас, я нашел решение - Pack URI .

Я сделал следующее в коде:

Image finalImage = new Image();
finalImage.Width = 80;
...
BitmapImage logo = new BitmapImage();
logo.BeginInit();
logo.UriSource = new Uri("pack://application:,,,/AssemblyName;component/Resources/logo.png");
logo.EndInit();
...
finalImage.Source = logo;

Или короче, используя другой конструктор BitmapImage:

finalImage.Source = new BitmapImage(
    new Uri("pack://application:,,,/AssemblyName;component/Resources/logo.png"));

URI разбит на части:

  • Полномочия: application:///
  • Путь: имя файла ресурса, который компилируется в ссылочную сборку. Путь должен соответствовать следующему формату: AssemblyShortName[;Version][;PublicKey];component/Path

    • AssemblyShortName: короткое имя для указанной сборки.
    • ; Версия [необязательная]: версия ссылочной сборки, которая содержит файл ресурсов. Используется, когда загружены две или более ссылочных сборки с одинаковым коротким именем.
    • ; PublicKey [необязательно]: открытый ключ, который использовался для подписи ссылочной сборки. Используется, когда загружены две или более ссылочных сборки с одинаковым коротким именем.
    • ; компонент: указывает, что ссылка на сборку указана из локальной сборки.
    • / Path: имя файла ресурса, включая его путь, относительно корня папки проекта указанной сборки.

Три слэша после application: должны быть заменены запятыми:

Примечание: компонент полномочий URI пакета является встроенным URI, который указывает на пакет и должен соответствовать RFC 2396. Кроме того, символ "/" должен быть заменен символом ",", и зарезервированные символы, такие как «%» а также "?" должен быть сбежал Смотрите OPC для деталей.

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

169 голосов
/ 26 августа 2009
var uriSource = new Uri(@"/WpfApplication1;component/Images/Untitled.png", UriKind.Relative);
foo.Source = new BitmapImage(uriSource);

Это загрузит изображение с именем «Untitled.png» в папку с именем «Images», для которой «Build Action» установлено в «Resource», в сборке с именем «WpfApplication1».

73 голосов
/ 06 января 2010

Это немного меньше кода и может быть сделано в одной строке.

string packUri = "pack://application:,,,/AssemblyName;component/Images/icon.png";
_image.Source = new ImageSourceConverter().ConvertFromString(packUri) as ImageSource;
41 голосов
/ 12 декабря 2010

Очень просто:

Чтобы динамически установить изображение элемента меню, выполните только следующее:

MyMenuItem.ImageSource = 
    new BitmapImage(new Uri("Resource/icon.ico",UriKind.Relative));

... тогда как «icon.ico» может находиться везде (в настоящее время он находится в каталоге «Resources») и должен быть связан как Resource ...

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

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

 this.Icon = new BitmapImage(new Uri("Icon.ico", UriKind.Relative));
15 голосов
/ 17 ноября 2011

Самый простой способ:

var uriSource = new Uri("image path here");
image1.Source = new BitmapImage(uriSource);
14 голосов
/ 10 февраля 2009

Вы пробовали:

Assembly asm = Assembly.GetExecutingAssembly();
Stream iconStream = asm.GetManifestResourceStream("SomeImage.png");
BitmapImage bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.StreamSource = iconStream;
bitmap.EndInit();
_icon.Source = bitmap;
11 голосов
/ 09 мая 2015

Это мой путь:

internal static class ResourceAccessor
{
    public static Uri Get(string resourcePath)
    {
        var uri = string.Format(
            "pack://application:,,,/{0};component/{1}"
            , Assembly.GetExecutingAssembly().GetName().Name
            , resourcePath
        );

        return new Uri(uri);
    }
}

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

new BitmapImage(ResourceAccessor.Get("Images/1.png"))
8 голосов
/ 10 июля 2009

Вот пример, который динамически устанавливает путь к изображению (изображение, находящееся где-то на диске, а не создается как ресурс):

if (File.Exists(imagePath))
{
    // Create image element to set as icon on the menu element
    Image icon = new Image();
    BitmapImage bmImage = new BitmapImage();
    bmImage.BeginInit();
    bmImage.UriSource = new Uri(imagePath, UriKind.Absolute);
    bmImage.EndInit();
    icon.Source = bmImage;
    icon.MaxWidth = 25;
    item.Icon = icon;
}

Размышления о иконах ...

Сначала подумайте, вы думаете, что свойство Icon может содержать только изображение. Но на самом деле он может содержать что угодно! Я обнаружил это случайно, когда программно попытался установить свойство Image непосредственно в строку с путем к изображению. В результате получилось не изображение, а фактический текст пути!

Это приводит к тому, что альтернативе не нужно создавать изображение для значка, а вместо этого использовать текст с символьным шрифтом для отображения простого «значка». В следующем примере используется шрифт Wingdings , который содержит символ «floppydisk». Этот символ действительно является символом <, который имеет особое значение в XAML, поэтому мы должны использовать вместо него закодированную версию &lt;. Это работает как мечта! Ниже показан символ дискеты в виде значка в пункте меню:

<MenuItem Name="mnuFileSave" Header="Save" Command="ApplicationCommands.Save">
  <MenuItem.Icon>
    <Label VerticalAlignment="Center" HorizontalAlignment="Center" FontFamily="Wingdings">&lt;</Label>
  </MenuItem.Icon>
</MenuItem>
6 голосов
/ 15 мая 2017

Если ваше изображение хранится в ResourceDictionary, вы можете сделать это только с одной строкой кода:

MyImage.Source = MyImage.FindResource("MyImageKeyDictionary") as ImageSource;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...