Binding image in Isolated Storage - c#

Hey.
I have a list of items that the user can search. The search results are displayed in a listbox. Each animal object has a path to an image in Isolated Storage. What's the quickest way to bind my Image control inside the listboxitem to the image in the isolated storage? Examples I've seen tend to display images from the internet rather than Isolated Storage. If I have around 10 images, it seems to take up all the memory and crash. thanks
EDIT:
I'm using this in my BitmapConverter class (inherits IValueConverter)
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value !=null)
{
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.SetSource(new MemoryStream((Byte[]) value));
return bitmapImage;
}
else
{
return null;
}
}
I have this at the top of my AppResource.xaml file:
<ImageApp_Converter:BitmapConverter x:Key="bmpConverter" />
In my style, within the AppResource.xaml file:
<Image HorizontalAlignment="Left" Margin="8,8,0,4" Width="160" Height="120" Source="{Binding Converter={StaticResource bmpConverter}}" />
I set a breakpoint in my BitmapConverter, but it's never called. I've never used IValueConverter before, so any help would be great. Thanks

There are a few problems in the code shown. Some may just be missing from your example:
Firstly, your binding to the converter does not specify what to bind to to get its value, so it is never called. At a minimum it needs a Path= (or simply a property name as short-cut) or the converter will not be called. Where are you setting the ItemSource of your list?
Secondly, the values getting passed are string file names. Your converter needs to use them as filenames and open a stream based on that name. At the moment it is trying to use the names as byte arrays.
Finally, if the images are a fixed set, it would make more sense to store them in an images folder under ClientBin and simply refer to them with the following path syntax "/images/imagename.jpg" etc. This will involve the browser's caching automatically. You do not need a converter for that. (The key is the leading "/". Without that Silverlight assumes the images are in the current module instead)
Below is a complete example using the images shown in the ClientBin/images folder that looks like this when run:
Sample Xaml file:
<UserControl x:Class="SilverlightApplication1.IsoImages"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:ImageApp_Converter="clr-namespace:SilverlightApplication1" mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot" Background="White">
<ListBox x:Name="ImageList">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Background="AliceBlue">
<Image HorizontalAlignment="Left" Margin="8,8,0,4" Width="160" Height="120" Source="{Binding Path=Filename}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</UserControl>
The sample code behind is:
using System.Collections.Generic;
using System.Windows.Controls;
namespace SilverlightApplication1
{
public partial class IsoImages : UserControl
{
public IsoImages()
{
InitializeComponent();
List<ImageItem> images = new List<ImageItem>()
{
new ImageItem("/images/Image1.jpg"),
new ImageItem("/images/Image2.jpg"),
new ImageItem("/images/Image3.jpg"),
new ImageItem("/images/Image4.jpg")
};
this.ImageList.ItemsSource = images;
}
}
public class ImageItem
{
public string Filename{ get; set; }
public ImageItem( string filename )
{
Filename = filename;
}
}
}

You are probably running out of memory because you are repeatedly loading the same file into new BitmapSource objects. You should create only "around 10" BitmapSource objects one for each file. Then re-use those BitmapSource instances by assigning them to Image.Source properties.
One way to do that is to use an implementation of IValueConverter that maintains a static dictionary of file path to BitmapSource key value pairs.

Related

Why is an image resource in a class library not loaded?

I have strange problem, which I don't know how to find - I looked for similair posts here, but failed.
Problem is that I have custom control in WPF and, obviously, I want to reuse it in multiple projects.
I have image background in that control with label over it (assured with Panel.ZIndex).
In one project it is showing correctly, but in another just Label is showing, image for some reason does no display.
What could problem be? I am loosing my mind over this...
Below code of a control:
<UserControl x:Class="SampleControls.LabelWithBoxBackground"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:SampleControls"
mc:Ignorable="d"
d:DesignHeight="150" d:DesignWidth="400" x:Name="labelWithBoxBackground">
<Grid>
<Image Source="pack://application:,,,/Images/boxImage.png" Stretch="Fill" Panel.ZIndex="1"/>
<TextBlock Background="White" Text="{Binding ElementName=labelWithBoxBackground, Path=Text}" Margin="0,20,0,0" Panel.ZIndex="2" HorizontalAlignment="Center" VerticalAlignment="Center" FontWeight="Bold" FontFamily="Calibri"/>
</Grid>
</UserControl>
Code behind:
public partial class LabelWithBoxBackground : UserControl
{
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(string), typeof(LabelWithBoxBackground), new FrameworkPropertyMetadata(string.Empty));
public string Text
{
get { return GetValue(TextProperty).ToString(); }
set { SetValue(TextProperty, value); }
}
public LabelWithBoxBackground()
{
InitializeComponent();
}
}
Use a full Resource File Pack URI, including the assembly name (not the namespace) of your UserControl library, as shown below.
Otherwise WPF resolves the Pack URI with the name of the "local" assembly, which may be that of the main application.
Source="pack://application:,,,/SampleControls;component/Images/boxImage.png"
Also make sure that the Build Action of the image file is set to Resource.
As a note, setting Panel.ZIndex is pointless here. The elements are stacked by default in the order they are declared in XAML, so the TextBlock is always on top of the Image, even without setting ZIndex.

Image.FromFile not loading into design time view c#.net

I am currently trying to get an image to show in design time in my Xaml with the code below:
Xaml:
<Canvas Grid.ColumnSpan="2" Margin="0,0,0,0">
<Image Canvas.ZIndex="1" Source="{Binding Coupon.OverlayImage}" Margin="0,-21,-76,108" Stretch="Fill" x:Name="PrintImageContextMenu" />
</Canvas>
C# Design Time:
Coupon.OverlayImage = Image.FromFile(#"C:\Temp\Images\TestImage.png");
Original Property of OverlayImage in VB (Legacy Code):
private _overlayImage as Image
Public Property OverlayImage As Image
Get
Return _overlayImage
End Get
Set
_overlayImage = value
NotifyPropertyChanged("OverlayImage")
End Set
End Property
Upon first view I cannot see anything wrong with but it does not show, even at runtime. Any ideas would be appreciated.
You can use Image Fallback value to set the default image.Here is a simple example.
<Window.Resources>
<BitmapImage x:Key="ImageSource" UriSource="C:\Temp\Images\TestImage.png"/>
</Window.Resources>
<Grid>
<Image
HorizontalAlignment="Left"
Source="{Binding SourceImage,FallbackValue={StaticResource ImageSource}}"/>
</Grid>
Everywhere you use the Image class, I think you use the System.Drawing.Image because the WPF Image control does not have a FromFile() method . You cannot use it as a source for the WPF Image Control. You must instead try using an IValueConverter to convert the Image to a BitmapSource/ImageSource.
Try this,
var uri = new Uri(Coupon.OverlayImage);
var bitmap = new BitmapImage(uri);
ImageName.Source = bitmap;

WPF Using Image Control to dynamically view Online images

Situation
I'm trying to use an image control in my program that accesses an online image by binding it to a property.
XAML:
<Image Source="{Binding TheImage}" x:Name="imgPic" HorizontalAlignment="Left" Height="113" Margin="14,89,0,0" VerticalAlignment="Top" Width="120"/>
Specifically, I'm binding to the return value of the searchMembers method (which returns an object) mempic contains a URL, and this mempic will change depending on which member is currently logged in.
View Model:
public Uri TheImage
{
get
{
return new Uri(hillracing.searchMembers(Username).mempic);
}
}
Problem
Neither this code, or a static link to the image actually works.
Here is the test image I'm actually using
wondered if anyone could tell em what I was doing wrong.
thanks.
The WPF Image control is more sophisticated than you imagine... just use the string URI value as the Image.Source directly like this:
<Image Source="http://i.imgur.com/aIf7B0P.jpg" />
Or, if you want to data bind, do this:
<Image Source="{Binding TheImage}" ... />
...
public string TheImage
{
get { return "http://i.imgur.com/aIf7B0P.jpg"; }
}

How to reuse vector images in wpf properly

X problem:
I want to use vector graphic in WPF.
I have bunch of SVG files, which I can convert into XAML by using Inkscape. Resulting xaml is ResourceDictionary with ViewBox / Canvas containing Path, etc. Dictionaries are merged into App.xaml and I can use key to access them.
Question: how to use such images? It looks like I am not using them properly.
Here is how I am using them
<Viewbox Child="{StaticResource MyImageResourceKey}" Width="100" Height="100"/>
But it looks like I can use it only once (in one place)! Attempting to use that image in multiple places simultaneously will either remove it from previous place or will throw
System.ArgumentException: Must disconnect specified child from current parent Visual before attaching to new parent Visual.
Y problem
I want to show a list of vector images. I display them like this
<ItemsControl ItemsSource="{Binding Images}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Viewbox Width="100" Height="100">
<ContentPresenter Content="{Binding Image}"/>
</Viewbox>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
ViewModel
public class ViewModelSomeWindow : INotifyPropertyChanged
{
public class MyImage
{
public object Image { get; set; }
}
private ObservableCollection<MyImage> _images;
public ObservableCollection<MyImage> Images
{
get { return _images; }
set { _images = value; OnPropertyChanged(); }
}
...
}
And items are added like this
Images.Add(new MyImage() { Image = App.Current.Resources["MyImageResourceKey"] });
Problem: when using same image ("MyImageResourceKey") for second item, then first item displays (blank) image. If image is already displayed with the use of StaticResource somewhere, then adding item will throw above ArgumentException.
P.S.: I need to solve Y problem, but perhaps I am not using vector graphic properly.
Please Use x:shared =false in path as shown in attached image
and visit this link too for reference

Displaying an Image from a file in an Image control in WPF

I have a huge amount of images (10000 +) all of which I know are JPEGS (from the file header of FF D8)
basically I search a database which gives me matching filenames for the search. I then want to show these images in a list view.
my problem is that none of the images have extensions and when I try to load the image into the list view I get the following error:
No imaging component suitable to complete this operation was found
I believe this is because it cant determine the file type to open it.
I am attempting to bind to a path property using a value converter to return the BitmapImage which will be displayed in the list view Image control.
the converter is here:
public class PathToImageSourceConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (File.Exists(value.ToString()))
{
//these files are JPEGs but without an extension
return new BitmapImage(new Uri(value.ToString()));
}
else return new BitmapImage();
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
The WPF control in XAML is here:
<!-- The list view containing the images, bound to the logos collection in the background -->
<ListView x:Name="lstImages"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
ItemsSource="{Binding Shoeprints}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
SelectedIndex="{Binding SelectedImageIndex}">
<!-- Use a wrap panel so that the images appear side by side instead of one in each row -->
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<!-- Sets the template for the data to be displayed -->
<ListView.ItemTemplate>
<DataTemplate>
<!-- Defines the actual image being displayed -->
<Image Width="50"
Height="50"
Margin="5"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Source="{Binding ShoePrintImagePath, Converter={StaticResource PathToImageSourceConverter}}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
and ShoePrintImagePath is a string property in the ShoePrints class. I know that the rest of this works as I have successfully bound to other properties in this class in this list vew but I cant work this out for images.
C#
VS 2012
WPF
Xaml

Categories