How to change image source on runtime? - wpf

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.

Related

Taking screenshort of WPF control not working in Win8

I have a function to capture the screenshot of a WPF control:
public System.Drawing.Bitmap CaptureScreenshot()
{
Point p = this.PointToScreen(new Point(0, 0));
System.Drawing.Rectangle rc = new System.Drawing.Rectangle((int)p.X, (int)p.Y, (int)this.ActualWidth, (int)this.ActualHeight);
System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(rc.Width, rc.Height);
using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap))
{
g.CopyFromScreen(rc.Location, System.Drawing.Point.Empty, rc.Size);
}
return bitmap;
}
This is working fine in Win7. However, in Win8, if this function is called from a context menu, the captured screenshot also shows the context menu. It is not waiting for my context menu to disappear before it's taking the screenshot.
Why it's working in Win7 but not Win8? How do I wait until context menu disappears before taking the screenshot? I tried several things like DoEvents or UpdateLayout() but they don't seem to help.
UPDATE:
Following pushpraj's comment, I got it working using RenderTargetBitmap:
var bitmap = new RenderTargetBitmap((int)grid.ActualWidth, (int)grid.ActualHeight, 96, 96, PixelFormats.Default);
bitmap.Render(grid);
Clipboard.SetImage(bitmap);
It seems to be working except one issue. My control has a light background, which turns into full black when I paste the clipboard. If I save the bitmap to a file directly, I don't have this problem. What's wrong?
UPDATE 2:
Okay, for the background problem using RenderTargetBitmap, I found a fix at here.

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.

Styling of WPF Chart AreaSerie in program

I need to create area series in WPF chart toolkit in a program, but I do not know how to change a color of serie.
Setting of PathStyle doesn't work even in XAML. According to source files area series should be binded to background color but this doesn't work either.
Thank you for your help.
I had a hard time also figuring out how to change colors. Changing Background colours or ColorPalette didn't seem to do anything. I solved the issue, for the LineSeries, by settings the background with a setter in the style ( the DataPointStyle of the LineSeries, which applies on a DataPoint)
so in vb :
Dim NLS = New LineSeries()
NLS.IndependentValuePath = "Time"
NLS.DependentValuePath = "Quantity"
NLS.Title = " Quantity in function of time"
NLS.ItemsSource = MyItemSource
Dim ThisStyle As New Style(GetType(DataPoint))
ThisStyle.Setters.Add(New Setter(BackgroundProperty, New SolidColorBrush(MyWantedColor)))
NLS.DataPointStyle = ThisStyle
I hope this can help you solve your issue for the Area Series.

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);

dynamic image download

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!

Resources