Load image from resources - c#

I want to load the image like this:
void info(string channel)
{
//Something like that
channelPic.Image = Properties.Resources.+channel
}
Because I don't want to do
void info(string channel)
{
switch(channel)
{
case "chan1":
channelPic.Image = Properties.Resources.chan1;
break;
case "chan2":
channelPic.Image = Properties.Resources.chan2;
break;
}
}
Is something like this possible?

You can always use System.Resources.ResourceManager which returns the cached ResourceManager used by this class. Since chan1 and chan2 represent two different images, you may use System.Resources.ResourceManager.GetObject(string name) which returns an object matching your input with the project resources
Example
object O = Resources.ResourceManager.GetObject("chan1"); //Return an object from the image chan1.png in the project
channelPic.Image = (Image)O; //Set the Image property of channelPic to the returned object as Image
Notice: Resources.ResourceManager.GetObject(string name) may return null if the string specified was not found in the project resources.
Thanks,
I hope you find this helpful :)

You can do this using the ResourceManager:
public bool info(string channel)
{
object o = Properties.Resources.ResourceManager.GetObject(channel);
if (o is Image)
{
channelPic.Image = o as Image;
return true;
}
return false;
}

Try this for WPF
StreamResourceInfo sri = Application.GetResourceStream(new Uri("pack://application:,,,/WpfGifImage001;Component/Images/Progess_Green.gif"));
picBox1.Image = System.Drawing.Image.FromStream(sri.Stream);

ResourceManager will work if your image is in a resource file. If it is just a file in your project (let's say the root) you can get it using something like this:
System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();
System.IO.Stream file = assembly .GetManifestResourceStream("AssemblyName." + channel);
this.pictureBox1.Image = Image.FromStream(file);
Or if you're in WPF:
private ImageSource GetImage(string channel)
{
StreamResourceInfo sri = Application.GetResourceStream(new Uri("/TestApp;component/" + channel, UriKind.Relative));
BitmapImage bmp = new BitmapImage();
bmp.BeginInit();
bmp.StreamSource = sri.Stream;
bmp.EndInit();
return bmp;
}

this.toolStrip1 = new System.Windows.Forms.ToolStrip();
this.toolStrip1.Location = new System.Drawing.Point(0, 0);
this.toolStrip1.Name = "toolStrip1";
this.toolStrip1.Size = new System.Drawing.Size(444, 25);
this.toolStrip1.TabIndex = 0;
this.toolStrip1.Text = "toolStrip1";
object O = global::WindowsFormsApplication1.Properties.Resources.ResourceManager.GetObject("best_robust_ghost");
ToolStripButton btn = new ToolStripButton("m1");
btn.DisplayStyle = ToolStripItemDisplayStyle.Image;
btn.Image = (Image)O;
this.toolStrip1.Items.Add(btn);
this.Controls.Add(this.toolStrip1);

You can add an image resource in the project then (right click on the project and choose the Properties item) access that in this way:
this.picturebox.image = projectname.properties.resources.imagename;

Related

Check if Url contains Image UWP

I have a series of images stored online which I try to reach programmatically in my Universal Windows Phone App.
Is there a way to find out if the Image exists for the selected parameter and, if not, use an Image placeholder instead?
var img = new BitmapImage(new Uri("url?ID_IMMAGINE=" + idImg1 + "&HEIGHT=100", UriKind.Absolute))
this is how I get the image.
You could attach a handler for the ImageFailed event to set a fallback value for the URI:
var defaultImageUri = new Uri("ms-appx:///Assets/DefaultImage.png");
var bitmap = new BitmapImage();
bitmap.ImageFailed += (s, e) => bitmap.UriSource = defaultImageUri;
bitmap.UriSource = new Uri(...);
You cant use async for Converter. return type of async method must be void,Task,Task<T>. That cant be given to Convert method
try
{
var img = new BitmapImage(new Uri("url?ID_IMMAGINE=" + idImg1 + "&HEIGHT=100", UriKind.Absolute));
if (img == null)
{
img = new BitmapImage(new Uri("defaultImage.png",UriKind.RelativeOrAbsolute));
}
}
catch
{
img = new BitmapImage(new Uri("defaultImage.png", UriKind.RelativeOrAbsolute));
}
If you really want to use converter please go through this Stackoverflow link

Get Exif info from photo

I want to read exif info from Photo using ExifLib, first way is finished because I used PhotoChooserTask and photoChooserTask.Completed += (s, e) => {PhotoConverter.GetMetaData(e);}
and method for get exif info
public static void GetMetaDate(PhotoResult e)
{
ExifLib.JpegInfo info = ExifLib.ExifReader.ReadJpeg(e.ChosenPhoto);
var img = new BitmapImage();
img.SetSource(e.ChosenPhoto);
App.MainViewModel.MetaDate = ReadExif(info);
}
private static string ReadExif(JpegInfo info)
{
JsonObject metaDate = new JsonObject();
metaDate.Add("FNumber", info.FNumber);
return metaDate.ToString();
}
and it is work great, but the problem is when I want to share picture from phone's gallery. My way to get picture looks like this
if (queryStrings.ContainsKey("FileId"))
{
MediaLibrary library = new MediaLibrary();
Picture photoFromLibrary = library.GetPictureFromToken(queryStrings["FileId"]);
BitmapImage bitmapFromPhoto = new BitmapImage();
bitmapFromPhoto.SetSource(photoFromLibrary.GetImage());
}
So, how I should change my GetMetaDate to read photoFromLibrary.GetImage
Ok, I find easy way
public static void GetMetaData(Stream photo)//change to stream
{
ExifLib.JpegInfo info = ExifLib.ExifReader.ReadJpeg(photo);
var img = new BitmapImage();
img.SetSource(photo);
App.MainViewModel.MetaDate = ReadExif(info);
}
and in place with MediaLiblary add stream
if (queryStrings.ContainsKey("FileId"))
{
// Retrieve the photo from the media library using the FileID passed to the app.
MediaLibrary library = new MediaLibrary();
Picture photoFromLibrary = library.GetPictureFromToken(queryStrings["FileId"]);
//Get metadate
Stream stream = photoFromLibrary.GetImage();
PhotoConverter.GetMetaData(stream);
}

Cannot deserialize Image after sending it through the network

So, I have these two methods, which I am using to serialize and deserialize Images:
private static Image GetImageFromString(string image)
{
using (var stream = new MemoryStream(Convert.FromBase64String(image)))
{
return Image.FromStream(stream);
}
}
private static string GetImageAsString(Image image)
{
using (var stream = new MemoryStream())
{
image.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
return Convert.ToBase64String(stream.GetBuffer());
}
}
If I do something Like this:
public Form1()
{
InitializeComponent();
var image = Image.FromFile(#"F:\phpide.png");
pictureBox1.Image = image;
var serialized = GetImageAsString(image);
var secondImage = GetImageFromString(serialized);
pictureBox2.Image = secondImage;
}
It works as expected
Although, If I do something like this:
//client
public void GetImage(JObject o)
{
var imageFile = o["file"].ToString();
if (!File.Exists(imageFile))
{
SendMessage("File does not exist");
return;
}
using (var image = Image.FromFile(imageFile))
{
var serialized = GetImageAsString(image);
var ob = new JObject
{
{ COMMAND, (int) Command.GetImage },
{ "content", serialized }
};
Send(ob);
ob = null;
serialized = null;
}
}
//server
public void ReceiveImage(JObject o)
{
var content = o["content"].ToString();
var image = GetImageFromString(content);
var form = new ImagePreviewForm(image);
form.Show();
}
//server
public ImagePreviewForm(Image image)
{
InitializeComponent();
pictureBox1.Image = image;
}
The image is just blank.
I have checked and the image is being received correctly, with no data loss.
What could be going wrong here? Where should I look?
This is at least one problem:
return Convert.ToBase64String(stream.GetBuffer());
You shouldn't use MemoryStream.GetBuffer here - you should use ToArray. The GetBuffer method returns the underlying buffer as-is... complete with junk data at the end of the buffer, beyond the logical current length of the stream.
Additionally, you shouldn't close the stream when you call Image.FromStream. From the docs:
You must keep the stream open for the lifetime of the Image.
So get rid of the using statement in GetImageFromString.
With the using statement you are disposing the image before the UI thread can display the image properly. Take the code out of the using block and add a Dispose() statement to the Form.Close() method.

How to display images from Picture Directory ?

I want to display pictures in the Pictures library. I get pictures and bind data.
StorageFolder picturesFolder = KnownFolders.PicturesLibrary;
IReadOnlyList<StorageFile> myPictures = await picturesFolder.GetFilesAsync();
var mydata = from file in myPictures select new { Subtitle = "subtitle", Title = "title", Image = this.getImage(file.Path) };
this.DefaultViewModel["Items"] = mydata;
This is getImage() for set BitmapImage.
private async Task<BitmapImage> getImage(string finename)
{
StorageFolder picturesFolder = KnownFolders.PicturesLibrary;
StorageFile file = await picturesFolder.GetFileAsync(fileName);
var stream = await file.OpenReadAsync();
var bitmap = new BitmapImage();
bitmap.SetSource(stream);
return bitmap;
}
But pictures are not displayed.I think this is because of async function, but I don't know the solution. Could you help me ?
I'm not sure how do you use the data that set to DefaultViewModel, but yeah, it looks like the async method is your problem.
What you need to do is to somehow await each call to getImage(). One way to do this is to use async lambda in your select. But to do that, you need to use the method syntax.
When you do that, you will have IEnumerable<Task<a>> (where a is your anonymous type), but you need just IEnumerable<a>. To get that, use Task.WhenAll() (which will return Task<a[]>) and then await its result:
var tasks = myPictures.Select(
async file => new { Subtitle = "subtitle", Title = "title", Image = await getImage(file.Path) });
var data = await Task.WhenAll(tasks);
This will execute all getImage()s at once, which may not be the most efficient solution. If you don't want that, you would need different solution.
svick's solution seems like should work, but as he/she said - it might not be the most efficient solution. A better solution for a folder with unknown number of files is to use data virtualization with FileInformationFactory.GetVirtualizedFilesVector(). That works best with a converter.
Something I have used:
Getting a virtualized file list and binding to a ListView
private async void GetPicturesFromGalleryFolder()
{
var queryOptions = new QueryOptions();
queryOptions.FolderDepth = FolderDepth.Shallow;
queryOptions.IndexerOption = IndexerOption.UseIndexerWhenAvailable;
queryOptions.SortOrder.Clear();
var sortEntry = new SortEntry {PropertyName = "System.DateModified", AscendingOrder = false};
queryOptions.SortOrder.Add(sortEntry);
queryOptions.FileTypeFilter.Add(".png");
var fileQuery = KnownFolders.PicturesLibrary.CreateFileQueryWithOptions(queryOptions);
var fileInformationFactory =
new FileInformationFactory(
fileQuery,
ThumbnailMode.PicturesView,
0,
ThumbnailOptions.None,
true);
MyListView.ItemsSource = fileInformationFactory.GetVirtualizedFilesVector();
}
XAML
<ListView.ItemTemplate>
<DataTemplate>
<Image
Source="{Binding Converter={StaticResource converters:IStorageItemInformationToBitmapImageConverter}"/>
</DataTemplate>
</ListView.ItemTemplate>
IStorageItemInformationToBitmapImageConverter
public class IStorageItemInformationToBitmapImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
var fileInfo = value as FileInformation;
if (fileInfo != null)
{
var bi = new BitmapImage();
// The file is being opened asynchronously but we return the BitmapImage immediately.
SetSourceAsync(bi, fileInfo);
return bi;
}
return null;
}
private async void SetSourceAsync(BitmapImage bi, FileInformation fi)
{
try
{
using (var stream = await fi.OpenReadAsync())
{
await bi.SetSourceAsync(stream);
}
}
catch
{
// ignore failure
}
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
return null;
}
}

BitmapFrameDecode into Image

Recently, I decided to play with Windows Presentation Foundation and create a variation of chess. The whole thing is kinda done (I believe) but it's a long time now as I can't find a way to set my PNG file as a Image control. This is exemplary class which is affected by a issue:
public class Field
{
public Image Image { get; set; }
public Image GetImage(String keyName)
{
ResourceDictionary imagesDictionary = new ResourceDictionary();
imagesDictionary.Source = new Uri("file:/[...]/ImagesDictionary.xaml");
var var = imagesDictionary[keyName];
Image image = (Image) imagesDictionary[keyName];
return image;
}
public void RefreshImage()
{
if (Unit.Subclass.CompareTo("Bishop").Equals(0))
{
if (Unit.Player.IsWhite)
{
this.Image = this.GetImage("WhiteBishop");
}
...
}
}
My ImagesDictionary.xaml file:
<ResourceDictionary>
<ImageSource x:Key="BlackBishop">BlackBishop.png</ImageSource>
<ImageSource x:Key="WhiteBishop">WhiteBishop.png</ImageSource>
...
</ResourceDictionary>
And the issue is that I don't know how to convert the output of GetImage
(System.Windows.Media.Imaging.BitmapFrameDecode)
into the
(System.Windows.Controls.Image)
Any ideas?
System.Windows.Media.Imaging.BitmapFrame is derived from ImageSource.
You should be able to do this:
this.Image = new Image();
this.Image.Source = this.GetImage("WhiteBishop");
or
this.Image.Source = this.GetImage("WhiteBishop").Source;
If BitmapFrameDecode is truly derived from System.Windows.Imaging.Image, not from ImageSource.
-Jesse
OK, here is an improved GetImageSource (name changed to reflect its real purpose).
/// <summary>
/// Get an ImageSource from the ResourceDictionary referred to by the
/// <paramref name="uriDictionary"/>.
/// </summary>
/// <param name="keyName">The ResourceDictionary key of the ImageSource
/// to retrieve.</param>
/// <param name="uriDictionary">The Uri to the XAML file that holds
/// the ResourceDictionary.</param>
/// <returns><c>null</c> on failure, the requested <c>ImageSource</c>
/// on success.</returns>
/// <remarks>If the requested resource is an <c>Image</c> instead of
/// an <c>ImageSource</c>,
/// then the <c>image.Source</c> is returned.</remarks>
public static ImageSource GetImageSource(String keyName, Uri uriDictionary)
{
if (String.IsNullOrEmpty(keyName))
throw new ArgumentNullException("keyName");
if (null == uriDictionary)
throw new ArgumentNullException("uriDictionary");
ResourceDictionary imagesDictionary = new ResourceDictionary();
imagesDictionary.Source = uriDictionary;
var var = imagesDictionary[keyName];
Object blob = imagesDictionary[keyName];
Debug.WriteLine(String.Format(
"error: GetImageSource( '{0}', '{1}' )"
+ " value is: {2}",
keyName,
uriDictionary,
(null == blob) ? "null" : blob.GetType().FullName));
if (null != blob)
{
if (blob is ImageSource)
{
return blob as ImageSource;
}
if (blob is Image)
{
Image image = blob as Image;
return image.Source;
}
if (blob is System.Drawing.Image)
{
System.Drawing.Image dImage = blob as System.Drawing.Image;
MemoryStream mem = new MemoryStream();
dImage.Save(mem, System.Drawing.Imaging.ImageFormat.MemoryBmp);
mem.Position = 0;
BitmapDecoder decode = new BmpBitmapDecoder(
mem,
BitmapCreateOptions.None,
BitmapCacheOption.None);
return decode.Frames[0];
}
Debug.WriteLine(String.Format(
"error: GetImageSource( '{0}', '{1}' )"
+ " can't handle type: {2}",
keyName,
uriDictionary,
blob.GetType().FullName));
}
return null;
}
And to use it you would do this:
String packText = String.Format("pack://application:,,,/{0};component/{1}",
Assembly.GetEntryAssembly().FullName,
"ImageDictionary.xaml");
Uri imageUri = new Uri(packText);
// or if you prefer:
// Uri imageUri = new Uri("file:///.../ImageDictionary.xaml");
//
ImageSource source = GetImageSource(imageKey, imageUri);
if (null != source)
{
this.Image.Source = source;
}
else
{
// bail ...
}
The Drawing.Image case will handle BMP, PNG, JPG, GIF, etc., even though I used BmpBitmapDecoder. But be aware that XAML images stretch very prettily but Drawing.Image does not.
-Jesse
Dim img As New BitmapImage
Using mem As New System.IO.MemoryStream(<InputArrayHere>)
img.BeginInit()
img.StreamSource = mem
img.EndInit()
End Using
return img

Categories