我有一种加载图像的方法,以供以后通过绑定使用。
当我按如下方式设置时,它可以工作:
public static ImageSource LoadImage()
{
return new BitmapImage(
new Uri("C:/User/Name/Documents/Visual Studio 2015/Projects/Project/bin/debug/subfolder/sprite.png", UriKind.Absolute));
}
然而,当我换成简单地使用:
public static ImageSource LoadImage()
{
return new BitmapImage(
new Uri("/subfolder/sprite.png", UriKind.Relative));
}
XAML没有显示图像。我查看了Environment.CurrentDirectory
,然后返回"C:/User/Name/Documents/Visual Studio 2015/Projects/Project/bin/debug/"
我已经用Google搜索解决方案,但似乎无法看到任何内容。
答案 0 :(得分:0)
如果您希望图像位于输出文件夹中。将您的图像添加到项目中,在Build Action中选择“Content”,然后在Copy to output directory选项中选择“Copy Always”。
您将在输出中获取图像,然后您可以使用Relative URI命令加载它。
答案 1 :(得分:0)
您应该从程序集资源文件中加载图像。
确保映像文件位于名为subfolder
的Visual Studio项目文件夹中,并将其Build Action设置为Resource
。然后按Resource File Pack URI:
public static ImageSource LoadImage()
{
return new BitmapImage(new Uri("pack://application:,,,/subfolder/sprite.png"));
}
答案 2 :(得分:0)
如果您不在项目中的任何地方使用它,并且将其标记为“资源”,则该图像将不包含在最终版本中。点击图片,然后在“生成操作”字段中选择“内容”。
答案 3 :(得分:0)
虽然我看到了你的评论,但我可以肯定地告诉你,你需要删除前导斜杠。
这个语法没有问题:
return new BitmapImage(new Uri("subfolder/sprite.png", UriKind.Relative));
我不会完全信任 Environment.CurrentDirectory
,因为我不知道 BitmapImage 如何处理相对 uri。
您可以尝试手动运行可执行文件,确保“子文件夹”在同一文件夹中。
当然,另一种选择是获取完整路径:
var fullPath = Path.GetFullPath("subfolder/sprite.png");
return new BitmapImage(new Uri(fullPath, UriKind.Absolute));
答案 4 :(得分:0)
查看具有不同路径定义的示例:
public class ImageUriViewModel
{
public Uri AbsoluteUri { get; }
public Uri RelativeUri { get; }
public Uri AbsoluteFromRelativeUri { get; }
public Uri AssemblyRelativeUri { get; }
public ImageSource AbsoluteImage { get; }
public ImageSource RelativeImage { get; }
public ImageSource AbsoluteFromRelativeImage { get; }
public ImageSource AssemblyRelativeImage { get; }
public ImageUriViewModel()
{
// Full path on my computer.
string AbsolutePath = "C:/Users/EldHa/Мои проекты/CyberForurm/CyberForurmWpf/Febr20y/bin/Debug/Images/sprite.png";
// Relative path on my computer.
// Note: there is no leading slash!
// The leading slash is interpreted as the path from the Root folder on the current drive.
string RelativePath = "Images/sprite.png";
AbsoluteUri = new Uri(AbsolutePath, UriKind.Absolute);
RelativeUri = new Uri(RelativePath, UriKind.Relative);
AbsoluteFromRelativeUri = new Uri(System.IO.Path.GetFullPath(RelativePath));
AssemblyRelativeUri = new Uri(System.IO.Path.GetFullPath(System.IO.Path.Combine(System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), RelativePath)));
AbsoluteImage = GetImage(AbsoluteUri);
RelativeImage = GetImage(RelativeUri);
AbsoluteFromRelativeImage = GetImage(AbsoluteFromRelativeUri);
AssemblyRelativeImage = GetImage(AssemblyRelativeUri);
}
private static ImageSource GetImage(Uri uri)
{
try
{
return new BitmapImage(uri);
}
catch (Exception)
{
return NotFile;
}
}
private static readonly ImageSource NotFile;
private static readonly double pixelsPerDip = VisualTreeHelper.GetDpi(new UIElement()).PixelsPerDip;
static ImageUriViewModel()
{
FormattedText text = new FormattedText("Not\r\nFile",
CultureInfo.CurrentCulture,
FlowDirection.LeftToRight,
new Typeface("Tahoma"),
12,
Brushes.Black,
pixelsPerDip);
Geometry textGeometry = text.BuildGeometry(new Point());
GeometryDrawing drawing = new GeometryDrawing(null, new Pen(Brushes.Red, 1), textGeometry);
NotFile = new DrawingImage(drawing);
NotFile.Freeze();
}
}
<Window.DataContext>
<local:ImageUriViewModel/>
</Window.DataContext>
<UniformGrid Background="AliceBlue" Columns="1">
<TextBlock Text="{Binding AbsoluteUri}" />
<Image Source="{Binding AbsoluteImage}"/>
<TextBlock Text="{Binding RelativeUri}" />
<Image Source="{Binding RelativeImage}"/>
<TextBlock Text="{Binding AbsoluteFromRelativeUri}" />
<Image Source="{Binding AbsoluteFromRelativeImage}"/>
<TextBlock Text="{Binding AssemblyRelativeUri}" />
<Image Source="{Binding AssemblyRelativeImage}" />
</UniformGrid>
</Window>
当从带有 exe 文件的文件夹(包括在 Studio 中运行)启动执行时 - 一切正常。
当从另一个文件夹(例如桌面上的快捷方式)启动执行时:
答案 5 :(得分:0)
您必须保留相对 URI 的前导 File.AppendAllLinesAsync
,这会使路径成为根目录,从而忽略任何基本 URI 的完整目录结构:
/
更新:
至于 var baseUri = new Uri("C:/User/Name/Documents/Visual Studio 2015/Projects/Project/bin/debug/");
var relative1 = new Uri("/subfolder/sprite.png", UriKind.Relative);
var relative2 = new Uri("subfolder/sprite.png", UriKind.Relative);
// file:///C:/subfolder/sprite.png
Console.WriteLine(new Uri(baseUri, relative1));
// file:///C:/User/Name/Documents/Visual Studio 2015/Projects/Project/bin/debug/subfolder/sprite.png
Console.WriteLine(new Uri(baseUri, relative2));
本身:像往常一样,官方 WPF 帮助确实有一些改进的空间。
BaseUri
中没有提到它的默认值实际上是 BitmapImage
而不是当前工作目录。UriSource
中有一些示例(混合路径是否有根),但他们忘记提及这仅在源是嵌入式资源时才有效。他们真的可以放置一个指向 this page 的链接。如果您不想将图片打包为资源,那么您有两个选择:
当然,StreamSource
属性的文档也很稀缺,只提到加载图片后,要将pack://application:,,,/ProjectName;component/WindowName.xaml
设置为CacheOption
才能关闭流。但简单地设置 OnLoad
是行不通的,所以完整的解决方案:
StreamSource
如果您不介意覆盖 public static ImageSource LoadImage(string relativePath)
{
var bmp = new BitmapImage();
bmp.BeginInit();
bmp.CacheOption = BitmapCacheOption.OnLoad;
bmp.StreamSource = File.OpenRead(relativePath);
bmp.EndInit();
return bmp;
}
中的默认 pack://...
值,正确的解决方案如下:
BaseUri