accessing pictures in my exe of wpf app from codebehind - wpf

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.

Related

how to get BitmapImage in codebehind from the image tag in xaml in wpf/silverlight

i dont have a problem with binding a bitmapimage to image tag in codebehind for eg.
BitmapImage image = new BitmapImage();
imagetaginxaml.Source = image; // this will remove whatever image is currently on the image tag in xaml and attach the empty bitmapimage above
but i'm not able to get the image by doing the reverse, for example, i want to process the image that is currently on the image tag. i am not able to do this
BitmapImage image = imagetaginxaml.Source;
what should i do
Well, Image.Source is of type ImageSource, there is no quarantee that it will be a BitmapImage, it may be though. If the source is created by the XAML parser it will be a BitmapFrameDecode (which is an internal class). Anyway, the only save assignment is:
ImageSource source = img.Source;
otherwise you need to cast:
BitmapImage source = (BitmapImage)img.Source;
which will throw an exception if the Source is not of this type. So you can either save-cast or try-catch:
//(Possibly check for img.Source != null first)
BitmapImage source = img.Source as BitmapImage;
if (source != null)
{
//If img.Source is not null the cast worked.
}
try
{
BitmapImage source = (BitmapImage)img.Source;
//If this line is reached it worked.
}
catch (Exception)
{
//Cast failed
}
You could also check the type beforehand using img.SourceisBitmapImage.
How about using WriteableBitmap to make a copy of the image, and then using a MemoryStream to copy the original image into a copy?
// Create a WriteableBitmap from the Image control
WriteableBitmap bmp = new WriteableBitmap(imagetaginxaml, null);
// Load the contents of a MemoryStream from the WritableBitmap
MemoryStream m = new MemoryStream();
bmp.SaveJpeg(m, bmp.PixelWidth, bmp.PixelHeight, 0, 100);
// Read from the stream into a new BitmapImage object
m.Position = 0;
BitmapImage image = new BitmapImage();
image.SetSource(m);
// do something with the new BitmapImage object
// (for example, load another image control)
anotherimagetaginxaml.Source = image;

How to bind Image source?

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.

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.

How to set uri for local image in silverlight app?

In SL class library MyLib, I have a image say my.png. Then I want to use it in code behind I tried following way:
StreamResourceInfo resourceStream = Application.GetResourceStream(new Uri("/MyLib;component/my.png", UriKind.Relative));
BitmapImage image = new BitmapImage();
image.SetSource(resourceStream.Stream);
this.MyIcon.Source = image;
But it's not woking. I think it's the Uri not set correctly. Help please.
This works:-
BitmapImage image = new BitmapImage(new Uri("/MyLib;component/my.png", UriKind.Relative));
MyIcon.Source = image;
I can't see why you would want to use a Stream here. Having said that your Stream code should work. The build action on the png should be "Resource" and "MyLib" in your Uri should be the Assembly name of the library as found on the "Silverlight" tab of the project properties.
Do you have your image marked as "Resource" in the properties window, or "Content"?
You could always set a style as a resource in your application and then call it like:
Application.Current.Resources["myCoolStyle"] and apply that to the image.

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