How do I retrieve an image from my resx file? - c#

I have added an image to my form's resource file, myForm.resx, and I would like to use it in my code file, myForm.cs, but I am not entirely clear on how to get a handle to it.

You can just use Visual Studio to add it (Project, Properties, Resources, Add existing file), and then access it by name:
Bitmap bmp = Properties.Resources.<name_you_gave_it>;

See MSDN for ResourceManager
rm = new ResourceManager("Images", this.GetType().Assembly);
pictureBox1.Image = (System.Drawing.Image)rm.GetObject("flag");

The following code is extracted from this link
// Creates the ResourceManager.
System.Resources.ResourceManager myManager = new
System.Resources.ResourceManager("ResourceNamespace.myResources",
myAssembly);
// Retrieves String and Image resources.
System.String myString;
System.Drawing.Image myImage;
myString = myManager.GetString("StringResource");
myImage = (System.Drawing.Image)myManager.GetObject("ImageResource");

pictureBox1.Image = new Bitmap (global::<<project namespace>>.Properties.Resources.<<Filename>>);
Like the following, the one I implemented:
pboxSignedInStaffIcon.Image = new Bitmap(global::EasyRent.Properties.Resources.worker1);

Related

C# - How can I have a dynamic Image / BitmapSource accessible from XAML?

In my C# project I have a list of images which are resources compiled in the exe:
/Pics/Image1.png
/Pics/Image2.png
/Pics/Image3.png
...
In my code I process the images to match them to the theme of the application. The issue I am having is that I am trying to figure out an easy way to access these processed images in the XAML syntax.
This is how I typically access a resource image (pre-processed):
<Image Source="/Pics/Image1.png" />
So I would really like to access these processed images a similar way.
I tried a static dictionary like this:
<Image Source="{x:Static local:Theme.Images.ImageDictionary[/Pics/Image1.png]}" />
But this threw an error because it doesn't like the ".png", I haven't been able to get this working with dictionary keys. Not to mention this looks really ugly.
Ideally I would love to be able to "replace" the resource references, or create a resource at runtime (e.g. PicsProcessed/Image1.png) but haven't been able to figure a way to add or modify resources in a running C# application programmatically.
Any suggestions are really appreciated - thank you!
Have you tried creating a Bitmap then setting it as the image source? I think this should be easy. Give your image a name, say theImage. You can't possibly reference the image without giving it a name.
Try the following:
string path="/Pics/Image3.png";//path to the image
var bitmapImage=new Bitmap(new Uri(path));
theImage.source=bitmapImage;//set the bitmap as the source.
There are other ways you can achieve this though. Hope this helps?
It took a couple of days but I figured out a solution!
I moved all my images into another C# Project in the same solution, set to compile as a Class Libary DLL file called DynamicResources.dll (assembly name in the Project settings is "DynamicResources"). This project is added as a reference to the main project. As such I can access images in the XAML - clean and tidy:
<Image Source="/DynamicResources;component/pics/image1.png" />
Then in the post-build event for the main project, I rename the compiled .dll so it doesn't get loaded by the main .exe binary at launch:
copy "$(TargetDir)DynamicResources.dll" "$(TargetDir)DynamicResources.temp"
del "$(TargetDir)DynamicResources.dll"
Then I used a third-party library called Mono.Cecil to load the DynamicResources.temp file (DLL format), replace the resources, write it back to memory, then tell the application to load it:
public static void UpdateAssembly()
{
string dllFile = "DynamicResources.temp";
string dllNamespace = "DynamicResources";
var asm = AssemblyDefinition.ReadAssembly(dllFile);
var module = asm.Modules.FirstOrDefault();
var resources = module.Resources;
var dllResource = (EmbeddedResource)(resources.FirstOrDefault());
var dllResourceReader = new ResourceReader(dllResource.GetResourceStream());
var newResourceOutputStream = new MemoryStream();
var newResourceWriter = new ResourceWriter(newResourceOutputStream);
foreach (DictionaryEntry dllResourceEntry in dllResourceReader)
{
var image = (BitmapSource)new ImageSourceConverter().ConvertFrom(dllResourceEntry.Value);
Color foreground = (Color)ColorConverter.ConvertFromString("#FFFFFF");
var processed = (WriteableBitmap)ColorizeImage(image, foreground); // Your image processing function ?
newResourceWriter.AddResource(dllResourceEntry.Key.ToString(), BitmapToByte(processed));
}
newResourceWriter.Close();
var newResource = new EmbeddedResource(dllResource.Name, dllResource.Attributes, newResourceOutputStream.ToArray());
module.Resources.Remove(dllResource);
module.Resources.Add(newResource);
var woutput = new MemoryStream();
asm.Write(woutput);
var doutput = woutput.ToArray();
Assembly assembly = Assembly.Load(doutput);
}
public static MemoryStream BitmapToByte(BitmapSource bitmapSource)
{
var encoder = new System.Windows.Media.Imaging.PngBitmapEncoder();
var frame = System.Windows.Media.Imaging.BitmapFrame.Create(bitmapSource);
encoder.Frames.Add(frame);
var stream = new MemoryStream();
encoder.Save(stream);
return stream;
}
public static void AttachAssembly(string myAsmFileName)
{
Assembly assembly = Assembly.LoadFile(AppDomain.CurrentDomain.BaseDirectory + myAsmFileName); // LoadFrom
AppDomain.CurrentDomain.Load(assembly.GetName());
}
Important note: When iterating through resources, they become lowercase, so you must use lowercase file and folder names.

load an image from resources in Visual C#, using a string?

If I have some resources, eg card1.png, card2.png, etc,
I want to them load them into a picBox, but only load the correct image
eg, something like
int cardNum = rn.Next(0,cardMax);
picCard.Image = Properties.Resources."card"+cardNum+".png";
Obviously that doesn't work, but how would I do what I am trying to do (load the correct resource after building the resource name into a string)
Instead of the generated properties in the Resources class use the ResourceManager directly:
string resName = $"card{cardNum}.png"; // Check the correct name in the .resx file. By using the wizards the extension is omitted, for example.
picCard.Image = (Image)Properties.Resources.ResourceManager.GetObject(resName);
Try using:
var rm = new System.Resources.ResourceManager(((System.Reflection.Assembly)System.Reflection.Assembly.GetExecutingAssembly()).GetName().Name + ".Properties.Resources", ((System.Reflection.Assembly)System.Reflection.Assembly.GetExecutingAssembly()));
Image img = (Bitmap)rm.GetObject("resourcesimagename.jpg");

How to make the Bitmap Constructor take a string

I know this question has been asked before, but i couldnt find an answer for my specific situation. Im trying to create new bitmap from a resource image.
private void button1_Click(object sender, EventArgs e)
{
string test = "meridian_am";
string resources = "Resources.Properties.Resources." + test;
var master = new Bitmap(Resources.Properties.Resources.master);
var meridian_am = new Bitmap(resources);
using (Graphics g = Graphics.FromImage(master))
{
g.DrawImageUnscaled(meridian_am, 114, 332);
}
}
for some reason, for the *var meridian_am = new Bitmap(resources)* im getting an invalid parameter error.. Ultimately, i would rather do a string concatenation on the fly, as in var meridian_am = new Bitmap(Resources.Properties.Resources. + test), but for some reason that wont work... Any ideas?
I'm no expert in C#, but... for var master = ... you're passing a resource that might well be an Image or something like that, while for var meridian = ... you're passing a string as the parameter, which should be the path to an accessible file.
Hope that helps.
EDIT:
I'm talking this constructor versus this one.
Does Resources.Properties.Resources.master contain image bytes or string (path to file name)? In any case you can't pass raw string "Resources.Properties.Resources.meridian_am" to Bitmap constructor. It treats it as path to file, not your resource.
You should load data from resources by this name before. Something like that (if your resource contain image bytes):
var assembly = System.Reflection.Assembly.GetEntryAssembly();
var resources = assembly.GetManifestResourceStream("Resources.Properties.Resources." + test);

Image from resources as a footer in excel

How can I use an image from resources as a footer in created excel file?
this definately will not work:
xlWorkSheet.PageSetup.CenterFooterPicture = Properties.Resources.stopka;
since:
Cannot implicitly convert type 'System.Drawing.Bitmap' to Microsoft.Office.Interop.Excel.Graphic'
Ok this works:
xlWorkSheet.PageSetup.CenterFooterPicture.Filename = Application.StartupPath + "\\stopka.png";
xlWorkSheet.PageSetup.CenterFooterPicture.LockAspectRatio = Microsoft.Office.Core.MsoTriState.msoTrue;
xlWorkSheet.PageSetup.CenterFooterPicture.Width = 590;
xlWorkSheet.PageSetup.CenterFooter = "&G";
But it is not what I needed. I would like to get the image from project resources not from application folder.
This works:
System.Reflection.Assembly CurrAssembly = System.Reflection.Assembly.LoadFrom(System.Windows.Forms.Application.ExecutablePath);
System.IO.Stream stream = CurrAssembly.GetManifestResourceStream("Oferty_BMGRP.Resources.stopka.png");
string temp = Path.GetTempFileName();
System.Drawing.Image.FromStream(stream).Save(temp);
xlWorkSheet.PageSetup.CenterFooterPicture.Filename = temp; //Application.StartupPath + "\\Resources\\stopka.png";
xlWorkSheet.PageSetup.CenterFooterPicture.LockAspectRatio = Microsoft.Office.Core.MsoTriState.msoTrue;
xlWorkSheet.PageSetup.CenterFooterPicture.Width = 590;
xlWorkSheet.PageSetup.CenterFooter = "&G";
the image "stopka.png" had to be set as embeded resource.
Since microsoft doesn't provide the set option for CenterFooterPicture property
The following is the documentation available in MSDN
CenterFooterPicture - Returns a Graphic object that represents the picture for the center section of the footer. Used to set attributes about the picture.
Link to Refer

Path to an embedded resource file

I have an icon in my resource file , which I want to reference.
This is the code that needs that path to an icon file:
IWshRuntimeLibrary.IWshShortcut MyShortcut ;
MyShortcut = (IWshRuntimeLibrary.IWshShortcut)WshShell.CreateShortcut(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + #"\PerfectUpload.lnk");
MyShortcut.IconLocation = //path to icons path . Works if set to #"c:/icon.ico"
Instead of having an external icon file I want it to find an embedded icon file.
Something like
MyShortcut.IconLocation = Path.GetFullPath(global::perfectupload.Properties.Resources.finish_perfect1.ToString()) ;
is this possible ? if so how ?
Thanks
I think this should work, but I can't remember exactly (not at work to double check).
MyShortcut.IconLocation = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("YourNamespace.IconFilename.ico");
Just expanding on SharpUrBrain's answer, which didn't work for me, instead of:
if (null != stream)
{
//Fetch image from stream.
MyShortcut.IconLocation = System.Drawing.Image.FromStream(stream);
}
It should be something like:
if (null != stream)
{
string temp = Path.GetTempFileName();
System.Drawing.Image.FromStream(stream).Save(temp);
shortcut.IconLocation = temp;
}
I think it will help you in some what...
//Get the assembly.
System.Reflection.Assembly CurrAssembly = System.Reflection.Assembly.LoadFrom(System.Windows.Forms.Application.ExecutablePath);
//Gets the image from Images Folder.
System.IO.Stream stream = CurrAssembly.GetManifestResourceStream("ImageURL");
if (null != stream)
{
//Fetch image from stream.
MyShortcut.IconLocation = System.Drawing.Image.FromStream(stream);
}
The res protocol may be able to help you with this: http://msdn.microsoft.com/en-us/library/aa767740(v=vs.85).aspx
In WPF I have done this before:
Uri TweetyUri = new Uri(#"/Resources/MyIco.ico", UriKind.Relative);
System.IO.Stream IconStream = Application.GetResourceStream(TweetyUri).Stream;
NotifyIcon.Icon = new System.Drawing.Icon(IconStream);
The resource it is embedded, so incapsulated in a DLL assembly. So you cannot get its real path, you have to change your approach.
You would probably want to load the resource in memory and write it down to a temp file, then link it from there. Once the icon is is changed on the destination file, you can delete the icon file itself.

Categories

Resources