change canvas image on button click in wpf - wpf

On button click I want to change the canvas image(background image) to another image which is in a folder(images is the folder name). This is what I have tried:
private void Button_Click_2(object sender, RoutedEventArgs e)
{
drawingCanvas.Children.Clear();
ImageBrush imageBrush = new ImageBrush();
imageBrush.ImageSource = new BitmapImage((new Uri(#"../Images/canvas.png", UriKind.Relative)));
drawingCanvas.Background = imageBrush;
}
First I'm clearing the contents of the canvas, deleting the previous image. Now want to set the background to another image. error: URI not handled exception. Any solutions will be appreciated. Thanks.

An image resource is loaded by a Resource File Pack URI:
imageBrush.ImageSource = new BitmapImage(
new Uri("pack://application:,,,/Images/canvas.png"));
In addition, the Build Actionof the image file has to be set to Resource, as shown in this answer.

Related

URI path in WPF window background image

I'm trying to assign a background to my WPF window.
I have a .jpg in bin\debug\StoredData\wallpaper.jpg
(I want to obtain the .jpg from there).
I came to putting this code inside the .cs file (newly created file):
InitializeComponent();
ImageBrush myBrush = new ImageBrush();
myBrush.ImageSource =
new BitmapImage(new Uri("\\StoredData\\login_wallpaper.jpg", UriKind.Absolute));
this.Background = myBrush;
But I get a "Invalid URI: The format of the URI could not be determined" message.
What should I change?
\StoredData\login_wallpaper.jpg is a relative URI. You can either change the UriKind to UriKind.Relative, or enter an absolute URI, depending on what behavior you want.

Blank - Black Image control in WPF if image source is absolute Uri

I use on listbox control own datatemplate. Listbox item consist one image control and some textblock.
On image source I bind property type of Uri (absolute url - for example: http://u.aimg.sk/fotky/1730/71/17307141.jpg?v=2)
Listbox have about 50 - 300 items.
If I test app, I sometimes see blank - white or black image instead user images.
The problem you can see on this images:
I would like to know what cause this problem and how can I solve this problem.
Image sources are good, I check it in browser.
Thank for advice.
I think what's happening is a race condition. Some of your images haven't completed downloading by the time you are asking them to display. There is a pretty good example given here http://social.msdn.microsoft.com/Forums/en/wpf/thread/dc4d6aa9-299f-4ee8-8cd4-27a21ccfc4d0 which I'll sum up:
private ImageSource _Src;
public ImageSource Src
{
get { return _Src; }
set
{
_Src = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("Src"));
((BitmapImage)_Src).DownloadCompleted += new EventHandler(MainWindow_DownloadCompleted);
}
}
void MainWindow_DownloadCompleted(object sender, EventArgs e)
{
PropertyChanged(this, new PropertyChangedEventArgs("Src"));
((BitmapImage)_Src).DownloadCompleted -= MainWindow_DownloadCompleted;
}
With the above code, your images that are binding to your property will be told to update with the PropertyChanged call when the value is first assigned as well as AFTER the images have downloaded 100%. This is taken care of in the DownloadCompleted event handler that is utilized in the above example. This should make them not appear as a black image anymore, but as their fully-ready selves.
Also, if you are using a stream to as the source for your images, you need to make sure you use BitmapCacheOption.OnLoad. Such as:
BitmapImage source = new BitmapImage();
source.BeginInit();
source.CacheOption = BitmapCacheOption.OnLoad;
source.StreamSource = yourStream;
source.EndInit();
This is because by default the image using the source will lazy load it and by then your stream is probably closed, which could also be why you get blank/black images.
Good luck.

Set an image source from code behind

I have a textbox where user will enter the url of the image :
suppose the user enters the following string -> C:\Users\malcolm\Desktop\img.png
imgSilverPart is a image control AND imageUrl is a string what i am getting from a textbox.
imgSilverPart.Source = new BitmapImage(new Uri(imageUrl, UriKind.RelativeOrAbsolute));
But the image is not being displayed.
This won't work. Silverlight runs in a safe Sandbox and you can't just access a file on the desktop.
So you have to call an OpenFileDialog, get the Stream to the file the user selected and set the Stream as source of the BitmapImage.
Add a Button in XAML and do the following in the Click event handler:
private void Button_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog openFileDlg = new OpenFileDialog();
if (openFileDlg.ShowDialog().Value)
{
using (var stream = openFileDlg.File.OpenRead())
{
var bitmapImage = new BitmapImage();
bitmapImage.SetSource(stream);
imgSilverPart.Source = bitmapImage;
}
}
}
As an alternative it's possible to use some special folders if your application runs in elevated trust mode as Out-Of-Browser app.
Maybe the kind of Uri was not determined corectly. Try tu use UriKind.Relative or UriKind.Absolute with valid relative or absolute url string.

using BitmapSource as Image source in WPF

I'm trying to update an Image (_browserScreenshot below) object in XAML by changing the source image every time an event determines the source needs updating. Right now I have this:
public BitmapSource GetScreen()
{
Bitmap bitmap = new Bitmap(app.Browser.ClientRectangle.Width, app.Browser.ClientRectangle.Height);
app.Browser.DrawToBitmap(bitmap, app.Browser.Bounds);
BitmapSource bitmapSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(bitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
bitmapSource.Freeze();
bitmap.Dispose();
bitmap = null;
return bitmapSource;
}
Then I have an event handler as shown:
app.BitmapSource.Changed += new EventHandler(BitmapSource_Changed);
void BitmapSource_Changed(object sender, EventArgs e)
{
Window1._browserScreenshot.Source = app.GetScreen();
}
Now whenever this event fires a new screenshot is taken and the source of the Image (called _browserScreenshot here) control should be updated. I keep getting an error about changing the IsFrozen propery, but I can't figure out how to change this correctly and have this work the way I want it to. Thanks in advance everyone.
In all likelyhood you want to Freeze the object. The problem you are having is that you want to create a completely new BitmapSource every time and let the garbage collector dispose of the old image.
The following line turned out to be my problem:
bitmapSource.Freeze();

Resize an Uploaded Image in Silverlight 3

I'm trying to resize an image in Silverlight 3 that has been submitted by a user via the OpenFileDialog control. I can grab the contents of the file and put it into a WriteableBitmap object and then display it on the screen just fine into an Image control. The Image control will even resize it to fit the size of the image control for me which is great.
The problem is the in memory image is still the original full resolution image, I kinda need to resize it in memory because I have a bunch of expensive operations I need to perform on it on a per pixel basis. So far I have the following code...
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
btnUploadPhoto.Click += new RoutedEventHandler(UploadPhoto_Click);
}
private void UploadPhoto_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog dialog = new OpenFileDialog();
dialog.Filter = "Image files (*.png;*.jpg;*.gif;*.bmp)|*.png;*.jpg;*.gif;*.bmp";
if (dialog.ShowDialog() == true)
{
WriteableBitmap bitmap = new WriteableBitmap(500, 500);
bitmap.SetSource(dialog.File.OpenRead());
imgMainImage.Source = bitmap;
txtMessage.Text = "Image size: " + bitmap.PixelWidth + " x " + bitmap.PixelHeight;
}
}
}
Problem is the WriteableBitmap class doesn't have a Resize method on it, and setting the height and width in the constructor doesn't seem to have any effect.
What you can do is create a new Image element and set its source to a Writeable bitmap created from the stream. Don't add this Image element to the visual tree. Create another WriteableBitmap of the final size you want. Then call Render on this WriteableBitmap passing the Image element and a ScaleTransform to resize the image to the appropriate size. You can then use the second WriteableBitmap as the source for a second Image element and add that to the visual tree. You can then allow the first Image and WriteableBitmap objects to get GCed so you get the memory back.
Have you looked at the WriteableBitmapEx project? It's an open source project with a tonne of extension methods for the WriteableBitmap class. Here's how you resize:
BitmapImage image = new BitmapImage();
image.SetSource(dialog.File.OpenRead());
WriteableBitmap bitmap = new WriteableBitmap(image);
WriteableBitmap resizedBitmap = bitmap.Resize(500, 500, WriteableBitmapExtensions.Interpolation.Bilinear);
// For uploading
byte[] data = resizedBitmap.ToByteArray();
I have used FJCore with some success, it's an open source C# imaging toolkit from Occipital. Includes in-memory resizing capability.
Also check out ImageMagick.

Resources