Loading BitmapImage in code - wpf

From my assembly (A) I want to call a method in another assembly (B) which passes an image. This image is then shown in a WPF Window - the window is part of B's project.
I can't seem to pass an ImageSource with a pack:// uri as this gets evaluated in the context of B, so I guess I need to cache the image using CachedBitmap (?) when still in A.
BitmapImage img = new BitmapImage(new Uri("Images/32px-Nuvola_apps_cache.png", UriKind.Relative));
CachedBitmap cbmp = new CachedBitmap(img, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
I've managed to get this to work if I set the image to Embedded Resource and load it as a stream, but this isn't the WPF way.
It seems from the pack: documentation that I should be able to do this, but I've tried these below and none work;
"Images/32px-Nuvola_apps_cache.png": "Could not find part of the path"
"pack://application:,,,Images/32px-Nuvola_apps_cache.png": "The URI prefix is not recognized.".
"pack://siteoforigin:,,,Images/32px-Nuvola_apps_cache.png": "The URI prefix is not recognized."
All I want to do is load a Resource .png file into memory and pass it wholesale to a method in another assembly.
Thanks
Paul.

Try:
pack://application:,,,/YourAssemblyName;component/Images/32px-Nuvola_apps_cache.png

Related

Adding image F#

I have a stack panel to which I want to add some icons dynamically.
If I add a TextBlock to the stack panel, it works perfectly:
// assuming stackPanel is my stack panel
let text = new TextBlock()
text.Text <- "Test"
stackPanel.Children.add(text)
However, my goal is to add an image, but seems like it fails to resolve the image
let getImageSource(imagePath) =
let uri = new Uri(imagePath, UriKind.Relative)
new BitmapImage(uri);
let icon = new Image()
icon.Source <- getImageSource("images/fileIcon/icon.gif")
stackPanel.Children.Add(icon) // this doesnt work
now when I do:
let icon = new Image()
icon.Source <- getImageSource("images/fileIcon/icon.gif")
stackPanel.Children.Add(icon)
let text = new TextBlock()
text.Text <- "Test"
stackPanel.Children.add(text)
I can see there's an empty space between the texts, as if there is an empty image there.
So my guess is there's something wrong with the way I resolve the image path - but I am not sure why.
Thoughts?
Thanks!
In case your gif's Build Action is Resource, then the proper way to address it is /SilverlightApplication1;component/path/to/file.gif. Here SilverlightApplication1 is the name of your silverlight application
In case it's Build Action is Content, then it's proper address is /path/to/file.gif, always with a leading slash when creating a BitmapImage.
Check out Silverlight 2: Demystifying URI references for app resources for more information.
For easier debugging of image loading problems, hook to the BitmapImage.ImageFailed event and see what kind of errors crop up.
One last note, AFAIK Silverlight doesn't support the GIF format. You might use PNG instead.
You can try with the following Uri if yours is WPF App.
let uri = Uri("pack://application:,,,/asm_name;component/images/fileIcon/icon.gif")
asm_name have to be replaced with your actual assembly name.
if your are working on Silverlight application, you need to modify the uri like this. Assuming that the build action of icon.gif is Resource.
let uri = Uri("../images/fileIcon/icon.gif", UriKind.Relative)
Hope this helps.

How to create Uri pointing to an local image in Silverlight?

I was wondering if it is allowed to read local images within a Silverlight client. (it is just to test a control)
var image = new BitmapImage { UriSource = new Uri("../Images/2.jpg", UriKind.Relative) };
Would this Uri be allowed and the image created? For some reason the picture doesn't show, despite getting no compiler errors that the Uri might have been wrong...
Thanks for advice,
kave
Assuming your project looks like this
- Project
- Images
- 2.jpg
- Another_Folder
- *your code file*
, that should be fine.
Remember that
../Images/2.jpg
is navigating to parent folder, then looking for an Images folder and a 2.jpg file.

WPF control hosted in Windows Forms: Is it possible to access resource files?

I have a WPF control hosted in Windows Forms and I would like to access it's resources, specifically images. What is the best way to do that?
I was thinking of using a ResourceDictionary, but I'm not sure how I can access it from within a Windows Form.
This is a standalone WPF control, in a DLL? There are two ways that the resources can be embedded... as part of a .resources file (e.g. the Project's "Resoruces" tab), or as files included as "Embedded Resources"...
To get the assembly reference to the DLL this is usually the easiest:
var ass = typeof(ClassInOtherDll).Assembly;
In the Resources
If this is part of the default project resources, and not a different .resources file included inside the DLL, you can use the default base-name.
var ass = typeof(ClassInTargetDLL).Assembly;
var rm = new ResourceManager("...BaseName...", ass);
BaseName for default project resources is :
C# := Namespace.Properties.Resources
VB := Namespace.Resources
After that you can just call GetObject() and do a cast back:
var myImage = rm.GetObject("check_16");
return myImage as Bitmap;
If you want to find out whats in there, get the assembly reference and call
ass.GetManifestResourceNames()
.resources files can be used with a ResourceManager
embedded resources will just show up as a list. Use the other method for these.
And this is all assuming they default culture =)
As Embedded Resources
You can use the regular methods on the assembly to get an embedded resource. You find it by name, and then Basically you will need to convert the stream back into your desired type.
GetManifestResourceNames()
GetManifestResourceStream(name)
help getting the desired file with a helper function to find files by name.
I usually use these like this:
// called GetMp3 in the post, but it returns a stream. is the same thing
var stream = GetResourceStream("navigation.xml");
var reader = New XmlTextReader(stream);
return reader;
To get an image that is an embedded resource, this works for me:
var stream = GetResoureStram("check_32.png");
var bmp = new Bitmap(stream);
this.MyButton.Image = bmp;

Silverlight image: load URL dynamically?

I'm tinkering with Silverlight 2.0.
I have some images, which I currently have a static URL for the image source.
Is there a way to dynamically load the image from a URL path for the site that is hosting the control?
Alternatively, a configuration setting, stored in a single place, that holds the base path for the URL, so that each image only holds the filename?
From what I gather you aren't trying to change the image itself dynamically, but rather to correctly determine the location of the image at runtime.
I believe simply prefixing the image relative URL with "../" should get you to the root of your application, not necessarily the site as the application might not be hosted in the root of a site.
If your XAP file is located as follows:
http://somesite.foo/app1/somethingelse/clientbin/MyFoo.xap
And you where trying to link the following image:
http://somesite.foo/app1/somethingelse/images/a/boo.png
Apparently all relative URI's are relative to where the XAP file is located (ClientBin folder typically) and Silverlight appends the current Silverlight client namespace. So if you Silverlight control is in the namespace Whoppa you would need to put all your images in the clientbin/Whoppa/ directory. Not exactly convenient.
The workaround is to use absolute URIs as follows:
new Uri(App.Current.Host.Source, "../images/a/boo.png");
In the code behind or a value converter you can do
Uri uri = new Uri("http://testsvr.com/hello.jpg");
YourImage.Source = new BitmapImage(uri);
// create a new image
Image image = new Image();
// better to keep this in a global config singleton
string hostName = Application.Current.Host.Source.Host;
if (Application.Current.Host.Source.Port != 80)
hostName += ":" + Application.Current.Host.Source.Port;
// set the image source
image.Source = new BitmapImage(new Uri("http://" + hostName + "/cute_kitten112.jpg", UriKind.Absolute));
http://www.silverlightexamples.net/post/How-to-Get-Files-From-Resources-in-Silverlight-20.aspx
using System.Windows.Resources; // StreamResourceInfo
using System.Windows.Media.Imaging; // BitmapImage
....
StreamResourceInfo sr = Application.GetResourceStream(new Uri("SilverlightApplication1;component/MyImage.png", UriKind.Relative));
BitmapImage bmp = new BitmapImage();
bmp.SetSource(sr.Stream);
SilverlightHost.Source will provide you the URL that was used to load the XAP file. You can use this to then construct a relative URL for your images.
So if for example your XAP is hosted on http://foo.bar/ClientBin/bas.xap and your images were stored in http://foo.bar/Images/ you can simply use the Source to grab the host name and protocol to construct the new URI.
img.Source = new BitmapImage(image uri) must work.
img.Source = new BitmapImage(new Uri("/images/my-image.jpg", UriKind.Relative)); will properly resolve to the root of the Silverlight application where as "../images/my-image.jpg" will not.
This is only true in the code-behind when dynamically setting the source of the image. You cannot use this notation (the "/" to designate the root) in the XAML (go fiquire, hope they fix that)
The below code worked for me only when the image is included in the project as a resource file:
img.Source = new BitmapImage(new Uri("/images/my-image.jpg", UriKind.Relative));
I am unable to access URL from absolute URLs. Not even Flickr's farm URL for images.

WPF - Load Font from Stream?

I have a MemoryStream with the contents of a Font File (.ttf) and I would like to be able to create a FontFamily WPF object from that stream WITHOUT writing the contents of the stream to disk. I know this is possible with a System.Drawing.FontFamily but I cannot find out how to do it with System.Windows.Media.FontFamily.
Note: I will only have the stream, so I can't pack it as a resource in the application and because of disk permissions issues, will not be able to write the font file to disk for reference as "content"
UPDATE:
The API docs how describe how an application resource can be used, though it is not clear to me whether that is an Embedded resource in the assembly or a file on disk.
You can use a base URI value when you reference a font that is packaged as part of the application. For example, the base URI value can be a "pack://application" URI, which lets you reference fonts that are packaged as application resources. The following code example shows a font reference that is composed of a base URI value and a relative URI value.
There is a similar question here, which contains a supposed solution by converting a System.Drawing.FontFamily to a WPF font family, all in memory without any file IO:
public static void Load(MemoryStream stream)
{
byte[] streamData = new byte[stream.Length];
stream.Read(streamData, 0, streamData.Length);
IntPtr data = Marshal.AllocCoTaskMem(streamData.Length); // Very important.
Marshal.Copy(streamData, 0, data, streamData.Length);
PrivateFontCollection pfc = new PrivateFontCollection();
pfc.AddMemoryFont(data, streamData.Length);
MemoryFonts.Add(pfc); // Your own collection of fonts here.
Marshal.FreeCoTaskMem(data); // Very important.
}
public static System.Windows.Media.FontFamily LoadFont(int fontId)
{
if (!Exists(fontId))
{
return null;
}
/*
NOTE:
This is basically how you convert a System.Drawing.FontFamily to System.Windows.Media.FontFamily, using PrivateFontCollection.
*/
return new System.Windows.Media.FontFamily(MemoryFonts[fontId].Families[0].Name);
}
This seems to use the System.Drawing.PrivateFontCollection(^) to add a System.Drawing.Font created from a MemoryStream and then use the Families[0].Name of that font to pass into the System.Windows.Media.FontFamily constructor. I assume the family name would then be a URI to the instance of that font in the PrivateFontCollection but you'd probably have to try it out.
The best approach I could think of, was to save the oldFont to a temp directory, and immediately load it using the newFont constructor that accepts a uri.

Resources