2021-01-25
关键字:Image加载外部图片
本文介绍如何在WPF桌面程序开发过程中将外部图片显示在Image控件以及将图片“隐藏”打包进程序安装包中。
使用外部图片可分静态与动态两种方式。下面逐一介绍。
首先介绍一下静态加载外部图片的方式。
创建一个.NET CORE的WPF工程。
其次选中工程,右键添加文件夹,如下图所示:
文件夹的名字随便起,建议以res或resource等直观的名字命名。然后在新建的文件夹上右键,添加本地文件,如下图所示:
在弹出的对话窗口中将你的外部图片文件添加进去。此时便可以看到如下图所示的工程结构:
接着便是创建布局文件,本文作为一个示例程序,一切以简单为原则,源码与效果如下图所示:
Image控件的Source中填写的即是要加载的图片在本工程中的相对位置。这个相对位置的起点是工程源码根目录,可以简单理解为是 .csproj 文件所在的位置。
code-behide 文件不需要写任何代码。不如意外的话运行以后便可以看到我们的图片显示在上面的了,以下是程序运行图:
为何会一片空白而没有预计的图片显示出来呢?
原因是当程序编译并运行以后其相对位置就则 .csproj 文件所在的位置变成了相应的编译输出目录,我们在 xaml 中设置的相对路径在程序运行时已经找不到了。
你可能立马会说相对路径不行那我们绝对路径肯定没问题了吧。 是的,用绝对路径确实可以解决,但是一旦你用了绝对路径,你的程序就只能在你自己的电脑上运行了,一旦发给其他人或打包发布,在其它机器上极有可能仍然是无法看到图片的。
那怎么解决呢?其实很简单,回到我们的解决方案浏览器中,选中我们的图片然后右键选择Property,在弹出的对话窗体中将图片的Build Action类型设置为Resource,如下图所示:
此时保存配置后先Clean一下解决方案,如下图所示:
然后再次运行,就能正常显示了:
使用这种方式会直接把图片打包进应用程序内部,将图片打包进程序内部非常有用,可以避免用户修改图片导致程序运行异常。
我们可以查看一下程序的编译目录,其结构如下图所示:
可以关注到在将图片以Resource的形式编译以后程序的dll文件瞬间增大了,由此也可以得出图片是被打包进dll库中的结论。
接下来是动态加载外部图片的方法。
还是前面这个工程,所不同的是将xaml中Image控件的Source删去,只留下一个空白控件:
动态加载图片需要在cs代码中操作,因此需要给Image控件添加Name标识。
Image控件的Source属性接受的类型是ImageSouce,其原型如下所示:
public System.Windows.Media.ImageSource Source { get; set; }
而ImageSouce本身又是一个抽象类:
public abstract class ImageSource : System.Windows.Media.Animation.Animatable, IFormattable
其派生类主要有三个:
System.Windows.Interop.D3DImage
System.Windows.Media.DrawingImage
System.Windows.Media.Imaging.BitmapSource
在这里,适合我们的是 BitmapSouce 类。但是BitmapSource也是一个抽象类:
public abstract class BitmapSource : System.Windows.Media.ImageSource
且BitmapSouce有众多派生类:
System.Windows.Interop.InteropBitmap
System.Windows.Media.Imaging.BitmapFrame
System.Windows.Media.Imaging.BitmapImage
System.Windows.Media.Imaging.CachedBitmap
System.Windows.Media.Imaging.ColorConvertedBitmap
System.Windows.Media.Imaging.CroppedBitmap
System.Windows.Media.Imaging.FormatConvertedBitmap
System.Windows.Media.Imaging.RenderTargetBitmap
System.Windows.Media.Imaging.TransformedBitmap
System.Windows.Media.Imaging.WriteableBitmap
这里适合我们的是 BitmapImage。
BitmapImage创建图片对象的方式很简单,以下直接贴出相关代码了:
public MainWindow() { InitializeComponent(); BitmapImage bimg = new BitmapImage(); bimg.BeginInit(); bimg.UriSource = new Uri(@"res/myimg.png", UriKind.Relative); bimg.EndInit(); Img.Source = bimg; }
new Uri类时第一个参数填的是图片相对于工程的地址,即以 .csproj 文件作为起点的相对地址,第二个参数就是描述第一个参数是相对位置还是绝对位置的。一般我们都填相对位置就够了。
在应用了以上代码后再次运行程序,又可以看到熟悉的画面了:
通过修改外部图片的Build Action为Resource的方式预置图片的方式即使在程序通过Setup Project打包成安装包发到其它机器安装后仍然可以正常显示图片且不会直接看到图片文件的存在,如下图所示:
嗯,真不错!