Label Adding Image Programatically -vs- Adding Image Using The VS2008 Designer - c#

I have a C# form that I am creating completely manually (i.e. without using the Visual Studio Design View). In this form I have a Label created (simply) as follows:
private Label myLabel = new Label();
Later on in the code, during a callback, I want to set an image for this label. I have found one way to do it and here is the code:
myLabel.Image = Image.FromFile("Images\\mark.png");
This works but the problem is, when I distribute my application I am going to always have to provide a folder (Images) containing mark.png.
This is acceptable I guess but it's really not what I want...
The interesting thing is, I looked at some other code I created where I used the Visual Studio Design View to add an image to a label and the Designer does it totally different.
It somehow parses the image, figures out the binary, and saves the base64 representation of this binary as a string in the .resx file:
<data name="fileDisconnect.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABkAAAAXCAYAAAD+4+QTAAAABGdBTUEAAK/INwWK6QAAAAlwSFlzAAAO
vAAADrwBlbxySQAAAA10RVh0U291cmNlAE51dm9sYaxPNfEAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5F
...
...
ns2di2Jn545YY+PJHw3ZbmREJBgZLDwzgehomExoMpmUG1spVLuhAG/80RSKwyEGo7ZBJNKcsrf/Pd7Q
MOijAUML48mPeAPCJ5FKhMcSBOt9Ach5ThKVujqeQvEa8v8FrglBl5d/7zYAAAAASUVORK5CYII=
</value>
Looking at the Designer file source code you can see it sets the image lable as follows:
this.fileConnect.Image = ((System.Drawing.Image)(resources.GetObject("fileConnect.Image")));
So, as you can see, doing it this way is much more elegant. There is no need to actually save the image to your hard disk and provide the image when delivering your application. The image information is stored in the .resx file and images are set getting the binary content programatically from the .resx.
My question is.... If I am creating my control manually how can I get the same kind of behavior? Can I create a .resx file, open the image with a HEX editor and copy the binary string into the .resx file? Then, when adding the image to the label I could just just do it like above.

If you save the image in Resources, you can just do this:
Label myLabel = new Label();
myLabel.Text = "whatever";
myLabel.Image = Properties.Resources.MyLabelImage;
this.Controls.Add(myLabel);

Related

Strange behaviour using resources in WPF application [duplicate]

I want to use localization in my project so I'm using ".resx" files.
I have two files "StringRes.resx" and "StringRes.fr.resx". As you can guess, I want that all the messages of my app change according to the CultureInfo of the user.
But when I do this :
public MainWindow()
{
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("fr");
InitializeComponent();
}
It doesn't change anything when I do :
Console.WriteLine(StringRes.FirstName);
Indeed, it's always the string in StringRes which is displayed and not the string from StringRes.fr
The both are in the same namespace.
Thank you for any help.
I have created my own test projected an I used "fr-FR" as a culture tag. The test project can be found on my skydrive.
Works perfect.
In short:
I set the culture in the Properties of the project to be en-US as that is what I would want my Resource.resx to be.
Then I created Resource.resx, Resource.fr-FR.resx and Resource.nl-NL.resx.
I filled them with the TestData string. And the created a window with 3 buttons with events hooked to them. Next to the buttons I created a textblock, the textblock is binded to a Text string field.
In the button events I change the culture and the Text field. And you can then see the change happen.
You first need to create your Resource.resx then in the same folder you need to create Resource.fr-FR.resx. The Resource.resx will get a codebehind file, all the cultured resource files should not. If your Resource.fr-FR.resx does have a culture file you did something wrong and it is best to delete that resources file and recreate it so it loses it's codebehind.

itextsharp hyperlink a image and have it open in default viewer when picked

I have a pdf file created with itextsharp with images in the file. I would like to put a hyperlink in the file that if you pick the picture it will open that picture in a picture viewer. I can set a hyperlink to a web address but have no idea how to get it to open a file. Below is the code, yes I know that c:\test.jpg is a bad hardcoded file name but it is just a test. When you click the picture it does nothing but I have no idea how to tell it what to do.
iTextSharp.text.Image pic =TextSharp.text.Image.GetInstance(comment.examplePic);
pic.ScaleToFit(200f, 200f);
Chunk cImage = new Chunk(pic, 0, 0, false);
Anchor anchor = new Anchor(cImage);
anchor.Reference = "c:\\test.jpg";
doc.Add(pic);
doc.Add(anchor);
A PDF is self-contained. This means that all the resources needed to show the PDF are (usually) stored inside the PDF (exceptions are for instance fonts that can be retrieved from the operating system).
When you have an image that is shown on a PDF page, the bytes of that image are stored in what we call an Image XObject. An XObject is an object that is external to the page, but that is stored as a separate object inside the PDF file.
You are asking to serve the image bytes stored inside this separate object to a viewer on the operating system. This is impossible. I don't know of any viewer that can take those bytes and somehow forward them to an image viewer.
I can think of three possible workarounds. I don't know if any of these workarounds is acceptable to you.
1. Serve the image online
You could put the image on a server and use the code you have in your snippet to link to that online image. Of course: this will only work if the person viewing the document is online and clicks OK when his viewer asks him if it's OK to link to a resources on the internet.
2. Serve the image as an annotation
In this case, you create an annotation for which you create an appearance that renders that same image XObject in the annotation layer (all annotations are shown on top of the page content). You can easily change the visibility status of an annotation to make it invisible (in your case, this would be the default status) or visible (in your case, this would be triggered by a JavaScript action when clicking the link).
There's an example of such an annotation here: Advertisement. If you open advertisement.pdf, you see an image with a button that says "Close this advertisement". Once you click that, the status of the annotation will be changed to invisible. You could do something similar, but the other way round: click a link to make it visible instead of invisible.
This solution doesn't depend on an external viewer, the image is shown in the PDF viewer.
3. Add the image as optional content
Starting with PDF 1.5, PDF supports optional content. See for instance the OptionalContentExample. In this example, we have some questions and answers, but the answers are not visible by default. See layer_actions.pdf. There are links "on / off / toggle" to make the answers visible or invisible.
You could do the same with images: you could add them to a layer that is invisible by default, but that can be made visible if somebody clicks a link. However: this requires a viewer that supports OCG (optional content groups) and the actions to change the status of these OCGs. For instance: if you would try the layer_actions.pdf example in the PDF viewer in Chrome, it won't work, but if you download the PDF and open it in Adobe Reader, you'll see the behavior I described.
Summarized:
You are asking something that is impossible, but there are workarounds. Please post another question if you have chosen a workaround and you don't succeed in making that workaround word (but please take into account that not all viewers support every workaround).
no offence but too much knowledge sometimes makes you ignorant of small things.
simple solution to this problem is here
http://kuujinbo.info/iTextSharp/imageAnchor.aspx
sample code that i implemented works like charm
PdfPCell p1 = new PdfPCell();
p1 = new PdfPCell();
p1.Padding = 0;
p1.Border = 0;
PdfPTable nav = new PdfPTable(1);
nav.WidthPercentage = 100;
nav.SpacingAfter = 12;
navbarImg.Annotation= new Annotation(0, 0, 0, 0, ur);
p1.Image = navbarImg;
nav.AddCell(p1);
_doc.Add(nav);

Change Image at Runtime Based On RadioButton Selection

I need to change the background image at runtime, based on which RadioButton the user clicks. I'm doing this in a WPF project in Visual Studio, and I need to put the code in the Checked event in the xaml.cs file
I have an Image control called imgBackground, with 6 images in its Source collection, which are listed in an Images folder in the Solution Explorer.
I've tried:
this.imgBackground.Source = "filename.jpg";
both with and without the quotes, and with various paths (I've tried too many different variations to list them all here) and nothing works - everything I've tried just gives an error in the editor, before I even try to build and run anything (the error given varies depending on what I'm trying at the time).
If you are using relative paths as filenames like
this.imgBackground.Source = "filename.jpg";
then these files must be in the same directory as the .exe of your program is.
One workaround would be to use absolute paths like
this.imgBackground.Source = #"C:\MyFolder\MyProject\filename.jpg";
Or, even further use the packaging mechanism of WPF or pack your images as resources into your assembly. Look at this thread.
EDIT:
For your clarification:
The Source-property demands an System.Windows.Media.ImageSource-object, which you must provide.
Do it like this:
BitmapImage bi3 = new BitmapImage();
bi3.BeginInit();
bi3.UriSource = new Uri("filename.jpg", UriKind.Relative);
bi3.EndInit();
this.imgBackground.Source = bi3;
Please refer to this documentation here.

How do I cast an icon from a resource file to an image for use on a button?

I'm trying to use an icon that I've added as a resource as the image on a button. I know it's possible because I can do it in other projects through the designer. However, I'm trying to do this with code. I added the icon as a resource to my project by following the steps in the accepted answer to this question. The resource is named CancelButtonIcon.
Now, I'm trying to add that icon as the image on a standard button with this code:
this.CancelButton.Image = (System.Drawing.Image)Properties.Resources.CancelButtonIcon;
However, I get an error message:
Cannot convert type 'System.Drawing.Icon' to 'System.Drawing.Image'
In the code that Visual Studio automatically generates when I use the designer, it looks like this:
((System.Drawing.Image)(resources.GetObject("SaveButton.Image")));
which results from manually adding a resource through the Properties window. How can I convert this icon resource to an image so it can be used on the button? Adding it through the designer is not an option (this button is created programmatically and thus isn't present in the designer).
You can use the Icon.ToBitmap method for this purpose. Note that a Bitmap is an Image.
CancelButton.Image = Properties.Resources.CancelButtonIcon.ToBitmap();
Not sure why, but any time I tried using the accepted answer's approach, the .ToBitmap() call was giving me array index out of bounds exceptions. I solved this by doing it this way instead:
System.Drawing.Icon.FromHandle(Properties.Resources.CancelButtonIcon.Handle).ToBitmap();

Add Image to Base64 Encoded ImageStream in Resources (resx)

I'm working on an older project, updating it. Part of the program has a toolstrip with many buttons on it, each with an image. I found that the images are stored in a Base64 encoded imagestream in the resx for the form and accessed as such:
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
...
this.imageList1 = new System.Windows.Forms.ImageList(this.components);
...
this.toolStrip1.ImageList = this.imageList1;
...
this.imageList1.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList1.ImageStream")));
...
this.toolStripButton1.ImageIndex = 0; //There are 41 images, so this can be between 0 and 40
I need to add another button with a new image. How can I add an image to this stream?
I cannot use the designer, as it crashes as soon as I load the form (I believe because it uses a custom component with unsafe code).
I could always just add a new image resource separate from the stream, but that would make that one button different and thus it would create problems with consistency, causing upkeep problems later. So I'm wondering if there is any way for me to edit the imagestream. I can access the raw base64 string, but I have no idea where to go from here.
Create another form.
Add an ImageList component.
Add an arbitrary image in order to generate an "imagestream".
Open old resx and copy the "value" element.
Open new resx and paste value element.
Open new form.
Add images as needed.
Save new form.
Open new form's resx file.
Copy value element.
Open old form's resx file.
Paste in new value element.
I found a way to do this using code:
imageList1.Images.Add( NEWIMAGE );
ResXResourceWriter writer = new ResXResourceWriter("newresource.resx");
writer.AddResource("imageList1.ImageStream",imageList1.ImageStream);
writer.Generate();
writer.Close();
writer.Dispose();
The code will write the updated ImageStream to the new resource file. I can then copy it to my current resource file.

Categories