Relative Uri works for BitmapImage, but not for MediaPlayer? - wpf

This will be simple for you guys:
var uri = new Uri("pack://application:,,,/LiftExperiment;component/pics/outside/elevator.jpg");
imageBitmap = new BitmapImage();
imageBitmap.BeginInit();
imageBitmap.UriSource = uri;
imageBitmap.EndInit();
image.Source = imageBitmap;
=> Works perfectly on a .jpg with
Build Action: Content
Copy to Output Directory: Copy always
MediaPlayer mp = new MediaPlayer();
var uri = new Uri("pack://application:,,,/LiftExperiment;component/sounds/DialingTone.wav");
mp.Open(uri);
mp.Play();
=> Does not work on a .wav with the same build action and copy to output. I see the file in my /debug/ folder..
MediaPlayer mp = new MediaPlayer();
var uri = new Uri(#"E:\projects\LiftExp\_solution\LiftExperiment\bin\Debug\sounds\DialingTone.wav");
mp.Open(uri);
mp.Play();
=> Works perfectly..
So, how do I get the sound to work with a relative path? Why is it not working this way?
Let me know if you want more code or screenshots.
Thanks.

The pack://application URI syntax is for "embed" files, make sure the the media file is set to that, or use the pack://siteoforigin for "loose" files (copied to bin directory).
MSDN link

Related

Accessing the images folder in wpf app

I have a wpf application in which I want to save a file in the Images folder, which is on the same level with the bin folder.
How do I access that folder?
I try like this:
using (var imageFile = new FileStream((new Uri(#"pack://application:,,,/Images/Application/")).ToString(), FileMode.Create))
{
//
}
and I get the error that "The given path's format is not supported.". How can I access that folder?
Your path refers to resources within the project assembly. You should use relative or absolute file system paths:
var path = Path.Combine(
Path.DirectorySeparatorChar.ToString(),
AppDomain.CurrentDomain.BaseDirectory,
"Images"); // Result could be for example: "C:\MyWorkspace\MyProject\bin\Debug\Images"
using (var imageFile = new FileStream(path, FileMode.Create)) { }
How about using double dots(..) to get to parent directory.
using (var imageFile = new FileStream("..\..\[Path goes here]", FileMode.Create))
{
//
}

WPF: How to save a GIF file in a string or file from an URL?

I try to retrieve the content of a .gif located on an URL into a string -and eventually save it to disk-, ran from a WPF appliactions using the webbrowser. After trying dozens of solutions I am not further than I was yesterday. I thought that the code below would do the job, but the saved string cGif contains...the url itself. From http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.gifbitmapdecoder.aspx I then thought I needed GifBitmapEncoder instead, but the sample suggests that this creates an empty gif instead of a downloaded one.
(PS: what I basically want to do is to retrieve the GIF bytes straight from the WPF webbrowser but I haven't found anything working there either)
private void GifSave()
{
var uri = new Uri(#"http://www.archivearts.com/GIRAFFE2.gif");
var Img = new GifBitmapDecoder(uri, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);
string cGif = Img.ToString();
}
Modified from a sample on the GifBitmapDecoder MSDN page:
// Open a Stream and decode a GIF image
var uri = new Uri(#"http://www.archivearts.com/GIRAFFE2.gif");
GifBitmapDecoder decoder = new GifBitmapDecoder(uri, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);
BitmapSource bitmapSource = decoder.Frames[0];
Then use the CopyPixels() method of the BitmapSource to copy the pixel data into an array. Then convert the array into a string?
I haven't done this, I just took a look at MSDN to get some hints.

Loading xap file on demand

I have Silverlight application called MyApp. During startup MyApp loads MyApp.Main.xap module using the following code:
WebClient wc = new WebClient();
wc.OpenReadCompleted += new OpenReadCompletedEventHandler(onMainModuleLoaded);
Uri uri = new Uri("MyApp.Main.xap", UriKind.Relative);
wc.OpenReadAsync(uri);
It works. Within MyApp.Main I would like to load another xap file MyApp.Billing.xap, so I wrote like the same as above
WebClient wc = new WebClient();
wc.OpenReadCompleted += new OpenReadCompletedEventHandler(onBillingModuleLoaded);
Uri uri = new Uri("MyApp.Billing.xap", UriKind.Relative);
wc.OpenReadAsync(uri);
but it throws an error saying the file not found. MyApp.Billing.xap file is inside ClientBin folder and I can download it directly via absolute path in a browser. If I try to download MyApp.Billing.xap not from inside MyApp.Main, but from inside MyApp (instead of MyAPp.Main.xap) it also works fine. What might be the problem?
See if you have more success by using the various properties at Application.Current.Host.Source to put together a complete (absolute) uri, instead of trying to use a relative one (after all, what is it relative to?).

Load image not in xap Silverlight

i'm developing an application and i would load an image that isn't in the clientbin folder, but in a folder placed in my server. I would do something like this
BitmapImage bit = new BitmapImage();
string path = "c:/image.png";
bit.UriSource = new Uri(path, UriKind.Absolute);
identity.Source = bit;
but it doesn't function.Any idea?
Thanks
Try:
Image.Source = New Imaging.BitmapImage(New Uri("http://www.Pic.jpg", UriKind.Absolute))
You do not want to include it in your project or the .xap will get huge.
Silverlight applications run on the client, not on the server, so referencing the path as you had been trying to do, would really point to the path on client machine running the application. However, Silverlight does not have rights to read or write from or to the client's disk anyway, due to sercurity reasons. The Isolated Storage functionality is the exception to that.
Therefore, your option is to try the first answer given by Bill, or a WebService, which is more complex to implement.
ib.
To add to Bill's answer. You can also use server side resources using the following helper method which is derived from the location of the xap file.
public static string GetUrlForResource(string resourcePage)
{
var webUrl = Application.Current.Host.Source.ToString();
//Get ClientBin Directory
var stub = webUrl.Substring(0, webUrl.LastIndexOf("/"));
//Get application root.
stub = stub.Substring(0, stub.LastIndexOf("/") + 1);
//Append the application root to the resource page.
webUrl = stub + resourcePage;
return webUrl;
}
To use it like Bill's answer, use the following:
Image.Source = new Imaging.BitmapImage(new Uri(GetUrlForResource("images/myimage.png"), UriKind.Absolute));

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.

Resources