我正在尝试编写将从资源中加载图像的代码,然后对其进行裁剪。当我在 XAML 中完成全部或部分代码时,此代码有效。我想从全 XAML 切换到全代码,因此我可以使用不同的 Uris 在多个地方重用它。
但是当我尝试在代码中做同样的事情时,我得到了一个 DirectoryNotFoundException,因为它突然开始尝试在磁盘上查找一个文件夹,而不是从资源中加载图像。
- 如果我在 XAML 中加载 BitmapImage,然后在 XAML 中创建 CroppedBitmap,一切正常。
- 如果我在 XAML 中加载 BitmapImage,然后编写代码从中创建 CroppedBitmap,一切正常。
- 如果我在代码中加载 BitmapImage,而不从中创建 CroppedBitmap,一切正常。
- 但是,如果我在代码中加载 BitmapImage 并在代码中创建CroppedBitmap,它会尝试从文件系统而不是资源加载,我会得到 DirectoryNotFoundException。
代码示例如下。我确定我在做一些愚蠢的事情,但我现在已经完成了整件事三遍(一次在我的真实应用程序中,一次在测试应用程序中,一次在写这个问题时),我得到了同样的结果结果都是三遍。
对于以下所有代码示例,我在我的项目中创建了一个图像文件夹,并在其中添加了一个名为“elf.png”的现有图像,其属性设置为默认值(构建操作 = “资源”;复制到输出目录 = “禁止抄袭”)。
案例 1:XAML 中的 BitmapImage 和 CroppedBitmap。
<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:XAML中的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"/>
</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;没有裁剪位图。
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:“无法创建在程序集“WpfApplication8,版本=1.0.0.0,文化=中性,PublicKeyToken=null”中定义的“Window1”的实例。调用目标引发了异常。标记文件“Window1.xaml”中的错误' 第 1 行位置 13。
- 内部异常: TargetInvocationException:“调用的目标已抛出异常。”
- 内部异常: DirectoryNotFoundException:“找不到路径 'C:\svn\WpfApplication8\WpfApplication8\bin\Debug\Images\elf.png' 的一部分。”
- 内部异常: TargetInvocationException:“调用的目标已抛出异常。”
inner-inner-exception 堆栈跟踪显示原始异常 (DirectoryNotFoundException) 是由实例化 CroppedBitmap 的行抛出的。我不知道为什么该行会尝试从磁盘读取,或者为什么当 as-far-as-I-can-tell-equivalent 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 版本中发生了什么不同的情况?