从相对路径加载图片

5

我正在为大学(一学期)的项目制作一个21点游戏,但遇到了一个无法解决的问题。

我试图加载卡牌图像以便在屏幕上显示,但是我一直都没有成功。我已经掌握了绝对路径;我可以从中加载,但任何尝试从相对路径加载都会失败。该项目必须是独立的;我不能要求我的教授将这些图像复制到根目录。

#if FROMDISK
        Uri myUri = new Uri(@"C:\cards\" + getFilename(r, s, "png"), UriKind.Absolute);
        PngBitmapDecoder decoder2 = new PngBitmapDecoder(myUri, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
        BitmapSource bmp = decoder2.Frames[0];
#else
        System.Reflection.Assembly myAssembly = System.Reflection.Assembly.GetExecutingAssembly();
        Stream myStream = myAssembly.GetManifestResourceStream("Blackjack." + getFilename(r, s, "png"));
        BitmapImage bmp = new BitmapImage();
        bmp.StreamSource = myStream;
#endif
        // Draw the Image
        im.Source = bmp;
        im.Stretch = Stretch.Uniform;
        im.Width = CARD_WIDTH;

(Context)

3个回答

7

您可以使用:

Uri uri = new Uri(@"FolderName\FileName.png",UriKind.Relative);
PngBitmapDecoder decoder2 = new PngBitmapDecoder(uri, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);

记得设置图像文件的属性(否则编译器会跳过它们),构建后可以查看bin/debug文件夹以验证文件是否在其应该在的位置:

  • 生成操作:内容
  • 复制到输出目录:始终复制

另一个选项是将文件作为嵌入式资源,然后您可以像这样访问它:

Bitmap bitmap = Properties.Resources.FileName;

我应该为哪个文件设置这些属性?在代码文件中设置它们似乎是错误的做法(说实话:我真的不知道它们到底是做什么的)。 - Sean Allred
我不确定为什么SO没有通知我所有这些,但我回家后会尝试一下! - Sean Allred

3
我喜欢在我的XAML中将图像声明为资源。我假设你现在仍然可以玩弄代码结构,希望对你来说没有太多新的概念。这是我的做法:
1. 在项目中创建一个名为“Images”的文件夹。 2. 将卡片的图像拖放到Visual Studio中的该文件夹中。确保它们的“Build Action”设置为Resource。 3. 按CTRL-SHIFT-A创建一个新的“Resource Dictionary”,并将其命名为CardImages.xaml。 4. 在App.xaml中链接此文件。如下所示(显示如何同时链接多个XAML文件,但当然要删除“AnyDictionary”行!)
App.XAML:
<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Controls/CardImages.xaml" />
            <ResourceDictionary Source="Controls/AnyDictionaryYouWant.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

将以下代码添加到CardImages.xaml中。将"MyBlackJackAssembly"重命名为您项目的程序集名称。
<Style TargetType="Image">
    <Setter Property="RenderOptions.BitmapScalingMode" Value="HighQuality" />
</Style>

<DataTemplate x:Key="Spade1">
    <Image Source="MyBlackJackAssembly;component/Images/Spade1.png" />
</DataTemplate>

<DataTemplate x:Key="Spade2">
    <Image Source="MyBlackJackAssembly;component/Images/Spade2.png" />
</DataTemplate>

然后,您可以像这样在代码中定位它们:
Label label = new Label();
label.ContentTemplate = (DataTemplate)label.FindResource("Spade1");

这将为您获取一个WPF标签对象,应该会显示您的卡片。这种技术适用于支持ContentTemplate的任何内容。然后,您可以将Label添加到UI上的网格中,我不确定您如何在屏幕上显示您的卡片。
对于21点应用程序,我可能会创建一个名为“Card”的UserControl,以便能够生成它,就像这样。这将把“卡生成”逻辑封装到自己的控件中,因此其余的代码可以专注于发牌。
XAML:
<myControls:CardImage Kind="Spades" Digit="1" />

或者在 c# 中这样写:

CardImage aCard = new CardImage();
aCard.Kind = CardImage.Kinds.Spades; //enum
aCard.Digit = 1;

1
我不确定为什么SO没有通知我所有这些,但我只想说我非常兴奋回家尝试一下!C#是一种非常方便的语言。 - Sean Allred

1
我正在加载一些在项目资源中导入的背景图片的方式:
this.staticBg.Source = new BitmapImage(
    new Uri(@"/Project;component/Images/" + ((App)App.Current).bgImage
                                          + ".jpg", UriKind.Relative));

其中,“Project”是项目名称。 基本上,您应该将图像添加到资源中,并使用相对URI调用它们。


我这样修改了我的代码:im.Source = new BitmapImage(new Uri(@"/Project;component/Images/" + getFilename(r, s, "png"), UriKind.Relative)) - 这样做正确吗?因为它似乎没有起作用。它没有抛出错误,只是什么也没有显示出来。'Images'是您创建的某个文件夹吗? - Sean Allred
@vermiculus 如果要将图像保留在应用程序中(并消除您可能需要的#FROMDISK),则必须在Visual Studio中将图像拖入项目中。 然后,确保其“生成操作”设置为“资源”(但通常这已经没问题了)。 然后,您可以像Clone所说的那样引用它,或者尝试更“WPF”的方法,即创建一个UserControl对象,用作窗口的可视对象。 - Joe
嗨,我通过右键单击项目名称并选择添加->新文件夹来创建了Images文件夹。然后通过右键单击图像文件夹并选择添加->现有项来导入实际图像。 构建操作设置为Content,并将复制到输出设置为始终复制(如果您想加快构建速度,也可以设置为仅在更新时复制)。 - Clone

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接