How to bind Image source? - wpf

From some examples, I think I'm doing this right, but it's not working so I wanted to check here to see. I'm binding my Image source, but the image is not there. If I take away my binding and just set the Image source to the path used in the method below it works fine.
public Image myImage = new Image();
public void someMethod() {
BitmapImage biSource = new BitmapImage();
biSource.BeginInit();
biSource.CacheOption = BitmapCacheOption.OnLoad;
biSource.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
biSource.UriSource = new Uri(#"C:\Images\testimage.jpg");
biSource.DecodePixelWidth = 150;
biSource.EndInit();
myImage.Source = biSource;
}
xaml code
<Image Source="{Binding Path=myImage}" Width="150" Height="150" />

You should bind the Source property to an ImageSource, not an Image. Expose biSource as a property and bind to it instead of myImage

You try to bind an Image to the source of an Image, not going to work. You need to bind the BitmapImage to the source of the Image.
Also the BitmapImage needs to be exposed as public property. If you are new to data binding read this overview on MSDN.
Further you should learn how to debug bindings.

Related

Why does binding image path to Image.Source does not work this way

I have an image path declared as following:
public static string _edit_vector32 = "pack://application:,,,/Resources/Images/Icons/32/edit-vector2-32.png";
I try to add a simple property that returns an ImageSource to my ViewModel as following:
public ImageSource ClockImage
{
get
{
return new BitmapImage(new Uri(RuntimeSettings._clock24)) as ImageSource;
}
}
Then bind in XAML:
<Image Source="{Binding ClockImage}"/>
Why does this not work, while:
<Image Source="pack://application:,,,/Resources/Images/Icons/32/edit-vector2-32.png"/>
Works as expected?
<Image Source="pack://application:,,,/Resources/Images/Icons/32/edit-vector2-32.png"/>
This works because ImageSource has a value converter (ImageSourceConverter) attached to it, which automatically converts strings to image sources.
The first case should work too (and does in my test project).

Load image from another assembly's resx file in XAML

I have two assemblies, say assembly1 and assembly2.
In assembly2 there is a XAML file. In this XAML file I want to create an image.
What I want to do is setting the source of this image to a bitmap that is in a resx file from assembly1.
<Image Name="image1" Stretch="Fill" Source="???" />
How do I correctly reference to that bitmap file in XAML? Is there an easy "XAML-only" solution?
Okay, so I assume there is no thing such as an "XAML-only" solution.
Instead, I do it like this after the WPF control's Loaded event is called:
Assembly coreAssembly = Assembly.GetAssembly(typeof (otherAssembly.Resources));
var resourceManager = new ResourceManager("otherAssembly.Resources", coreAssembly);
// get image from core resources
Bitmap completeImage = (Bitmap) resourceManager.GetObject("Complete");
// apply image to WPF image
var memoryStream = new MemoryStream();
completeImage.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Png);
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.StreamSource = new MemoryStream(memoryStream.ToArray());
bitmapImage.EndInit();
this.myWpfImage.Source = bitmapImage;

accessing pictures in my exe of wpf app from codebehind

im currently accessing my image in XAML and setting it to a picturebox with
Source="/SocialShock-WPF-Client;component/Images/blue-bar-replication.png"
how would i do this in the codebehind?
public static BitmapImage GetImageFromResource(string name)
{
var res = new BitmapImage();
res.BeginInit();
res.StreamSource = Assembly.GetExecutingAssembly().GetManifestResourceStream("SocialShock-WPF-Client.Images." + name);
res.EndInit();
return res;
}
Invoke this method with the image name, "blue-bar-replication.png" in your case.
The image build action should be set to EmbededResource.
Exactly the same way. Create BitmapImage object (pass Uri object with the same path to its constructor). Then set Image's Source property to the newly created BitmapImage object.

Silverlight Image Data Binding

I am new to Silverlight, and have an issue with binding.
I have a class ItemsManager, that has inside its scope another class Item.
class ItemsManager
{
...
class Item : INotifyPropertyChanged
{
...
private BitmapImage bitmapSource;
public BitmapImage BitmapSource
{
get { return bitmapSource; }
set
{
bitmapSource = value;
if(PropertyChanged != null )PropertyChanged("BitmapSource")
}
}
}
}
I do the following in code to test binding:
{
ItemsManager.Instance.AddItem("123");
//Items manager started downloading item visual
//part (in my case bitmap image png)
Binding b = new Binding("Source");
b.Source = ItemsManager.Instance.GetItem("123").BitmapSource;
b.BindsDirectlyToSource = true;
Image img = new Image();
img.SetBinding(Image.SourceProperty, b);
img.Width = (double)100.0;
img.Height = (double)100.0;
LayoutRoot.Children.Add(img);
}
Once image is loaded, image doesn't appear. Though, if I set directly after image has been loaded its source, it displays well.
I also noticed that PropertyChanged("BitmapSource") never fires, because PropertyChanged is null, like Image never binded to it.
I am looking forward to hearing from you!
PropertyChanged("BitmapSource") fires in case of two-way binding.
I.e. if you use two way binding and then manually change image source, like
img.Source = new BitmapImage(new Uri("http://...."));
the property changed event would fire.
As for the image appearance, it seems you bind data in wrong way.
Try declarative bindings.
There are several things wrong with this code:-
You've bound directly to the BitmapImage exposed by the BitmapSource property so you've taken your nested Item class out of the picture anyway.
Also for the property setter to be called you would need something to assign a value to the Image elements Source property and your binding would need to be in two way mode.
Your binding object creation is confused, it specifies a path (which is wrong anyway) but then binds direct to source.
Hence your code would need to look like this:-
Binding b = new Binding("BitmapSource");
b.Source = ItemsManager.Instance.GetItem("123");
b.Mode = BindingMode.TwoWay;
Now when a new BitmapImage is assigned the Image Source property your setter code should run. However it should be born in mind that the this property is of the more general type ImageSource. Hence this code will break if another derivative of ImageSource is assigned instead.
One other thing which may be a problem, I can't recall of the top of my head whether Silverlight supports binding to nested types. You might need to bring your Item class out of ItemsManager and give it a more specific name like ManagedItem.
First, do not bind to BitmapImage unless you have a good reason. Binding to a string is good enough. The implicit conversion will happen automatically. Second, use declaritive binding. Programatic creation and binding is a real mess. Third, only implement INotifyPropertyChanged if you need to send changes of that property to the UI.
You are likely over complicating your situation with all this extra code.
Thanks for explanations. However, I don't need a TwoWay binding. Just one way, once ItemsManager downloads Item image, it should be automatically updated in the Image control.
So, I changed my code to this:
ItemsManager.Instance.AddItem("123");
Binding b = new Binding("BitmapSource");
b.Source = ItemsManager.Instance.GetItem("123");
Image img = new Image();
img.SetBinding(Image.SourceProperty, b);
img.Width = (double)100.0;
img.Height = (double)100.0;
LayoutRoot.Children.Add(img);
I also took Item out of ItemsManager scope, so it is now in its own class file, but image still stays empty, even though bitmap image arrives, and changes in BitmapSource property of Item object.

WPF Image Dynamically changing Image source during runtime

I have a window with a title on it. When the user selects a choice from a drop down list, the title image can change. The problem is when the image loads, it's a blurred, stretched, and pixelated. These are PNG files I'm working with and they look good prior to setting the source dynamically.
Here's the code I'm using to change the image's source.
string strUri2 = String.Format(#"pack://application:,,,/MyAssembly;component/resources/main titles/{0}", CurrenSelection.TitleImage);
Stream iconStream2 = App.GetResourceStream(new Uri(strUri2)).Stream;
imgTitle.Source = HelperFunctions.returnImage(iconStream2);
Here are the helper functions.
public static BitmapImage returnImage(Stream iconStream)
{
Bitmap brush = new Bitmap(iconStream);
System.Drawing.Image img = brush.GetThumbnailImage(brush.Height, brush.Width, null, System.IntPtr.Zero);
var imgbrush = new BitmapImage();
imgbrush.BeginInit();
imgbrush.StreamSource = ConvertImageToMemoryStream(img);
imgbrush.CreateOptions = BitmapCreateOptions.PreservePixelFormat;
imgbrush.EndInit();
var ib = new ImageBrush(imgbrush);
return imgbrush;
}
public static MemoryStream ConvertImageToMemoryStream(System.Drawing.Image img)
{
var ms = new MemoryStream();
img.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
return ms;
}
And the XAML
<Image x:Name="imgTitle" HorizontalAlignment="Left" VerticalAlignment="Bottom" Grid.Column="1" Grid.Row="1" Stretch="None" d:IsLocked="False"/>
And for Ref:
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
Anyone have any ideas what's up?
I can think of two things:
First, try loading the image with:
string strUri2 = String.Format(#"pack://application:,,,/MyAseemby;component/resources/main titles/{0}", CurrenSelection.TitleImage);
imgTitle.Source = new BitmapImage(new Uri(strUri2));
Maybe the problem is with WinForm's image resizing, if the image is stretched set Stretch on the image control to "Uniform" or "UnfirofmToFill".
Second option is that maybe the image is not aligned to the pixel grid, you can read about it on my blog at http://www.nbdtech.com/blog/archive/2008/11/20/blurred-images-in-wpf.aspx
Hey, this one is kind of ugly but it's one line only:
imgTitle.Source = new BitmapImage(new Uri(#"pack://application:,,,/YourAssembly;component/your_image.png"));
Here is how it worked beautifully for me.
In the window resources add the image.
<Image x:Key="delImg" >
<Image.Source>
<BitmapImage UriSource="Images/delitem.gif"></BitmapImage>
</Image.Source>
</Image>
Then the code goes like this.
Image img = new Image()
img.Source = ((Image)this.Resources["delImg"]).Source;
"this" is referring to the Window object
Like for me -> working is:
string strUri2 = Directory.GetCurrentDirectory()+#"/Images/ok_progress.png";
image1.Source = new BitmapImage(new Uri(strUri2));
Me.imgAddNew.Source = New System.Windows.Media.Imaging.BitmapImage(New Uri("/SPMS;component/Images/Cancel__Red-64.png", UriKind.Relative))
Try Stretch="UniformToFill" on the Image

Resources