Настройка источника изображения WPF в коде
Я пытаюсь установить источник изображения 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" />
Ответы
Ответ 1
После того, как у меня возникла та же проблема, что и у вас, и я немного почитал, я обнаружил решение - 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:
должны быть заменены запятыми:
Примечание. Компонент полномочий URI пакета является встроенным URI, который указывает на пакет и должен соответствовать RFC 2396. Кроме того, символ "/" должен быть заменен символом "," и зарезервированными символами, такими как "%". а также "?" должен быть сбежал. Смотрите OPC для деталей.
И, конечно же, убедитесь, что вы установили действие по сборке для вашего образа на Resource
.
Ответ 2
var uriSource = new Uri(@"/WpfApplication1;component/Images/Untitled.png", UriKind.Relative);
foo.Source = new BitmapImage(uriSource);
Это загрузит изображение под названием "Untitled.png" в папку под названием "Изображения" с "Установочным действием", установленным в "Ресурс" в сборке под названием "WpfApplication1".
Ответ 3
Это немного меньше кода и может выполняться в одной строке.
string packUri = "pack://application:,,,/AssemblyName;component/Images/icon.png";
_image.Source = new ImageSourceConverter().ConvertFromString(packUri) as ImageSource;
Ответ 4
Очень просто:
Чтобы динамически установить изображение элемента меню, выполните следующие действия:
MyMenuItem.ImageSource =
new BitmapImage(new Uri("Resource/icon.ico",UriKind.Relative));
... тогда как "icon.ico" может быть расположен везде (в настоящее время он находится в каталоге "Ресурсы" ) и должен быть связан как ресурс...
Ответ 5
Вы также можете уменьшить это до одной строки. Это код, который я использовал для установки значка для моего главного окна. Предполагается, что файл .ico помечен как Контент и копируется в выходной каталог.
this.Icon = new BitmapImage(new Uri("Icon.ico", UriKind.Relative));
Ответ 6
Самый простой способ:
var uriSource = new Uri("image path here");
image1.Source = new BitmapImage(uriSource);
Ответ 7
Вы пробовали:
Assembly asm = Assembly.GetExecutingAssembly();
Stream iconStream = asm.GetManifestResourceStream("SomeImage.png");
BitmapImage bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.StreamSource = iconStream;
bitmap.EndInit();
_icon.Source = bitmap;
Ответ 8
Это мой путь:
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"))
Ответ 9
Вот пример, который динамически устанавливает путь к изображению (изображение, находящееся где-то на диске, а не создается как ресурс):
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, поэтому мы должны использовать закодированную версию <
вместо. Это работает как мечта! Ниже показан символ флоппидиска в виде значка в пункте меню:
<MenuItem Name="mnuFileSave" Header="Save" Command="ApplicationCommands.Save">
<MenuItem.Icon>
<Label VerticalAlignment="Center" HorizontalAlignment="Center" FontFamily="Wingdings"><</Label>
</MenuItem.Icon>
</MenuItem>
Ответ 10
Если ваше изображение хранится в ResourceDictionary, вы можете сделать это только с одной строкой кода:
MyImage.Source = MyImage.FindResource("MyImageKeyDictionary") as ImageSource;
Ответ 11
Там также более простой способ. Если изображение загружено как ресурс в XAML, а рассматриваемый код является выделенным кодом для этого содержимого XAML:
Uri iconUri = new Uri("pack://application:,,,/ImageNAme.ico", UriKind.RelativeOrAbsolute);
NotifyIcon.Icon = BitmapFrame.Create(iconUri);
Ответ 12
Поместите рамку в VisualBrush:
VisualBrush brush = new VisualBrush { TileMode = TileMode.None };
brush.Visual = frame;
brush.AlignmentX = AlignmentX.Center;
brush.AlignmentY = AlignmentY.Center;
brush.Stretch = Stretch.Uniform;
Поместите VisualBrush в GeometryDrawing
GeometryDrawing drawing = new GeometryDrawing();
drawing.Brush = brush;
// Brush this in 1, 1 ratio
RectangleGeometry rect = new RectangleGeometry { Rect = new Rect(0, 0, 1, 1) };
drawing.Geometry = rect;
Теперь поместите GeometryDrawing в DrawingImage:
new DrawingImage(drawing);
Поместите это в ваш источник изображения, и вуаля!
Вы могли бы сделать это намного проще, хотя:
<Image>
<Image.Source>
<BitmapImage UriSource="/yourassembly;component/YourImage.PNG"></BitmapImage>
</Image.Source>
</Image>
И в коде:
BitmapImage image = new BitmapImage { UriSource="/yourassembly;component/YourImage.PNG" };
Ответ 13
Там также более простой способ. Если изображение загружено как ресурс в XAML, а рассматриваемый код является кодовым указателем для этого XAML:
Здесь словарь ресурсов для файла XAML - единственная строка, которая вас волнует, - это ImageBrush с ключом "PosterBrush" - остальная часть кода просто показывает контекст
<UserControl.Resources>
<ResourceDictionary>
<ImageBrush x:Key="PosterBrush" ImageSource="..\Resources\Images\EmptyPoster.jpg" Stretch="UniformToFill"/>
</ResourceDictionary>
</UserControl.Resources>
Теперь, в коде, вы можете просто сделать это
ImageBrush posterBrush = (ImageBrush)Resources["PosterBrush"];
Ответ 14
Как загрузить изображение из встроенных в иконки ресурсов и изображений (исправленная версия Arcturus):
Предположим, вы хотите добавить кнопку с изображением. Что вы должны сделать?
- Добавьте в папку иконки проекта и поместите изображение ClickMe.png здесь
- В свойствах "ClickMe.png" установите "BuildAction" на "Resource"
- Предположим, что имя вашей скомпилированной сборки - "Company.ProductAssembly.dll".
-
Теперь пришло время загрузить наше изображение в XAML
<Button Width="200" Height="70">
<Button.Content>
<StackPanel>
<Image Width="20" Height="20">
<Image.Source>
<BitmapImage UriSource="/Company.ProductAssembly;component/Icons/ClickMe.png"></BitmapImage>
</Image.Source>
</Image>
<TextBlock HorizontalAlignment="Center">Click me!</TextBlock>
</StackPanel>
</Button.Content>
</Button>
Готово.
Ответ 15
Я новичок в WPF, но не в .NET.
Я потратил пять часов, пытаясь добавить файл PNG в "Проект библиотеки пользовательских элементов управления WPF" в .NET 3.5 (Visual Studio 2010) и установить его в качестве фона унаследованного элемента управления.
Ничего относительного с URI не сработало. Я не могу себе представить, почему нет способа получить URI из файла ресурсов через IntelliSense, может быть, как:
Properties.Resources.ResourceManager.GetURI("my_image");
Я пробовал много URI и играл с методами ResourceManager и Assembly GetManifest, но все они были исключениями или значениями NULL.
Здесь я добавляю код, который работал для меня:
// Convert the image in resources to a Stream
Stream ms = new MemoryStream()
Properties.Resources.MyImage.Save(ms, ImageFormat.Png);
// Create a BitmapImage with the stream.
BitmapImage bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.StreamSource = ms;
bitmap.EndInit();
// Set as source
Source = bitmap;
Ответ 16
Если у вас уже есть поток и знаете формат, вы можете использовать что-то вроде этого:
static ImageSource PngStreamToImageSource (Stream pngStream) {
var decoder = new PngBitmapDecoder(pngStream,
BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
return decoder.Frames[0];
}
Ответ 17
Вы просто немного пропустили.
Чтобы получить встроенный ресурс из любой сборки, вы должны указать имя сборки вместе с именем вашего файла, как я упоминал здесь:
Assembly asm = Assembly.GetExecutingAssembly();
Stream iconStream = asm.GetManifestResourceStream(asm.GetName().Name + "." + "Desert.jpg");
BitmapImage bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.StreamSource = iconStream;
bitmap.EndInit();
image1.Source = bitmap;