【问题标题】:Can't find embedded resource using GetManifestResourceStream使用 GetManifestResourceStream 找不到嵌入式资源
【发布时间】:2015-07-12 10:41:51
【问题描述】:

我目前正在开发一个卡片 DLL,其中我需要每个卡片的图像文件作为嵌入式资源,当前项目如下所示:

注意:卡片图片 (.png) 位于 Resources 文件夹中。

我一直在尝试的代码几乎是我能找到的唯一代码,是这样的:

Assembly _assembly;
Stream _imageStream;

private Image img;
public Image Img
{ 
get
    {
        return img;
    }
}

public Kaart() : this(5, "Spades") { }

public Kaart(int val, string s)
{
    this.KaartWaarde = val;
    this.Figuur = s;
    this._imageStream = imgS();
    this.img = new Image(_imageStream);
}

private Stream imgS()
{
    try
    {
        _assembly = Assembly.GetExecutingAssembly();
        Stream s = _assembly.GetManifestResourceStream(string.Format("{0}{1}.png", this.kaartWaarde, this.figuur.Substring(0, 1)));
        if (s != null)
            return s;
        else
            return null ;
    }
    catch
    {
        throw new Exception("Kaart kan niet geladen worden.");
    }
}

我似乎得到的唯一例外是创建 Kaart 对象的异常,代码在这里:

Kaart k = null;
try
{
    k = new Kaart();
}
catch (Exception ex)
{
    MessageBox.Show(ex.Message); //This MessageBox is being shown
}
ImageSourceConverter c = new ImageSourceConverter();
testBox.Source = (ImageSource)c.ConvertFrom(k.Img);

使用MessageBox捕获并显示的异常如下:

“null”的值对“stream”无效。

在代码执行期间观察我的变量时,我注意到了这条线

Stream s = _assembly.GetManifestResourceStream(string.Format("{0}{1}.png", this.kaartWaarde, this.figuur.Substring(0, 1)));

即使使用Kaarten.{0}{1}.png格式也找不到图像

这只是让我想知道我是否在这里做错了,或者我是否使用了错误的语法。有什么想法吗?

编辑: 图像现在已正确加载,但 ImageSourceConverter 仍在抛出 NullReferenceException

据我所知,卡片创建和加载 Stream 对象(并将它们卸载到 Image 对象中)现在工作正常,但是当尝试使用代码在我的 WPF 图像控件中实际显示图像时下面,会抛出 NullRefException。

Kaartspel kaarten = new Kaartspel();

Kaart k = kaarten.kaarten[7];

ImageSourceConverter c = new ImageSourceConverter();
testBox.Source = (ImageSource)c.ConvertFrom(k.Img); //Exception here

【问题讨论】:

  • (1) 如果你这样调用会发生什么:_assembly.GetManifestResourceStream("Kaarten.Resources.5S.png"); (2) 哪里抛出了异常? (3) 显示它的完整堆栈跟踪。
  • @Alex 此处抛出异常:testBox.Source = (ImageSource)c.ConvertFrom(k.Img); 至于堆栈跟踪,我已经尝试弄清楚它是如何工作的,但我似乎无法...所有我发现到目前为止,在即时窗口中使用了一些“k”命令,但我似乎无法找出正确的语法?另外,当我尝试_assembly.GetManifestResourceStream("Kaarten.Resources.5S.png"); 时,没有什么不同
  • 您的问题是典型的XY question。如果您问“如何让我的图像控件显示存储在 WPF 中我的应用程序资源中的图像”,您会更快地得到不同的答案。进行互联网搜索将为您提供答案。
  • 我明白了,但这就是我最初搜索的内容,并且该搜索使我得到了我现在正在尝试的解决方案。问题是,由于某种原因,该解决方案根本不适合我,我想/需要找出原因。此外,该特定搜索不会完全帮助我,因为我需要将图像存储在我的类库中,而不是我的实际应用程序:)
  • 在构建动作中将图片资源设置为嵌入资源

标签: c# stream embedded-resource system.drawing


【解决方案1】:

要获取资源,您应该使用GetManifestResourceStream(string) 和区分大小写的限定资源名称,该名称由两个点分隔的部分组成:

  1. 包含资源的项目的默认命名空间。在大多数情况下,默认命名空间等于项目名称。
  2. 包含项目相对路径的资源文件名。所有目录分隔符都必须替换为点。
resource_name ::= default_namespace '.' full_file_name
full_file_name ::= (directory_name '.')* file_name

在你的情况下:

string name = string.Format("Kaarten.Resources.{0}{1}.png", this.kaartWaarde, this.figuur.Substring(0, 1)));
Stream stream = _assembly.GetManifestResourceStream(name);

另一种获取资源的方法是使用GetManifestResourceStream(Type, string)。在这种情况下,名称相对于指定类型的命名空间(MSDN,请参阅备注)。

string name = string.Format("Resources.{0}{1}.png", this.kaartWaarde, this.figuur.Substring(0, 1)));
Stream stream = _assembly.GetManifestResourceStream(typeof(Kaart), name);

【讨论】:

    【解决方案2】:

    哪个Image 类提供了一个接受流的构造函数?

    猜你可以使用System.Drawing.Image.FromStream 并将其转换为System.Drawing.Bitmap。然后您可以使用以下内容:

    System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(bitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());

    【讨论】:

      【解决方案3】:

      _assembly.GetManifestResourceStream("{ProjectName}.resources.{ImageName.ext}");

      这将正确加载图像。

      Resources != 资源,这将导致它出错。

      【讨论】:

      • 试过.Resources.img..resources.img.,小“r”返回null,大“R”确实返回一个值,但它仍然没有被转换。
      • @Yorrick,您应该在新帖子中提出第二个问题。这是 Stack Overflow 的规则。
      【解决方案4】:

      解决此问题的最简单方法是获取嵌入资源名称的列表:

      string[] result = myAssembly.GetManifestResourceNames();
      

      在单元测试中运行它,或者创建一个引用程序集的单独控制台应用程序,执行 typeof().Assembly.GetManifestResourceNames()。

      记得在每个文件上指定构建操作:嵌入式资源并至少构建一次程序集以嵌入文件。

      我不确定,但我认为您应该使用的文件名遵循 (?.

      【讨论】:

      • 我已经使用了.GetManifestResourceNames(); 方法并且他们已经确认了名称是Kaarten.Resources.[name].png 的事实我想我已经在我的问题中更新了这个,但显然我没有,我会在几秒钟内更新它。
      【解决方案5】:

      我想以强类型的方式从 Properties.Resources 访问我的图像。

      要实现这一点,请右键单击项目根目录并选择“属性”,然后打开“资源”选项卡并将图像拖放到此处(您可以从项目的名为资源的文件夹中选择它们)。

      【讨论】:

        猜你喜欢
        • 2013-05-19
        • 2015-03-09
        • 1970-01-01
        • 1970-01-01
        • 2011-10-30
        • 1970-01-01
        • 2011-01-09
        • 2011-03-05
        • 1970-01-01
        相关资源
        最近更新 更多