在C#中从项目的资源区加载图像

240

我的项目中有一个存储在Resources/myimage.jpg的图像。如何将此图像动态加载到Bitmap对象中?


1
看看这个答案:https://dev59.com/1XVD5IYBdhLWcg3wE3bz#7375570 - Roland
这是一个后来被问到的问题,但是相关的,如果不算重复的话: https://dev59.com/KGYr5IYBdhLWcg3wi6zd - vapcguy
17个回答

273

你是否在使用Windows Forms呢?如果你是通过属性/资源UI添加图片的,那么你可以从生成的代码中访问到该图片,所以你可以简单地这样做:

var bmp = new Bitmap(WindowsFormsApplication1.Properties.Resources.myimage);

不是,它被添加为普通文件到资源文件夹中。 - Pavel Bastov
10
好的,那么我认为@Hallgrim使用资源流给你提供了答案。如果你正在使用Windows表单,我建议你从UI中删除图像并重新添加它 - 这样更容易。 - Matt Hamilton

124
你可以通过以下方式获取图像的引用:

Image myImage = Resources.myImage;

如果您想要制作图像的副本,您需要执行以下操作:

Bitmap bmp = new Bitmap(Resources.myImage);

在使用完bmp后,请不要忘记将其销毁。如果您在编译时不知道资源图像的名称,可以使用资源管理器:

ResourceManager rm = Resources.ResourceManager;
Bitmap myImage = (Bitmap)rm.GetObject("myImage");

ResourceManager的好处是您可以在Resources.myImage通常超出范围或者您想动态访问资源的情况下使用它。此外,这也适用于声音、配置文件等。


25
注:使用 Properties.Resources.myImage; 来获取图片。(说明:这是一句指示,告诉你在代码中如何获取图片资源。翻译时需要保持原意,并简化语言,使其更易懂,但不能添加任何额外的解释或内容。) - splattne
1
我正在尝试使用您的方法将资源对象绑定到我的数据网格,但它没有显示出来。数据网格图像列是模板化的。 - alice7
我尝试将第一行转换为VB,但对于VB不起作用:( 有什么想法吗?这是我尝试的:Dim QR As Image = Resources.SampleQRCode.png - Zeek2
@Zeek2 可以尝试使用 Set 关键字。 - PetoMPP

74

您需要从资源流中加载它。

Bitmap bmp = new Bitmap(
  System.Reflection.Assembly.GetEntryAssembly().
    GetManifestResourceStream("MyProject.Resources.myimage.png"));

如果您想要知道程序集中的所有资源名称,请使用以下代码:

string[] all = System.Reflection.Assembly.GetEntryAssembly().
  GetManifestResourceNames();

foreach (string one in all) {
    MessageBox.Show(one);
}

34
有更简单的方法可供使用,因此不应该需要使用反射——这似乎过于复杂了。 - Charlie Salts
这个解决方案在 C# / Windows Phone .NETCF 中无法工作 - GetManifestResourceNames() 仅返回单个名称,即程序集 DLL 模块的名称。在清单中只有一个可用资源 - DLL 模块的流 Blob。如果没有C++和不安全代码允许您调用 Win32 API 调用,那么使用这个内存块会非常麻烦。 - Mark Jones
2
你也可以使用 typeof(this).Assembly 来简写。 - Sri Harsha Chilakapati
2
@SriHarshaChilakapati typeof(this) 不起作用。this.GetType().Assembly 是最接近你所说的,但它是有风险的,因为它会捕捉到一个可能在不同程序集中的继承超类。 - John Gibb
@JohnGibb,你能否给我澄清一下?我认为 typeof(this) 等同于 this.GetType(),是这样吗? - Sri Harsha Chilakapati
3
typeof(this); 无法编译,会得到 Error 1 Type expected 错误。 - John Gibb

29

比大多数提出的答案都要简单得多

tslMode.Image = global::ProjectName.Properties.Resources.ImageName;

1
如果文件不是资源清单的一部分,就无法以这种方式访问该文件,正如 OP 明确指出的那样,它只是作为一个文件添加进来的。 - Wobbles
1
他也想要一个 Bitmap 对象,而不是一个 Image 对象。 - vapcguy

19

最好的方法是在项目的资源设置中将它们添加为图像资源。然后,您可以通过使用 Resources.myimage 直接获取该图像。这将通过生成的 C# 属性获取图像。

如果您只将图像设置为嵌入式资源,则可以使用以下代码进行访问:

string name = "Resources.myimage.jpg"
string namespaceName = "MyCompany.MyNamespace";
string resource = namespaceName + "." + name;
Type type = typeof(MyCompany.MyNamespace.MyTypeFromSameAssemblyAsResource);
Bitmap image = new Bitmap(type.Assembly.GetManifestResourceStream(resource));

其中MyTypeFromSameAssemblyAsResource是你程序集中的任何类型。


1
不能使用"namespace"作为变量名,感谢您提供如何获取与资源相同程序集的MyTypeFromSameAssemblyAsResource。 - Jason Fuerstenberg
修复了打字错误,解决了Jason的问题。 - John Gibb

14

使用以下代码。我已经在 Windows 表格视图单元格中进行了测试。

Object rm = Properties.Resources.ResourceManager.GetObject("Resource_Image");
Bitmap myImage = (Bitmap)rm;
Image image = myImage;

“Resource_Image”资源的名称可以在项目中找到。

在项目的名称下,您可以找到“属性”。展开它。那里您可以看到“Resources.resx”文件。打开它。将您的文件名应用为“Resource_Image”。


14

我在多个项目中使用的代码... 它假定你仅将图像存储为位图而不是图标资源。

    public static Bitmap GetImageByName(string imageName)
    {
        System.Reflection.Assembly asm = System.Reflection.Assembly.GetExecutingAssembly();
        string resourceName = asm.GetName().Name + ".Properties.Resources";
        var rm = new System.Resources.ResourceManager(resourceName, asm);
        return (Bitmap)rm.GetObject(imageName);

    }

7

JDS的回答最好。C#示例加载图像:

  • 将图像作为资源包含在项目中(项目树 ->资源,右键单击添加所需的文件 ImageName.png)
  • 嵌入式资源(项目树 ->资源 ->ImageName.png,右键单击选择属性)
  • .png 文件格式(.bmp .jpg 也应该可以)

pictureBox1.Image = ProjectName.Properties.Resources.ImageName;

注意以下几点:

  • 资源图像文件为 "ImageName.png",文件扩展名应省略。
  • ProjectName 可能更适当地被理解为“程序集名称”,它是项目 -> 属性页面上的相应文本条目。

此示例代码行可在 VisualStudio 2015 Community 中成功运行。


6

我建议:

System.Reflection.Assembly thisExe;
thisExe = System.Reflection.Assembly.GetExecutingAssembly();
System.IO.Stream file = 
    thisExe.GetManifestResourceStream("AssemblyName.ImageFile.jpg");
Image yourImage = Image.FromStream(file);

来自 MSDN 的信息:http://msdn.microsoft.com/zh-cn/library/aa287676(v=vs.71).aspx

使用 Image.FromStream 更好,因为您不需要知道图像的格式(bmp、png 等)。


6
您可以像这样将bmp保存在变量中:
var bmp = Resources.ImageName;

希望这能有所帮助!

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