I need to find the way to save images to the IsolatedStorage and show them I the Silverlight (XAML)
Important: Silverlight have to take image “himself”, I cannot set the image from the code behind
I have tried many solutions before.
The very last solution is, to bind byte array and convert them to the Image
XAML
StackPanel Orientation="Horizontal" Margin="0,0,0,20">
<Image Width="110" CacheMode="BitmapCache" Source="{Binding ThumbLocal,Converter={StaticResource imgConverter}}"
Margin="12,0,9,0"/>
<StackPanel Width="311">
Code behind
public byte[] ThumbLocal
{
get;
set;
}
public class ByteImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
MemoryStream memStream = new MemoryStream((byte[])value);
memStream.Seek(0, SeekOrigin.Begin);
BitmapImage thumbLocal = new BitmapImage();
thumbLocal.SetSource(memStream);
return thumbLocal;
}
}
Everything work till I save byte[] to the database and tried to retrieve.
By now I can see the only option save image as file to the IsolatedStorage and then retrieve and covert to byte[].
Is this “smart ” solution?
First, create this converter:
public class BinaryToImageSourceConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value != null && value is byte[])
{
var bytes = value as byte[];
var stream = new MemoryStream(bytes);
var image = new BitmapImage();
image.SetSource(stream);
stream.Close();
return image;
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Second, bind to Your byte[] using this converter, i.e. if you are using MVVM:
View:
<Image Source="{Binding IsolatedStorageImage, Converter={StaticResource BinaryToImageSourceConverter}}" x:Name="ScanImage"/>
You can make property in contrlol (prop snippet) type byte[] and read image to byte array from isostorage, then set value of property to it.
If You got more questions, feel free to ask me.
Related
In WPF, How to use Image source with Multi:
<Image x:Name="imgLane1" HorizontalAlignment="Left" Height="25" Margin="180,225,0,0" VerticalAlignment="Top" Width="42" Stretch="Fill">
<Image.Source>
<MultiBinding Converter="StaticResource LaneImageConverter}" UpdateSourceTrigger="PropertyChanged">
<Binding Path="Attachments">
<Binding Path="Delivery"/>
</MultiBinding>
</Image.Source>
</Image>`
public class LaneImageConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
string path = "";
int attachments = 0;
string delivery = values[1].ToString();
Int32.TryParse(values[0].ToString(), out attachments);
return System.Windows.Data.Binding.DoNothing;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
I can not update imageSource with MultiBinding also debug to update source
Please help me ?
The converter must return an instance of a class that is derived from ImageSource, e.g. a BitmapImage that is loaded from the path of an image file:
public object Convert(
object[] values, Type targetType, object parameter, CultureInfo culture)
{
string path = "";
// compose path from values
return new BitmapImage(new Uri(path));
}
When the image file is a assembly resource, you would use a Resource File Pack URI:
var uri = string.Format("pack://application:,,,/images/{0}{1}.png", values); // for example
return new BitmapImage(new Uri(uri));
I have an ItemsControl control. In its items I show a lot of things: two images in each of the items, some textblocks, etc.
One of the images that are shown in each of the items is the same for all of the items. It's in the Resources.resx file in my project and here's how I load it:
<Image Width="60" Height="60" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Row="0" Grid.Column="2" Grid.RowSpan="2">
<Image.Source>
<Binding Source="{x:Static properties:Resources.myImageName}" Converter="{StaticResource BitmapToImageConverter}" />
</Image.Source>
</Image>
The Convert method of my BitmapToImageConverter converter class looks like this:
public object Convert(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
using (MemoryStream stream = new MemoryStream())
{
((System.Drawing.Bitmap)value).Save(stream, ImageFormat.Png);
stream.Position = 0;
BitmapImage resultImage = new BitmapImage();
resultImage.BeginInit();
resultImage.CacheOption = BitmapCacheOption.OnLoad;
resultImage.StreamSource = stream;
resultImage.EndInit();
resultImage.Freeze();
return resultImage;
}
}
Now, the binding takes a lot of time and I want to shorten it somehow. The Convert method gets called once for every item in my itemscontrol, but with the same image (the same parameters). How can I call it just once for all of the items?
The Converter extends the IValueConverter class.
If I havent misunderstood your question Try this
public class ImageConverter : ValueConverter
{
static BitmapImage resultImage = null;
public object Convert(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
if (resultImage != null)
return resultImage;
using (MemoryStream stream = new MemoryStream())
{
((System.Drawing.Bitmap)value).Save(stream, ImageFormat.Png);
stream.Position = 0;
resultImage = new BitmapImage();
resultImage.BeginInit();
resultImage.CacheOption = BitmapCacheOption.OnLoad;
resultImage.StreamSource = stream;
resultImage.EndInit();
resultImage.Freeze();
return resultImage;
}
}
Create a static variable and assign it the value first time and return it for next times
I have a image in window
<Image Source="{Binding Path=MYImage, Converter={StaticResource ResourceKey=imageConverter}}" />
I have also tried using a value converter:
public class ImageConverter : IValueConverter
{
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
try
{
return new BitmapImage(new Uri((string)value));
}
catch
{
return new BitmapImage();
}
}
public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
and created a dependency property for it.
public string MYImage
{
get { return (string)GetValue(MYImageProperty); }
set { SetValue(MYImageProperty, value); }
}
public static readonly DependencyProperty MYImageProperty=DependencyProperty.Register("PickerImage",typeof(string),typeof(MYClass),new PropertyMetadata("/MYProject;component/pic.png"));
but when i use it, don't show image !!!
you don't have to convert the source.
you can Bind a string like that:
"/My.Namespace;component/Resources/thatsMyImage.png"
xaml:
<Image Source="{Binding Path=MYImage}" />
This is how I resolved the issue in my application.
My Application has many solutions and each solution has many projects.
I am running .NET 4.5 on VS 2012 using WPF.
My application structure is:
MyApplication
CoreSolution
-ProjectA1
-Resources
-Images
warning.ico (Build action set to Resource)
information.ico (Build action set to Resource)
error.ico (Build action set to Resource)
+ProjectA2
PersonDatabaseSolution
+ProjectB1
+ProjectB2
I have added images (actual images and not links) in CoreSolution's ProjectA1 project. I did not change the build action of any of the images. Compiled the project to get ProjectA1.dll.
In ProjectB2's PersonDatabaseSolution, I refer to error.ico in code behind using the following:
private ImageSource _myImage
public ImageSource MyImage
{
get
{
if(_myImage==null)
{
uriLoc=new Uri("pack://application:,,,/CoreSolution.ProjectA1;component/Resources/Images/error.ico", UriKInd.Absolute);
BitmapImage bmImage = new BitmapImage();
bmImage.BeginInit();
bmImage.UriSource = uriLoc;
bmImage.EndInit();
_myImage=bmImage;
}
return _myImage;
}
}
The MyImage property is bound in the xaml:
<Image Source="{Binding Path=MyImage}"/>
So far this has worked for me. Hope it helps others as well.
Thanks,
RDV
I've got a WPF application that needs to send pre-generated EMF files to a specified printer/tray.
I don't want to show the PrintDialog; the actual printer/tray is configured before hand. I also don't need to actually view the EMF file either; but rather just send it to the printer.
So far, all my R&D into this has led to is a bunch of posts that are 5 years old dealing with EMF and WPF and how it isn't supported.
Has anybody had any luck with this before? Can someone point me in the right direction?
Turns out this was easier than I thought. You can do this via a Image control, and use of a converter. This example takes the file location of the emf file, and puts it into a WPF usercontrol that I then send to a printer.
In XAML:
<Grid Margin="12">
<Image Source="{Binding Path=FileName, Converter={StaticResource emfImageConverter}, Mode=OneWay}"></Image>
</Grid>
and your converter class:
[ValueConversion(typeof(string), typeof(BitmapImage))]
public class EmfImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var fileName = (string)value;
if (fileName == null || !File.Exists(fileName))
return new BitmapImage();
using (var stream = File.Open(fileName, FileMode.Open))
{
return GetImage(stream);
}
}
internal BitmapImage GetImage(Stream fileStream)
{
var img = Image.FromStream(fileStream);
var imgBrush = new BitmapImage { CacheOption = BitmapCacheOption.OnLoad, CreateOptions = BitmapCreateOptions.PreservePixelFormat };
imgBrush.BeginInit();
imgBrush.StreamSource = ConvertImageToMemoryStream(img);
imgBrush.EndInit();
return imgBrush;
}
public MemoryStream ConvertImageToMemoryStream(Image img)
{
var ms = new MemoryStream();
img.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
return ms;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
I have a Value Converter running for an incoming string value from the database, to set the appropriate icon for a gender. The value coming in must be either M or F, and either one will display a male or female icon respectively. The Binding is working to some extent, in that the picture appears, but it is only displaying one set of icons for either value.
The value converter code is as follows:
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var gender = (string)value;
Uri uri;
uri = gender == "F" ?
new Uri("../Resources/Icons/female_user.png", UriKind.Relative) :
new Uri("../Resources/Icons/male_user.png", UriKind.Relative);
return uri;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
and the XAML is as follows
<Image Margin="8" Width="35" Height="35"
VerticalAlignment="Top" HorizontalAlignment="Center"
Source="{Binding Gender, Converter={StaticResource genderConverter}}" />
The resource is cited in the usercontrol.resources and all is properly bound I assume. So why does the converter persistently return only one value?
Try this...
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var gender = (string)value;
Uri uri;
uri = gender == "F" ?
new Uri("../Resources/Icons/female_user.png", UriKind.Relative) :
new Uri("../Resources/Icons/male_user.png", UriKind.Relative);
BitmapImage img_Gender = new BitmapImage(uri);
return img_Gender;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return null;
}
All I needed was a gender.Trim() to get rid of all white spaces.
var gender = value.ToString();
try
{
return gender.Trim() == "F" ? "../Resources/Icons/male_user.png" : "../Resources/Icons/female_user.png";
}
catch (Exception)
{
return "";
}
Thats took care of it all, and it works. Thanks for the answers and "doh!" possibilites though.