How can I include an image as a Resource in my project? - c#

I want to add an image as a resource in my project so that I can reference it for programmatically inserting into a range in a spreadsheet.
I added the image by right-clicking the project and selecting Add > Existing Item...
I hoped that the image (.png file) would then be available using this code:
var logoRange = _xlSheet.Range[
_xlSheet.Cells[1, LOGO_FIRST_COLUMN],
_xlSheet.Cells[5, LOGO_LAST_COLUMN]];
//System.Drawing.Bitmap logo =
//ReportRunner.Properties.Resources.pa_logo_notap.png;
System.Drawing.Image logo =
ReportRunner.Properties.Resources.pa_logo_notap.png;
_xlSheet.Paste(logoRange, logo);
...but using either Bitmap or Image, I get, "'ReportRunner.Properties.Resources' does not contain a definition for 'pa_logo_notap'"
This seemed like sensible code based on what I read here, but it seems that the image has to be explicitly marked as a resource for this to work. How do I accomplish that?
UPDATE
I tried this:
System.Drawing.Image logo = (System.Drawing.Image)ReportRunner.Properties.Resources.ResourceManager.GetObject("pa_logo_notag.png");
_xlSheet.Paste(logoRange, logo);
...but not only did I get a confirmation msg about the item being pasted not being the same size and shape as the place where it was being inserted, and did I really want to do that, it also inserted some seemingly unrelated text ("avgOrderAmountCell.Style") instead of the image.
UPDATE 2
Okay, I tried this:
Assembly myAssembly = Assembly.GetExecutingAssembly();
System.Drawing.Image logo = (System.Drawing.Image)myAssembly.GetName().Name + ".pa_logo_notap.png";
Clipboard.SetDataObject(logo, true);
_xlSheet.Paste(logoRange, logo);
...but get, "Cannot convert type 'string' to 'System.Drawing.Image' on the second line of that code.
UPDATE 3
This works:
private System.Drawing.Image _logo;
. . .
_logo = logo; // logo (the image) is passed in an overloaded constructor
. . .
var logoRange = _xlSheet.Range[
_xlSheet.Cells[1, LOGO_FIRST_COLUMN], _xlSheet.Cells[6,
LOGO_LAST_COLUMN]];
Clipboard.SetDataObject(_logo, true);
_xlSheet.Paste(logoRange, _logo);
...but I'm not crazy about it, because I'm using an image that is on a form, and passing the image to this class's constructor. Passing images around seems kind of goofy when it should be possible to store the image as a resource and just load the resource. I still haven't gotten that methodology to work, though...
UPDATE 4
I reckon I'll just stick with what I've got (in Update 3), kludgy as it is, because this:
Assembly myAssembly = Assembly.GetExecutingAssembly();
Stream myStream =
myAssembly.GetManifestResourceStream(myAssembly.GetName().Name +
"pa_logo_notap.png");
Bitmap bmp = new Bitmap(myStream);
Clipboard.SetDataObject(bmp, true);
_xlSheet.Paste(logoRange, bmp);
...fails with, "Value of 'null' is not valid for 'stream'"

You have change the build action of the image to be embedded resource.
Then you can reference by doing:
UPDATED
Assembly myAssembly = Assembly.GetExecutingAssembly();
Stream myStream = myAssembly.GetManifestResourceStream( myAssembly.GetName().Name + ".images.pa_logo_notap.png");
Bitmap bmp = new Bitmap(myStream);

My method is to open Resources.resx under Properties. You'll see all your resources laid out on screen.
Click on the downarrow next to 'Add Resource' and you'll see the option Add Existing File. Choose your image name.

Related

c# WPF URI syntax

I am just learning c# and have been struggling to work with URIs in WPF. I've googled around a fair bit but not having much luck.
Essentially I'm trying to have a BitmapImage object stored as a property in a Car object. I then want to display the BitmapImage in an Image control on a WPF form.
The app is a simple app (it's for a Uni assignment), so no database, etc.
I have two methods of doing this. The first is that I'm preloading Car data from a text file, including the filename of the JPG I want to load. I have included the JPG in a directory called Files which is off the main directory where my source code and class files are. I have set the JPG file to 'Content' and 'Always copy'. When I run a Debug, it copies the Files directory and the JPG to the debug\bin directory.
My code creates a BitmapImage by referring to the JPG using a URI as follows;
BitmapImage myImage = new BitmapImage (new Uri("Files/" + Car.Imagefilename, UriKind.Relative);
Car.Image = myImage;
ImageControl.Source = myImage;
If I step through this code in the debugger, it sometimes works and displays the image, but most of the time it doesn't.
My second method is when a user creates a new Car. This method always works. In this one, I use a file dialog box (dlg) to select the image and use an absolute path.
BitmapImage myImage = new BitmapImage (new Uri(dlg.Filename, UriKind.Absolute);
Car.Image = myImage;
ImageControl.Source = myImage;
So....I can't work out why the first method doesn't work. I think it's got something to do with the relative reference, but I can't work out how to syntax that properly to work. I've tried using "pack:,,,", I've tried adding "component", I've tried an '#' before the "pack". I can't seem to find something that explains this simply.
Apologies if this is straight forward but it's doing my head in! Appreciate any pointers.
If the image files are located in a "Files" folder of your Visual Studio project, you should set their Build Action to Resource (and Copy to Output Directory to Do not copy), and load them by a Resource File Pack URI:
var image = new BitmapImage(new Uri("pack://application:,,,/Files/" + Car.Imagefilename));
Car.Image = image;
ImageControl.Source = image;
There is no need to copy the files anywhere. Images are loaded directly from the assembly.
First try to load the image file using its absolute path. For example if the images are stored in c:\projects\yourproject\files, then try using something like
BitmapImage myImage = new BitmapImage (new Uri("c:/projects/yourproject/files/carname.jpg", UriKind.Absolute);
If it works, what you are facing is an path calculation issue.
At this point you may either calculate the Absolute with reference to your executable using AppDomain.CurrentDomain.BaseDirectory at runtime or use App.Config to store the path and reference it from there.
Cheers

EPPlus Excel error when using AddPicture

I been trying to find the solution for this for so many hours i'm really tired, i hope someone can indicate me with i'm missing. I will try to be as clear as posible with all the possible information so there is no confusion.
I'm using EPPlus 3.1.3.0, Visual Studio 2010, C#, MVC.NET Framework 4.0 and MS Excel 2007
I'm just trying to do a simple thing: download an Excel file with a picture in it. Nothing else.
I have an action that opens an excel file, fills it with data and adds a picture which code looks like this:
public ActionResult FillExcelFile(string imagePath)
{
FileInfo template = new FileInfo([path_of_excel_file]);
ExcelPackage xls = new ExcelPackage(template);
ExcelWorksheet worksheet = xls.Workbook.Worksheets["Sheet1"];
worksheet.Cells[1, 1].Value = "data1";
worksheet.Cells[1, 2].Value = "data2";
worksheet.Cells[1, 3].Value = "data3";
/* ToDo: add picture */
return File(xls.GetAsByteArray(), "application/vnd.ms-excel", "excel.xlsx"));
}
At this moment everything works great! The file have the information and i can download and open it with no problem at all.
Now i will add the picture i want, i will change the ToDo part with the next code:
Image img = Image.FromFile(imagePath);
ExcelPicture pic = worksheet.Drawings.AddPicture("img", img);
pic.SetPosition(1, 1);
Run it, download it, open it aaand... error:
Excel found unreadable content in "excel.xlsx". Do you want to recover... blah blah blah
Of course i want to recover.
Files open aaand... is empty and an error appear:
Replaced Part: /xl/worksheets/sheet1.xml part with XML error. Load error. Line...
From this moment till now i been adding different code:
Image img = Image.FromFile(imagePath);
ExcelPicture pic = worksheet.Drawings.AddPicture("img", img);
pic.SetPosition(1, 1);
pic.SetSize(100, 100);
And...
Bitmap img = new Bitmap(Image.FromFile(imagePath));
ExcelPicture pic = worksheet.Drawings.AddPicture("img", img);
pic.SetPosition(1, 1);
And...
FileInfo img = new FileInfo(imagePath);
ExcelPicture pic = worksheet.Drawings.AddPicture("img", img);
pic.SetPosition(1, 1);
With the last one there as exception:
: System.ArgumentException: Part URI is not valid per rules defined in the Open Packaging Conventions specification
And many many many more like open the image with a stream, adding the setSize because someone said some kind of problem if you don't define it, define my own URI, save the file in the server then download it, etc.
I really appreciate any help that you can give me, really. I don't known what else to check. If you require more information be free to ask.
i found the problem... or kind of. Thanks to #Chris to guide me in this one and to #Ernie for the sugestion.
The problem is the template file that i was trying to fill has something inside that doesn't work fine when i try to add an image. #Chris says "you already have a drawing part in the template and EPPlus is creating some sort of conflict". I don't know what could that be.
So i create a new template from scratch (the template i was using was done by someone else) and everything worked like charm.
Steps that i performed:
I created a new file with using EPPlus and download it and it worked.
I created a new empty template and add the image with EPPlus and it worked.
I created a new template with all the stuff i needed in it and it worked.
I hope this help someone else if they have a similar problem.
I had the same problem. With prueba prueba's answer I analysed my original template and found this: If the table formatting feature (see screenshot) is used then AddPicture causes the XML errors. My solution was to remove the table formatting.
I've had the same issue and noticed that when you add a background-picture before adding the picture the file gets corrupted. If you add the background picture afterwards it works fine.
osheet.BackgroundImage.Image = My.Resources.anyimage
I found the same problem. I'm using the version 4.1.0.0.
I try to use this code:
Bitmap arquivoLogotipo = new Bitmap(#"C:\xxxxxx.jpg");
ExcelPicture logotipoExcel = principal.Drawings.AddPicture("logotipo", arquivoLogotipo);
logotipoExcel.SetPosition(50, 250);
I try this too:
FileInfo logotipoEndereco = new FileInfo("C\okokoko.jpg");
var logotipo = principal.Drawings.AddPicture("logotipo", logotipoEndereco);
logotipo.SetPosition(50, 250);
In my case, I just have a blank sheet. My cod just insert a name of a project and one image.I really don't know what is happening.
Thanks :D!

Winform loading an Image via an TCP message

I'm trying to have an image load in my winform through a TCP message.
At the moment I have a my program set to look in the required directory via the following. This line is held with in a TCP class I've set up:
Image _imageName = Image.FromFile("C:\\Image\\");
What my tcp command will do is send the following string line:
IMG Cat
The first 3 letters aren't important, but need to be in there. With this tcp command I've set up a switch statement that will act depending on those first three letters. So, my new _image name line looks like the following:
Image _imageName = Image.FromFile("C:\\Image\\" + splitString[1]);
The value of _imageName is then stored in a getter called Picture;
Inside my Image class I'm setting the file to be displayed like this:
PictureBox _picBox = new PictureBox();
_picBox.Image = Image.FromFile(_tcp.Picture);
However, I get the following errors:
The best overloaded method match for "System.Drawing.Image.FromFile(string) has some invalid arguments
Argument 1: cannot convert 'System.Drawing.Image' to 'string;
The line that is highlighted is the _picBox.Image line. I've tried googleing an answer. Casting the command as both an Image and a float, changing my getter. But nothing is working.
Does anyone know how I can fix this?
In this lines you are trying to create Image form another Image instance.
PictureBox _picBox = new PictureBox();
_picBox.Image = Image.FromFile(_tcp.Picture);
While FromFile method accepts string path to image file you want to load.
Fix it like this:
PictureBox _picBox = new PictureBox();
_picBox.Image = _tcp.Picture;

GetManifestResourceStream giving Null Reference exception ( Parameter name: streamSource)

I keep on getting a null reference exception from GetManifestResourceStream, am trying to add Logo image to the Lightswitch ribbon and it is supposed to work just fine....
was referring to LR__ http://social.msdn.microsoft.com/Forums/en-US/lightswitch/thread/2d16c638-f833-4c4c-beec-656912a87b8e/#76fa5382-0135-41ba-967c-02efc3f8c3a2
System.Windows.Media.Imaging.BitmapImage image = new System.Windows.Media.Imaging.BitmapImage();
image.SetSource(Assembly.GetExecutingAssembly().GetManifestResourceStream(
Application.Current.Details.Name + ".Resources.logo.jpg"));
Image myImage = new Image()
{
Source = image,
Stretch = System.Windows.Media.Stretch.Uniform,
HorizontalAlignment = HorizontalAlignment.Left,
Margin = new Thickness(2, 2, 2, 14),
Cursor = System.Windows.Input.Cursors.Hand
};
I tried a lot of things but I can't find my where the problem is!!
add your image or file in your project then select your file on the solution explorer window then on the properties window select Build Action then set value "Embedded Resource" to Build Action properties
just this
Does Logo.jpg have it's build action set to "Embedded Resource"?
Edit:
Here the C# translation of my GetResourceUri (note, it needs a Resource, not an Embedded Resource):
public Uri GetResourceUri(this Assembly asm, string resourceName)
{
Uri result = null;
var assemblyName = new AssemblyName(asm.FullName).Name;
result = new Uri(string.Format("/{0};component/{1}", assemblyName, resourceName), UriKind.Relative);
return result;
}
The same "technique" should work in C#.
I also have a custom shell extension (that uses LR's technique to add images to both the ribbon & the navigation menu). I'm just finishing a few things (writing the "documentation" is taking some time) & then I'll release it on the Visual Studio Gallery for the community to use (it's called Luminous Classic Shell).
The extension allows you to have the images without needing to write code.
You can use a tool such as Reflector to see the full names of the resources in the Assembly.
I had this null return problem & I was tearing my hair out because this using image files as embedded resources is one of my standard tricks.
I eventually found the reason was that I'd been sent files from a graphic designer who uses an Apple & they didn't work. I fiddled with permissions; used a Paint program to save them in a different format but nothing worked.
In the end I created a completely new file in Paint, then copied & pasted the pixels from the original image. It then worked.
Just for the record, does anyone know why this happened? It must be in the header blocks somehow.

C# - WPF how to unreference a BitmapImage so I can delete the source file?

This seems like a fairly simple issue, but I can't seem to figure a way to work around it.
In a WPF window I have an image, image_small_pic. In the associated C# file I set the value of that using this code:
Uri src = new Uri(image_source, UriKind.RelativeOrAbsolute);
small_image_bmp = new BitmapImage(src);
image_small_pic.Source = small_image_bmp;
Where small_image_bmp is a public BitmapImage object. But then if then, later on, if I change small_image_bmp to another file and reassign image_small_pic.Source, then the original image is still locked and I can't delete it. Even if I try later it's still locked. Any thoughts how I can free this up?
Check out this article. There's some odd behaviour with WPF images that you're coming across. The solution is to read in the bytes yourself and then create an image based on them, since if you let the framework handle it, the file will remain locked.
Uri src = new Uri(image_source, UriKind.RelativeOrAbsolute);
var small_image_bmp = new BitmapImage();
small_image_bmp.BeginInit();
small_image_bmp.CacheOption = BitmapCacheOption.OnLoad;
small_image_bmp.UriSource = src;
small_image_bmp.EndInit();
image_small_pic.Source = small_image_bmp;

Categories