Я пытаюсь написать код, который будет загружать изображение из ресурса, а затем обрезать его. Этот код работает, когда я делаю все или часть этого в XAML. Я хочу переключиться с all-XAML на all-code, чтобы я мог использовать его более чем в одном месте с разными Uris.
Но когда я пытаюсь сделать то же самое в коде, я получаю исключение DirectoryNotFoundException, потому что внезапно он начинает пытаться искать папку на диске вместо загрузки изображения из ресурса.
- Если я загружаю BitmapImage в XAML, а затем создаю CroppedBitmap в XAML, все работает.
- Если я загружаю BitmapImage в XAML, а затем пишу код для создания из него CroppedBitmap, все работает.
- Если я загружаю BitmapImage в коде, без создания из него CroppedBitmap, все работает.
- Но если я загружаю BitmapImage в коде и создаю CroppedBitmap в коде, он пытается загрузить из файловой системы вместо ресурсов, и я получаю исключение DirectoryNotFoundException.
Примеры кода приведены ниже. Я уверен, что делаю что-то глупое, но я все это трижды пробежал (один раз в моем реальном приложении, один раз в тестовом приложении и один раз во время написания этого вопроса), и я получил то же самое результаты все три раза.
Для всех следующих примеров кода я создал папку Images внутри своего проекта и добавил туда существующее изображение с именем "elf.png", свойства которого установлены в значения по умолчанию (Build Action = "Resource"; Копировать в Выходной каталог = "Не копировать").
Случай 1: BitmapImage и CroppedBitmap в XAML.
<Window x:Class="WpfApplication8.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<BitmapImage x:Key="fullImage" UriSource="Images/elf.png"/>
<CroppedBitmap x:Key="croppedImage" Source="{StaticResource fullImage}"
SourceRect="0 0 240 320"/>
</Window.Resources>
<Image Source="{StaticResource croppedImage}"/>
</Window>
Показывает обрезанную часть растрового изображения, как и ожидалось.
Случай 2: BitmapImage в XAML; CroppedBitmap в коде позади.
XAML:
<Window x:Class="WpfApplication8.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<BitmapImage x:Key="fullImage" UriSource="Images/elf.png"/>
</Window.Resources>
<Image Name="image"/>
</Window>
Конструктор в коде:
public Window1()
{
InitializeComponent();
var fullImage = (BitmapImage) FindResource("fullImage");
var croppedImage =
new CroppedBitmap(fullImage, new Int32Rect(0, 0, 240, 320));
image.Source = croppedImage;
}
Здесь также отображается обрезанная часть растрового изображения, как и ожидалось.
Случай 3: BitmapImage в коде; нет CroppedBitmap.
public Window1()
{
InitializeComponent();
var uri = new Uri("Images/elf.png", UriKind.RelativeOrAbsolute);
var fullImage = new BitmapImage(uri);
image.Source = fullImage;
}
Это показывает все растровое изображение. Это не то, что я хочу, но действительно говорит мне, что я знаю, как написать код C #, чтобы создать правильный тип Uri и загрузить BitmapImage из ресурса.
Случай 4: BitmapImage и CroppedBitmap в коде.
public Window1()
{
InitializeComponent();
var uri = new Uri("Images/elf.png", UriKind.RelativeOrAbsolute);
var fullImage = new BitmapImage(uri);
var croppedImage =
new CroppedBitmap(fullImage, new Int32Rect(0, 0, 240, 320));
image.Source = croppedImage;
}
Насколько я могу судить, это просто собирает те же самые части, что и раньше. Он использует код, который, как я знаю, будет загружать BitmapImage из ресурса, а код, который я знаю, будет обрезать раздел из загруженного BitmapImage. Но каким-то образом, когда они объединены, он забывает о наличии ресурса и пытается загрузить его с диска. Я получаю следующее исключение:
- XamlParseException: "Невозможно создать экземпляр 'Window1', определенный в сборке 'WpfApplication8, Version = 1.0.0.0, Culture = нейтральный, PublicKeyToken = null'. Исключение было выдано целью вызова. Ошибка в файле разметки ' Window1.xaml 'Line 1 Position 13 ".
- Внутреннее исключение: TargetInvocationException: «Исключение было сгенерировано целью вызова».
- Внутреннее исключение: DirectoryNotFoundException: "Не удалось найти часть пути" C: \ svn \ WpfApplication8 \ WpfApplication8 \ bin \ Debug \ Images \ elf.png '. "
Трассировка стека внутренних внутренних исключений показывает, что исходное исключение (DirectoryNotFoundException) генерируется строкой, которая создает экземпляр CroppedBitmap. Я не знаю, почему эта строка будет пытаться читать с диска или почему она не работает, если XAML, насколько я могу сказать, работает нормально.
Поскольку я знаю, что XAML использует конструкторы без параметров, я также попробовал следующую версию, которая должна быть намного ближе к тому, что на самом деле делает XAML:
public Window1()
{
InitializeComponent();
var uri = new Uri("Images/elf.png", UriKind.RelativeOrAbsolute);
var fullImage = new BitmapImage();
fullImage.BeginInit();
fullImage.UriSource = uri;
fullImage.EndInit();
var croppedImage = new CroppedBitmap();
croppedImage.BeginInit();
croppedImage.Source = fullImage;
croppedImage.SourceRect = new Int32Rect(0, 0, 240, 320);
croppedImage.EndInit();
image.Source = croppedImage;
}
То же исключение, на этот раз из строки croppedImage.EndInit();
.
Любые идеи о том, как я могу получить полностью кодовую версию, чтобы правильно загрузить ресурс и обрезать изображение? Что происходит в версии XAML, которая отличается?