I am working on a Windows 8 app. I need to know how to programmatically set the Source of an Image. I assumed that the Silverlight approach would work. However, it doesn't. Does anybody know how to do this? The following will not work:
string pictureUrl = GetImageUrl();
Image image = new Image();
image.Source = new Windows.UI.Xaml.Media.Imaging.BitmapImage(new Uri(pictureUrl, UriKind.Relative));
image.Stretch = Stretch.None;
image.HorizontalAlignment = Windows.UI.Xaml.HorizontalAlignment.Left;
image.VerticalAlignment = Windows.UI.Xaml.VerticalAlignment.Center;
I get an Exception that says: "The given System.Uri cannot be converted into a Windows.Foundation.Uri."
However, I can't seem to find the Windows.Foundation.Uri type.
I just tried
Image.Source = new BitmapImage(
new Uri("http://yourdomain.com/image.jpg", UriKind.Absolute));
And it works without problems... I'm using System.Uri here. Maybe you have a malformed URI or you have to use an absolute URI and use UriKind.Absolute instead?
This is what I use:
string url = "ms-appx:///Assets/placeHolder.png";
image.Source = RandomAccessStreamReference.CreateFromUri(new Uri(url));
Well, Windows.Foundation.Uri is documented like this:
.NET: This type appears as System.Uri.
So the tricky bit isn't converting it into a Windows.Foundation.Uri yourself - it looks like WinRT does that for you. It looks like the problem is with the URI you're using. What is it relative to in this case? I suspect you really just need to find the right format for the URI.
This example uses a FileOpenPicker object to obtain the storage file.
You can use whatever method you need to access your file as a StorageFile object.
Logo is the name of the image control.
Reference the following code:
var fileOpenPicker = new FileOpenPicker();
fileOpenPicker.ViewMode = PickerViewMode.Thumbnail;
fileOpenPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
fileOpenPicker.FileTypeFilter.Add(".png");
fileOpenPicker.FileTypeFilter.Add(".jpg");
fileOpenPicker.FileTypeFilter.Add(".jpeg");
fileOpenPicker.FileTypeFilter.Add(".bmp");
var storageFile = await fileOpenPicker.PickSingleFileAsync();
if (storageFile != null)
{
// Ensure the stream is disposed once the image is loaded
using (IRandomAccessStream fileStream = await storageFile.OpenAsync(Windows.Storage.FileAccessMode.Read))
{
// Set the image source to the selected bitmap
BitmapImage bitmapImage = new BitmapImage();
await bitmapImage.SetSourceAsync(fileStream);
Logo.Source = bitmapImage;
}
}
check your pictureUrl since it was what resulted in the exception.
but this should work as well
img.Source = new BitmapImage(new Uri(pictureUrl, UriKind.Absolute));
it should have nothing to do with Windows.Foundation.Uri. since winrt will handle it for you.
Try this format:
ms-appx:/Images/800x600/BackgroundTile.bmp
The given System.Uri cannot be converted into a Windows.Foundation.Uri
<Image Name="Img" Stretch="UniformToFill" />
var file = await KnownFolders.PicturesLibrary.GetFileAsync("2.jpg");
using(var fileStream = (await file.OpenAsync(Windows.Storage.FileAccessMode.Read))){
var bitImg= new BitmapImage();
bitImg.SetSource(fileStream);
Img.Source = bitImg;
}
Related
I am trying to display an image from a StorageFile after selecting it from a FilePicker. Since the Source of an Image has to be either a URI or an ImageSource, I am trying to get either of those from the StorageFile.
I am having a hard time getting data binding to work on an Image in XAML. I have tried the following:
<Image Width="300"
Height="300"
x:Name="LogoImage">
<Image.Source>
<BitmapImage UriSource="{Binding ImagePath}" />
</Image.Source>
</Image>
This way doesn't work, as the Path property of a StorageFile is not a URI. Also, I can't bind directly to the StorageFile itself, as it is not an ImageSource.
I tried to use this method:
public async Task<Image> GetImageAsync(StorageFile storageFile)
{
BitmapImage bitmapImage = new BitmapImage();
FileRandomAccessStream stream = (FileRandomAccessStream)await storageFile.OpenAsync(FileAccessMode.Read);
bitmapImage.SetSource(stream);
Image image = new Image();
image.Source = bitmapImage;
return image;
}
But, it returns a Task<Image>, which is also not an ImageSource or URI. It seems like it should be something more straightforward than what I am trying to do, but I am just not seeing it. Also, I have tried just specifying a file in the XAML for the Image.Source and it works fine. I just haven't been able to link it up based on the selected file from the FilePicker.
My ultimate goal is: select a file from FilePicker, update the ImageSource of the displayed Image, encode to base64 for storage in database. Then later, load existing base64 string from database, convert back to Image to be displayed.
Edit:
I was able to accomplish this task using the solution I posted below. Thanks in great part to Jerry Nixon's blog post: http://blog.jerrynixon.com/2014/11/reading-and-writing-base64-in-windows.html
The best solution would be to set the source in code behind instead of using a binding as it would let you handle things like cancellation in case the ImagePath gets updated while the previous image is still loading.
Alternatively, you could create a bitmap, start a task of loading it and return before that task is complete, e.g.
public Image GetImage(StorageFile storageFile)
{
var bitmapImage = new BitmapImage();
GetImageAsync(bitmapImage, storageFile);
// Create an image or return a bitmap that's started loading
var image = new Image();
image.Source = bitmapImage;
return image ;
}
private async Task GetImageAsync(BitmapImage bitmapImage, StorageFile storageFile)
{
using (var stream = (FileRandomAccessStream)await storageFile.OpenAsync(FileAccessMode.Read))
{
await bitmapImage.SetSource(stream);
}
}
If anyone else comes across this question looking for an answer, what I ultimately ended up doing for my situation, is take the StorageFile that is selected from the FilePicker, encode that as a base64 string (which I will save to my database for later retrieval).
Once I have the base64 string, I can decode that string into an ImageSource to set in code-behind. Here is my full ButtonClick event handler:
private async void ChooseImage_Click(object sender, RoutedEventArgs e)
{
var filePicker = new FileOpenPicker();
filePicker.FileTypeFilter.Add(".jpg");
filePicker.ViewMode = PickerViewMode.Thumbnail;
filePicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
filePicker.SettingsIdentifier = "picker1";
filePicker.CommitButtonText = "Open File to Process";
var files = await filePicker.PickMultipleFilesAsync();
if (files.Count > 0)
{
// encode the storage file to base64
var base64 = await Encoding.ToBase64(files[0]);
// asynchronously save base64 string to database
// ...
// decode the base64 and set the image source
LogoImage.Source = await Encoding.FromBase64(base64);
}
}
The base64 encoding/decoding I found at the great Jerry Nixon's blog here: http://blog.jerrynixon.com/2014/11/reading-and-writing-base64-in-windows.html
I'm trying to get all images from a directory in WP7. I already use
var temp = Directory.GetFiles(#"\Pictures");
but it doesn't seem to work.
by the way i also tried the isolated storage solution. but none of those solution seems to work.
Is i a wp7 limitation?
you shoud use following code for images from the resources:
Uri uri = new Uri(uriString, UriKind.Relative);
String originalUriString = uri.OriginalString;
Uri resourceStreamUri = originalUriString.StartsWith("/", StringComparison.Ordinal) ? new Uri(originalUriString.TrimStart('/'), UriKind.Relative) : uri;
StreamResourceInfo streamResourceInfo = Application.GetResourceStream(resourceStreamUri);
if (null != streamResourceInfo)
{
stream = streamResourceInfo.Stream;
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.SetSource(stream);
Image image = new Image();
image.Source = bitmapImage;
}
Probably, you should use IsolatedStorageFile.GetFileNames instead.
Good tutorial: How to: Find Existing Files and Directories in Isolated Storage
You probalby have your pictures as Resource and not as Content. Right click on images in your solution and change the Build Action to Content.
I get image URL at runtime from the xml file reader. This image URL is pass to the below method to download it dynamically.
public void Display_Image(string MyURL)
{
BitmapImage bi = new BitmapImage();
bi.UriSource = new Uri(this.BaseUri, MyURL);
Img_Poster.Source = bi;
}
But this doesn't work. I don't get any image source. The above code works fine with static URL provided at compile time. What do I need to do more?
The method I suggested below is obsolete. However, creating a new Bitmap image created dynamically with a Uri determined at runtime IS supported and working on the RTM build of Windows 8. Display_Image(url) should work as you expect.
You can get the image stream using the CreateFromUri helper: http://msdn.microsoft.com/en-us/library/windows/apps/windows.storage.streams.streamreference.createfromuri.aspx#Y0
var stream = RandomAccessStreamReference.CreateFromUri(new Uri(imageUrl))
You should then be able to set the source of your bitmap to the RandomAccessStream that the helper returns
I've had similar problems with previously-working Bitmap code not working on Windows RT, an early attempt convinces me that it refuses to download anything unless it is going to be displayed on the UI (here, I needed to insert a 1ms delay before assigning sources just to get it to trigger the image download):
var image = .... // reference to animage on the UI
var placeholder = ... // a placeholder BitmapImage
var source = ... // uri to download
image.Source = placeholder;
var src = new BitmapImage(new Uri(source));
src.ImageOpened += (s, e) =>
{
var bi = s as BitmapImage;
image.Source = bi;
};
image.Source = src;
// Delay required to trigger download
await Task.Delay(1);
image.Source = placeholder;
Here's another solution I've tried with success:
var image = .... // reference to animage on the UI
var source = ... // uri to download
var placeholder = ... // a placeholder BitmapImage
image.Source = placeholder;
var bytes = await new HttpClient().GetByteArrayAsync(source);
var img = new BitmapImage();
await img.SetSourceAsync(bytes.AsBuffer().AsStream().AsRandomAccessStream());
image.Source = img;
Here is the problem.
I want to open a file from local drives, then make it into a WritableBitmap so i can edit it.
But the problem is, i cannot create a WritableBitmap from Uri or something like that. Also i know how to open a file into BitmapImage but i cannot figure out how to open a file as WritableBitmap.
Is there way to open a file directly into a WritableBitmap,if there is not, is there a way to convert a BitmapImage to a WritableBitmap?
Thanks guys.
You can load your image file into a BitmapImage and use that as a source for your WriteableBitmap:
BitmapImage bitmap = new BitmapImage(new Uri("YourImage.jpg", UriKind.Relative));
WriteableBitmap writeableBitmap = new WriteableBitmap(bitmap);
I'm no expert and don't have immediate access to intellisense and whatnot, but here goes...
var fileBytes = File.ReadAllBytes(fileName);
var stream = new MemoryStream(fileBytes);
var bitmap = new BitmapImage(stream);
var writeableBitmap = new WritableBitmap(bitmap);
Even if not a perfect example this should be enough to point you in the right direction. Hope so.
In Silverlight 5 you can use below method to open file from local disk and convert it to BitmapImage and make it in to WriteableBitmap;
OpenFileDialog dlg = new OpenFileDialog();
dlg.Multiselect = false;
dlg.ShowDialog();
byte[] byteArray = new byte[] { };
if (dlg.File == null) return;
BitmapImage bi = new BitmapImage();
bi.CreateOptions = BitmapCreateOptions.None;
// bi.UriSource = new Uri(#"C:\Users\saw\Desktop\image.jpg", UriKind.RelativeOrAbsolute);
bi.SetSource(dlg.File.OpenRead());
WriteableBitmap eb=new WriteableBitmap(bi);
setting new Uri gave me error (Object reference not set to an instance of an object) while trying to create WriteableBitmap
I need to set image source dynamically, please note my image is in somewhere on the Network, here is my code
BitmapImage logo = new BitmapImage();
logo.BeginInit();
logo.UriSource = new Uri(#"pack://application:,,,\\myserver\\folder1\\Customer Data\\sample.png");
logo.EndInit(); // Getting the exception here
ImageViewer1.Source = logo;
Exception:
The URI prefix is not recognized
None of the above solutions worked for me. But this did:
myImage.Source = new BitmapImage(new Uri(#"/Images/foo.png", UriKind.Relative));
You just need one line:
ImageViewer1.Source = new BitmapImage(new Uri(#"\myserver\folder1\Customer Data\sample.png"));
The pack syntax you are using here is for an image that is contained as a Resource within your application, not for a loose file in the file system.
You simply want to pass the actual path to the UriSource:
logo.UriSource = new Uri(#"\\myserver\folder1\Customer Data\sample.png");
None of the methods worked for me as i needed to pull the image from a folder instead of adding it to the application.
The below code worked:
TestImage.Source = GetImage("/Content/Images/test.png")
private static BitmapImage GetImage(string imageUri)
{
var bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.UriSource = new Uri("pack://siteoforigin:,,,/" + imageUri, UriKind.RelativeOrAbsolute);
bitmapImage.EndInit();
return bitmapImage;
}
You are all wrong!
Why? Because all you need is this code to work:
(image View) / C# Img is : your Image box
Keep this as is, without change ("ms-appx:///) this is code not your app name
Images is your folder in your project you can change it.
dog.png is your file in your folder, as well as i do my folder 'Images' and file 'dog.png'
So the uri is :"ms-appx:///Images/dog.png"
and my code :
private void Button_Click(object sender, RoutedEventArgs e)
{
img.Source = new BitmapImage(new Uri("ms-appx:///Images/dog.png"));
}