dynamic image download - silverlight

Can you look at the code below?
Image img = new Image();
BitmapImage bi = new BitmapImage();
bi.UriSource = new Uri("OryxAntelope.jpg", UriKind.Relative);
img.Source = bi;
LayoutRoot.Children.Add(img);
It works fine.
But after I comment last line of code(//LayoutRoot.Children.Add(img);) picture not downloads.
What is the problem of this approach?
Thanks,
Vitaliy

The image is fetched only when it is first displayed. That is occurring after you add it to the layout (and the layout becomes visible).
What are you trying to accomplish? The example does not make it clear what the end result is.

Check out this article. You need to first download the image asynchronously with the WebClient control, and then you will be able to use/display it as you want. What I've done is set up a callback function, since its asynchronous, and you could put your code example in that function so that you don't try to add the image before it's finished downloading.
Hope this helps!

Related

WPF Bitmap performance

I'm trying to understand why my images are not snappy, so I built a sample to test WPF performance. I used a timer to calculate how long my "display images" event handler executed, and used a stop watch to measure how long it took the images to appear on the screen. The bottom line: when displaying 100, 1600, 2500 and 3600 images, WPF took 2, 9, 12 and 16 seconds after my code had finished to display the images on the screen. So I feel helpless: It seems I can't improve my code to make the images appear faster - I need to do something with WPF!
So my question is: What do I need to do differently to make the images display faster?
The test setup is simple:
The window contains a Grid. After the "test" button is clicked, row and column definitions are added.Then an Image is added to each cell of the grid as follows:
var image = new Image();
image.BeginInit();
image.Name = ImageNameFromCell(theRow, theColumn);
image.Stretch = Stretch.None;
image.HorizontalAlignment = HorizontalAlignment.Center;
image.VerticalAlignment = VerticalAlignment.Center;
RenderOptions.SetBitmapScalingMode(image, BitmapScalingMode.LowQuality);
image.EndInit();
theGrid.Children.Add(image);
Finally, the Source of each image is set to a bitmap:a gray-scale image already scaled down to the estimated screen size. The bitmap is generated as follows:
var smallerBitmapImage = new BitmapImage();
smallerBitmapImage.BeginInit();
smallerBitmapImage.DecodePixelWidth = (int)(theImageWidth);
smallerBitmapImage.UriSource = theUri;
smallerBitmapImage.CacheOption = BitmapCacheOption.None;
smallerBitmapImage.EndInit();
//BitmapFrame bitmapFrame = BitmapFrame.Create(this.FullPath);
var convertedBitmap = new FormatConvertedBitmap();
convertedBitmap.BeginInit();
convertedBitmap.Source = smallerBitmapImage;
convertedBitmap.DestinationFormat = PixelFormats.Gray16;
convertedBitmap.EndInit();
convertedBitmap.Freeze();
So, I'm at my wits end. The images appear with a noticeable delay, and it seems to be out of my control. What can I do?
What appears to have made the difference is setting the image's cache option to OnLoad
smallerBitmapImage.CacheOption = BitmapCacheOption.OnLoad;
This moved the work to my event handler, so now I can use pre-fetching to do this at the background.
Do you actually see all those images at the same time? If not you can use some ItemsControl with a virtualizing panel so only images in view are displayed. (Speaking of panels, your current setup could also be replaced with an ItemsControl which uses a UniformGrid as panel)
You could also try to write a better decoder, which probably is a wasted effort.

How to set window icon in code behind in wpf?

In xaml it is :
<View:BaseWindow.Icon>
/VBDAdvertisement;component/Images/logoVBD.png
</View:BaseWindow.Icon>
I want to convert it into code behind.
Thanks
Something like
myWindow.Icon = new BitmapImage(new Uri("/VBDAdvertisement;component/Images/logoVBD.png"));
You may need to qualify the path more though.
Edit: As i thought the path should be in pack-uri format:
"pack://application:,,,/VBDAdvertisement;component/Images/logoVBD.png"
This is the correct way to do it (assuming MyIcon.ico is placed on the root folder of a WPF project named MyApplication):
Uri iconUri = new Uri("pack://application:,,,/MyApplication;component/MyIcon.ico");
myWindow.Icon = BitmapFrame.Create(iconUri);
This is also what actually happens when you set the Icon property for the window in XAML.
When just setting the Icon to a new Bitmap, it will not be rendered smoothly and correctly, but instead quite a bit pixelated.
Try this its absolutely working for both png as well as ico image format.
window.Icon = BitmapFrame.Create(Application.GetResourceStream(new Uri("LiveJewel.png", UriKind.RelativeOrAbsolute)).Stream);

save writableimage to file in silverlight

How want to save the image of a canvas to a file.
var img = new WriteableBitmap(canvas1, null);
Image i = new Image();
i.Source = img;
var bitmap = new Bitmap(i);
I tried to use bitmap.Save( for saving the image but Bitmap is not supported by silverlight.
How would you save WriteableBitmap to a file?
The WriteableBitmap has a Pixels collection which can be used to access the rendered image. However you really need to get it stored in a known format (preferable PNG).
The imagetools codeplex project can do that for you.
See this blog for a simple example of using it for your purposes.

Displaying loading progress for Image control in WP7

How do I get loading progress with the percent loaded info when an image is loading?
I have this:
Image image = new Image();
image.Source = new BitmapImage(new Uri("http://somesite.com/someimage.jpg"));
I expected something like this:
image.Loading += RoutedEventHandler(image_Loading);
but I can't find any such event. There is Loaded (not related to loading the source) and ImageOpened (which fires after loading the source is complete and has effected a layout pass).
I know it is possible because I have seen other apps indicate loading progress for images (for example "img news reader"). Is this possible with the standard Image Control, is there a 3rd party control that provides this, or do I have to write my own?
DownloadProgress is the event I was looking for, and it was hiding in the BitmapImage class:
Image image = new Image();
BitmapImage myBitmap = new BitmapImage(new Uri("http://somesite.com/someimage.jpg", UriKind.Absolute));
myBitmap.DownloadProgress += new EventHandler<DownloadProgressEventArgs>(myBitmap_DownloadProgress);
image.Source = myBitmap;

How to change image source on runtime?

I get new bitmap from some other component ( dont have any control on the other component ) every 5 seconds and i need to update my wpf image control with the new bitmap ( every 5 seconds ... ).
I cant find any way to update this wpf image control in run-time.
How can i do it ?
Thanks.
There is a another question like this
Setting WPF image source in code
the answer boils down to
ImgOnForm.Source = new BitmapImage(new Uri(#"/yourApp;component/img.png", UriKind.Relative));
Here is what worked for me :
chemin = "/Assets/Images/" + nomFichier + ".gif";
MonImage.Source = new BitmapImage(new Uri(base.BaseUri, chemin));
None of the suggestions I found on the forums worked (I had no image, or an ArgumentException). But with "base.BaseUri" as first agument, it worked at last.

Resources