Load image from another assembly's resx file in XAML - wpf

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;

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.

How to update image file binding to Image control?

My app includes a Image control which has binding to a disk image file. I some condition, the image file need be updated. But the updating can't be done because the image file is open and can not be overwritten. What should I do?
You can try to remove the binding, so the image will not be used by your program
than overwrite the image file
and than re-add the binding
i'm not sure about this, but it's worth a try
Now my solution is:
To use a converter to convert the image path into BitmapImage.
in the converter, load the image using a FileStream and copy the data into a MemoryStream and finally close the FileStream.
BitmapImage bmp = new BitmapImage();
bmp.CacheOption = BitmapCacheOption.OnLoad;
bmp.BeginInit();
var fileStream = new FileStream(path, FileMode.Open, FileAccess.Read);
var memStream = new MemoryStream();
memStream.SetLength(fileStream.Length);
fileStream.Read(memStream.GetBuffer(), 0, (int)fileStream.Length);
memStream.Flush();
fileStream.Close();
bmp.StreamSource = memStream;
bmp.EndInit();
return bmp;

Binding Bitmapimge to Image in Wpf?

This is a simple Question (lets see)
I want to bind bitmap image to Image. For doing this in cs code u must write this line.
this.leftImage.Source = new BitmapImage(new Uri(#"C:\a.bmp"));
But I want make Binding from resources. Because In release time resources became part of project.exe file and if you make binding from file(Mean set Image.source with Image file address), you must always put image file in the same address(disaster programing) :)
One option is to get it from a resx file. You can do something similar to this. Assuming Images.resx contains a Left image bitmap.
leftImage.Source = ConvertBitmapToBitmapImage(Images.Left);
...
private BitmapImage ConvertBitmapToBitmapImage(Bitmap bitmap)
{
MemoryStream memoryStream = new MemoryStream();
bitmap.Save(memoryStream, ImageFormat.Png);
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.StreamSource = new MemoryStream(memoryStream.ToArray());
bitmapImage.EndInit();
return bitmapImage;
}
With some more work, you can do this from XAML too.

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