Silverlight Image Loading - silverlight

I'm a beginner just beginning to work with Silverlight with a very basic question. I want to display a .png image. I have already done it in the page.xaml file but I would like to do it in code (C#) so that I can add and remove images while my program is running. I have seen some code in which you add an image to the Children of a Canvas, but when I do this no images are ever displayed. Could someone provide some code and where to put it? Here is what I've been working with. There are no exceptions, but no image appears.
page.myCanvas.Children.Add(LoadImage("Image/MrBlue"));
public Image LoadImage(string resource)
{
Image img = new Image();
Uri uri = new Uri(resource, UriKind.Relative);
ImageSource imgSrc = new System.Windows.Media.Imaging.BitmapImage(uri);
img.SetValue(Image.SourceProperty, imgSrc);
return img;
}
The image is set to "Resource" and "Do not Copy."

Debugging Silverlight can be a pain, although it's quite possible to set up in VS2008 (which you might already have done. If you haven't feel free to ask...) and that can catch some of the 'simple' errors like having the wrong Uri for the image you want. Your code looks fine to me, although what I'm using is slightly different. If you want an example from a working app, the function I use for loading images is:
public void ShowPicture(Uri location)
{
Image pic = new Image();
pic.Source = new BitmapImage(location);
Grid.SetColumn(pic, 1);
Grid.SetRow(pic, 1);
LayoutRoot.Children.Add(pic);
}
Note that I have a using statement that includes System.Windows.Media.Imaging.
Even without full debugging, a utility like fiddler that shows the http requests might help track down bad Uris in code, which is all I can think of that might be wrong here. Hope it helps.

I tested your code and it works fine for me, so as Raumornie already hinted, it would seem to most likely be an issue with the path to the image. As per your code, is the image file located in a folder called Image in your Silverlight project and just named MrBlue? On a quick look, it seems to be missing the .png, or?
Good luck!

Related

WPF cannot set Build Action for added file [duplicate]

I would like to assign a BitmapImage from my Resources.resx to an Image.
Beforehand I saved a .png image to Resources.resx. This image is now located in "/Resources/logo.png".
After reading several SO posts and other articles I have this now:
logoImage.Source = new BitmapImage(new Uri(#"pack://application:,,,/Resources/logo.png"));
Unfortunately it doesn't work.
I don't know how to solve this.
I tried to replace the Pack-URI with the fullpath and it worked but I would like to use relative paths in order to use the same source on different machines on which the absolute path would be incorrect.
Can anyone help me out with this?
In order to make that Uri work, the file logo.png must be contained in a folder named "Resources" in your VS project (see first image), and its Build Action must be set to Resource (see second image).
This Resources folder is completely unrelated to Resources.resx. You may rename it to whatever you like.

Dynamically loading images from database to webpage momentarily messes up how the masterpage looks like

I'm a senior majoring in Computer Science. I'm new at web development. I'm using ASP.NET C# with MS SQL Server. I've been trying to figure out how to load images from the database onto the webpage. I have successfully done this with the following code.
<asp:Image ID="imageClient" runat="server" style="width:100px; height:100px;"/>
protected void LoadImage()
{
ModelDataContext mdc = new ModelDataContext();
byte[] image = (from c in mdc.Clients select c.Logo).FirstOrDefault().ToArray();
string base64String = Convert.ToBase64String(image, 0, image.Length);
imageClient.ImageUrl = "data:image/jpg;base64," + base64String;
}
Right now I'm just doing it for 1 image. I will eventually be using a repeater to display multiple images on the same page.
The problem is with the loading of the image. It does some weird stuff to the masterpage that it uses. It's as if it isn't applying the CSS to the masterpage. But a few seconds later it looks as it should. The problem is definitely with the loading of the image because there is no other loading problems on any of the other pages.
I tried posting pictures of what I am seeing, but my reputation is too low.
The problem isn't browser specific, it does the same thing in all the major browsers...
If anybody could help me with the problem that would be great.
/############################/
Edit: I realized the images that I was trying to view may have had a filesize too large and it was taking too long to get it from the database and to load the image. My new approach is to save the image to a folder within my project and saving the imageurl in the database to refer to the actual location of the image.
Is this the best approach keeping in mind I am nowhere near at being advanced in Web Dev?
Thanks
Caching the image to a folder can give you benefits such as reducing load on the database. If the web pages are in a busy environment (ie. many users) caching everything you can reducing the load on the database is desirable.
As to the initial image-tag. As far as I remember, the asp:Image doesn't support a Style tag as with html img tag. I think you would need to define a css in a style-sheet (or embedded in the page) and refer to that with the CssClass tag instead - or - use the .Style("property") = "mysetting" in code instead.
F.ex:
imageClient.Style("Width") = "100px"
imageClient.Style("Height") = "100px"

At design time pack uri is valid, but not at runtime?

I'm setting a Button's content to an Image. It looks something like this:
<Button>
<Image Source="pack://application:,,,/NavigationImages/nav_up_left.png" />
</Button>
In my project I have a subfolder named NavigationImages and within that folder is the image file nav_up_left.png.
When I view the Designer the image appears, however during runtime I get an IOException error saying it cannot locate the resource.
The Build Action is set to Resource.
Actually, this worked fine in one project. But when I copied it over the another project it fails. This seems like an incredibly simple problem, but I find myself stumped and ready to start pulling out hair. #_#
Your thoughts and suggestions will be much appreciated!
Whelp, I figured it out...kinda.
I copied that xaml code from one project where the output type is Windows Application, to another project where the output type is Class Library.
I didn't think of it at the time, but apparently when the output type is a Class Library the pack URI needs to change.
So instead of "pack://application:,,,/NavigationImages/nav_up_left.png" I changed it to "/ProjectName;component/NavigationImages/nav_up_left.png" and now it's working just fine.
I'm not 100% clear why this is works and not the former. I've read through the MSDN documentation on pack URIs in WPF but perhaps I misinterpreted something.
I'll leave this answer unchecked in the event someone can give me a good explanation why what I previously had doesn't work in a project with output type Class Library.
I'm probably missing something really simple. #_#
I just struggled with this same problem for quite a while, and I think that part of what was going wrong in the original was the missing word "component". I, for instance, had
myBitmapImage.UriSource = new Uri(#"pack://application:,,,/MyApp;images/mona2.jpg");
but should have had
... = new Uri(#"pack://application:,,,/MyApp;component/images/mona2.jpg");
The word "component" is not part of the pathname, despite its appearance -- it's a string literal that has to be there. Why? Someone thought it'd be a good idea, I guess.
And for those struggling with another part of the thing, what about "MyApp"? That's the name of the Assembly. Right-click on your project name, select "Properties...", and under the "Application" tab you'll see the "Assembly name:" field.
If you don't feel like searching for that (or worry that it might change, breaking your code), you can do this:
String appUri = #"pack://application:,,,/" +
System.Reflection.Assembly.GetEntryAssembly().GetName().Name + ";";
String path = appUri + "component/images/mona2.jpg";
myBitmapImage.UriSource = new Uri(path);
Not very pretty code, I admit -- it can clearly be shortened -- but it'll gets you where you need to go, I hope. Remember to set the "Build" property on your image file to "Resource"!
Just to shine a light on what was happening in your situation. The second pack uri. The one that worked. Is meant for resources located in an assembly other than the host application. By the sounds of it, the host application was loading this resource from the Class Library in question?
You can see the differences in the pack uri schemes here:
MSDN Pack URI Scheme
The uri changes slightly when referencing a resource from the main assembly, and referencing one from another assembly.
Also, the pack://application:,,, includes what is referred to as the "authority", to omit it would basically make it a relative path, both are valid in most cases where the application authority is assumed.
EDIT: basically because /Subfolder/Resource.xaml(.jpg etc.) and /Assembly;component/Resource.xaml are very similar, the latter tells the parser/loader that it's looking in a referenced assembly, not in the main application's assembly. (I imagine this helps speed up the search).
One other solution to getting this right:
Once your image Build Action is set to 'Resource' and you have rebuilt, navigate to the properties of your <Image /> object. The properties window will provide a ... file resource browser, whereupon selecting your image the Source="..." attribute of your <Image /> will be correctly filled in.

looping through an image folder in a wpf application

I currently am loading all images in a folder in my "MyPictures" folder on my machine which works fine...
foreach (string filename in Directory.GetFiles(Environment.GetFolderPath(Environment.SpecialFolder.MyPictures)))
What I really want to be able to do, though, is load all the images in my Images folder within my solution project. Can someone please tell me the correct syntax to do this?
[Nothing in your question (as it is currently stated) is really directly related to WPF as opposed to C# (and Windows development) in general, as far as I can tell. You might get a better reply if the question was tagged to C# as opposed to just WPF.]
I don't think there is a way to reference your solution's folder as such (nor does it really make much sense, as the users of your application won't in general have the solution, only the distributables).
If you need the directory to be within your solution folder somehow, maybe you should refer to the directory your executable resides in (...\SolutionDir\bin\Debug), which you can get using
System.IO.Path.GetDirectoryName(
System.Reflection.Assembly.GetExecutingAssembly()
.GetModules()[0].FullyQualifiedName);
(Of course, you could tack \..\.. to that to refer to the SolutionDir instead, but that'd be a bit ugly.)
Depending on the usage of the images, though, it'd probably be better to put them under one of the defined special directories -- Environment.SpecialFolder.CommonApplicationData sounds like the best candidate, if the images are to be shared by all users.
One way to access images stored in a folder inside the WPF project is to do the following:
If you have already added the images inside an Images folder, Add the images file names in the Resources.resx file under Properties. You can access the images in the code by the following
string imageFilename = "pack://application:,,,/APP.UI;component/Images/" + Properties.Resources.imagefilename;
var src = new BitmapImage();
src.UriSource = new Uri(imageFilename , UriKind.Absolute);

How to free WPF resources after they are no longer being used

I use a default image as a user avatar the first time my application is loaded. After that, the user can change their avatar. The problem is that after using a new avatar, the user cannot delete the old avatar. They get the error message: "file access denied". That means my application is still using the old image somewhere, but I don't know where.
My question is: How do I free the WPF resource after using it? I have looked around with Google, but found nothing.
Please help me!
Thanks.
You usually have to call Dispose() on class instances after use to free resources. Even better is to use the using statement that implicitly calls Dispose() like this:
using (FileStream fsSource = new FileStream(pathSource, FileMode.Open, FileAccess.Read))
{
// Load file content
}

Resources