BitmapFrameDecode into Image - c#

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

Related

Can't retrieve image from web in Xamarin forms

In the viewmodel of my page, I try to get an image to show. This image I get from one of our webservice. The image source is stored in ProductImage
string path = $#"http://www.MyCompany.be/cdn-cgi/image/width=150,quality=75/images/products/{CurrentProduct.Image}".Replace($"\\", $"/");
ProductImage = ImageSource.FromUri(new Uri(path));
I of course make sure when I update the Image source for the view when I change it
public ImageSource ProductImage
{
get
{
return _productImage;
}
set
{
if (_productImage != value)
{
_productImage = value;
OnPropertyChanged();
}
}
}
Sadly, for some reason it doesn't work. I checked the URL called and it does lead to an image.
It used to work when I was using streams instead of calling an URL. I know I haven't put the safety checks around yet to make sure the image exist, but other than that nothing has changed. I save the image the exact same way, i just use fromUri rather than fromStream.
//Get target's SmbFile.
var file = new SmbFile(path, auth);
try
{
if (file.Exists())
{
// Get readable stream.
var readStream = file.GetInputStream();
//Create reading buffer.
MemoryStream memStream = new MemoryStream();
//Get bytes.
((Stream)readStream).CopyTo(memStream);
var stream1 = new MemoryStream(memStream.ToArray());
if (stream1.Length < 30000000)
{
//Save image
//ProductImage = ImageSource.FromStream(() => stream1);
//Dispose readable stream.
readStream.Dispose();
InfoColSpan = 1;
}
else
{
Common.AlertError("Image trop lourde pour l'affichage");
}
}
}
catch (Exception ex)
{
Common.AlertError(ex, "Impossible de charger l'image");
}
Since I changed my method, I no longer load anything.

Compress and decompress file before saving to disk

In my application i have one web service which getting one file from FormData(client side) and i want to compress that file before saving to disk(without using extra folder).
i read a lot of answers from here but i got confused, which method i will use in code behind to achieve better compression.and also i want to decompress that file on the time of access.
Currently in code behind i am using bellow code to save the file directly.
var httpPostedFile = HttpContext.Current.Request.Files["UploadedImage"];
// Get the complete file path
var fileSavePath = Path.Combine(HttpContext.Current.Server.MapPath("~/Download/"), httpPostedFile.FileName);
// Save the uploaded file to "UploadedFiles" folder
httpPostedFile.SaveAs(fileSavePath);
We can do this by different ways,
one of the best way is convert all images into jpeg,because it will give better clarity with less size,in this we don't need to change any height or width of the particular image
method 1 : convert all images into jpeg(no additional compression needed)
private static void VaryQualityLevel(Image imgToResize,string imageName)
{
// Get a bitmap.
Bitmap bmp1 = new Bitmap(imgToResize);
ImageCodecInfo jgpEncoder = GetEncoder(ImageFormat.Jpeg);
// Create an Encoder object based on the GUID
// for the Quality parameter category.
System.Drawing.Imaging.Encoder myEncoder =
System.Drawing.Imaging.Encoder.Quality;
// Create an EncoderParameters object.
// An EncoderParameters object has an array of EncoderParameter
// objects. In this case, there is only one
// EncoderParameter object in the array.
EncoderParameters myEncoderParameters = new EncoderParameters(1);
EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder,
50L);
myEncoderParameters.Param[0] = myEncoderParameter;
var fileSavePath = Path.Combine(HttpContext.Current.Server.MapPath("~/Download/"), imageName+".jpeg");
bmp1.Save(fileSavePath, jgpEncoder,
myEncoderParameters);
//myEncoderParameter = new EncoderParameter(myEncoder, 100L);
//myEncoderParameters.Param[0] = myEncoderParameter;
//fileSavePath = Path.Combine(HttpContext.Current.Server.MapPath("~/Download/"), "TestPhotoQuality100.jpeg");
//bmp1.Save(fileSavePath, jgpEncoder,
// myEncoderParameters);
// Save the bitmap as a JPG file with 75 quality level compression.
myEncoderParameter = new EncoderParameter(myEncoder, 75L);
//myEncoderParameters.Param[0] = myEncoderParameter;
//fileSavePath = Path.Combine(HttpContext.Current.Server.MapPath("~/Download/"), "TestPhotoQuality75.jpeg");
//bmp1.Save(fileSavePath, jgpEncoder,
// myEncoderParameters);
}
private static ImageCodecInfo GetEncoder(ImageFormat format)
{
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();
foreach (ImageCodecInfo codec in codecs)
{
if (codec.FormatID == format.Guid)
{
return codec;
}
}
return null;
}
method 2: by changing the height and width of the image(without jpeg conversion)
CommonConstant.CS
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace EmptyDemo.compression
{
#region[Directive]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
#endregion[Directive]
/// <summary>
/// This class is used to get the constants
/// </summary>
public class CommonConstant
{
public const string JPEG = ".jpeg";
public const string PNG = ".png";
public const string JPG = ".jpg";
public const string BTM = ".btm";
}
}
ImageCompress.CS
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace EmptyDemo.compression
{
#region[Directive]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
#endregion[Directive]
/// <summary>
/// This class is used to compress the image to
/// provided size
/// </summary>
public class ImageCompress
{
#region[PrivateData]
private static volatile ImageCompress imageCompress;
private Bitmap bitmap;
private int width;
private int height;
private Image img;
#endregion[Privatedata]
#region[Constructor]
/// <summary>
/// It is used to restrict to create the instance of the ImageCompress
/// </summary>
private ImageCompress()
{
}
#endregion[Constructor]
#region[Poperties]
/// <summary>
/// Gets ImageCompress object
/// </summary>
public static ImageCompress GetImageCompressObject
{
get
{
if (imageCompress == null)
{
imageCompress = new ImageCompress();
}
return imageCompress;
}
}
/// <summary>
/// Gets or sets Width
/// </summary>
public int Height
{
get { return height; }
set { height = value; }
}
/// <summary>
/// Gets or sets Width
/// </summary>
public int Width
{
get { return width; }
set { width = value; }
}
/// <summary>
/// Gets or sets Image
/// </summary>
public Bitmap GetImage
{
get { return bitmap; }
set { bitmap = value; }
}
#endregion[Poperties]
#region[PublicFunction]
/// <summary>
/// This function is used to save the image
/// </summary>
/// <param name="fileName"></param>
/// <param name="path"></param>
public void Save(string fileName, string path)
{
if (ISValidFileType(fileName))
{
string pathaname = path + #"\" + fileName;
save(pathaname, 60);
}
}
#endregion[PublicFunction]
#region[PrivateData]
/// <summary>
/// This function is use to compress the image to
/// predefine size
/// </summary>
/// <returns>return bitmap in compress size</returns>
private Image CompressImage()
{
if (GetImage != null)
{
Width = (Width == 0) ? GetImage.Width : Width;
Height = (Height == 0) ? GetImage.Height : Height;
Bitmap newBitmap = new Bitmap(Width, Height, PixelFormat.Format24bppRgb);
newBitmap = bitmap;
newBitmap.SetResolution(80, 80);
return newBitmap.GetThumbnailImage(Width, Height, null, IntPtr.Zero);
}
else
{
throw new Exception("Please provide bitmap");
}
}
/// <summary>
/// This function is used to check the file Type
/// </summary>
/// <param name="fileName">String data type:contain the file name</param>
/// <returns>true or false on the file extention</returns>
private bool ISValidFileType(string fileName)
{
bool isValidExt = false;
string fileExt = Path.GetExtension(fileName);
switch (fileExt.ToLower())
{
case CommonConstant.JPEG:
case CommonConstant.BTM:
case CommonConstant.JPG:
case CommonConstant.PNG:
isValidExt = true;
break;
}
return isValidExt;
}
/// <summary>
/// This function is used to get the imageCode info
/// on the basis of mimeType
/// </summary>
/// <param name="mimeType">string data type</param>
/// <returns>ImageCodecInfo data type</returns>
private ImageCodecInfo GetImageCoeInfo(string mimeType)
{
ImageCodecInfo[] codes = ImageCodecInfo.GetImageEncoders();
for (int i = 0; i < codes.Length; i++)
{
if (codes[i].MimeType == mimeType)
{
return codes[i];
}
}
return null;
}
/// <summary>
/// this function is used to save the image into a
/// given path
/// </summary>
/// <param name="path">string data type</param>
/// <param name="quality">int data type</param>
private void save(string path, int quality)
{
img = CompressImage();
////Setting the quality of the picture
EncoderParameter qualityParam =
new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
////Seting the format to save
ImageCodecInfo imageCodec = GetImageCoeInfo("image/jpeg");
////Used to contain the poarameters of the quality
EncoderParameters parameters = new EncoderParameters(1);
parameters.Param[0] = qualityParam;
////Used to save the image to a given path
img.Save(path, imageCodec, parameters);
}
#endregion[PrivateData]
}
}
Here I am uploading image with the help of jquery and web service and i am passing the file as formdata
[WebMethod]
public void UploadFile()
{
if (HttpContext.Current.Request.Files.AllKeys.Any())
{
// Get the uploaded image from the Files collection
var httpPostedFile = HttpContext.Current.Request.Files["UploadedImage"];
if (httpPostedFile != null)
{
ImageCompress imgCompress = ImageCompress.GetImageCompressObject;
imgCompress.GetImage = new System.Drawing.Bitmap(httpPostedFile.InputStream);
imgCompress.Height = 260;
imgCompress.Width = 358;
//imgCompress.Save(httpPostedFile.FileName, #"C:\Documents and Settings\Rasmi\My Documents\Visual Studio2008\WebSites\compressImageFile\Logo");
imgCompress.Save(httpPostedFile.FileName, HttpContext.Current.Server.MapPath("~/Download/"));
}
}
}

MimeKit.MimeMessage to Browser-Renderable HTML

Is there a way to convert a MimeKit.MimeMessage to HTML that can be rendered in a web browser? I'm not concerned with message attachments, but would like to be able to display the message body, complete with embedded images, in a browser. I'm new to MimeKit and couldn't locate anything in the API docs for this. Any info is appreciated.
EDIT: I didn't find a way to do this natively with MimeKit, but I combined it with the HtmlAgilityPack to parse the MimeMessage.HtmBody and fix the inline images. This seems to work and I'll go with it unless someone has a better idea. For reference, here's the code:
//////////////////////////////////////////////////////////////////////////////////////////
// use MimeKit to parse the message
//////////////////////////////////////////////////////////////////////////////////////////
MimeKit.MimeMessage msg = MimeKit.MimeMessage.Load(stream);
//////////////////////////////////////////////////////////////////////////////////////////
// use HtmlAgilityPack to parse the resulting html in order to fix inline images
//////////////////////////////////////////////////////////////////////////////////////////
HtmlAgilityPack.HtmlDocument hdoc = new HtmlAgilityPack.HtmlDocument();
hdoc.LoadHtml(msg.HtmlBody);
// find all image nodes
var images = hdoc.DocumentNode.Descendants("img");
foreach (var img in images)
{
// check that this is an inline image
string cid = img.Attributes["src"].Value;
if (cid.StartsWith("cid:"))
{
// remove the cid part of the attribute
cid = cid.Remove(0, 4);
// find image object in MimeMessage
MimeKit.MimePart part = msg.BodyParts.First(x => x.ContentId == cid) as MimeKit.MimePart;
if (part != null)
{
using (MemoryStream mstream = new MemoryStream())
{
// get the raw image content
part.ContentObject.WriteTo(mstream);
mstream.Flush();
byte[] imgbytes = mstream.ToArray();
// fix the image source by making it an embedded image
img.Attributes["src"].Value = "data:" + part.ContentType.MimeType + ";" + part.ContentTransferEncoding.ToString().ToLower() + "," +
System.Text.ASCIIEncoding.ASCII.GetString(imgbytes);
}
}
}
}
// write the resulting html to the output stream
hdoc.Save(outputStream);
Your solution is similar to the logic I used to use in MimeKit's MessageReader sample, but now MimeKit provides a better solution:
/// <summary>
/// Visits a MimeMessage and generates HTML suitable to be rendered by a browser control.
/// </summary>
class HtmlPreviewVisitor : MimeVisitor
{
List<MultipartRelated> stack = new List<MultipartRelated> ();
List<MimeEntity> attachments = new List<MimeEntity> ();
readonly string tempDir;
string body;
/// <summary>
/// Creates a new HtmlPreviewVisitor.
/// </summary>
/// <param name="tempDirectory">A temporary directory used for storing image files.</param>
public HtmlPreviewVisitor (string tempDirectory)
{
tempDir = tempDirectory;
}
/// <summary>
/// The list of attachments that were in the MimeMessage.
/// </summary>
public IList<MimeEntity> Attachments {
get { return attachments; }
}
/// <summary>
/// The HTML string that can be set on the BrowserControl.
/// </summary>
public string HtmlBody {
get { return body ?? string.Empty; }
}
protected override void VisitMultipartAlternative (MultipartAlternative alternative)
{
// walk the multipart/alternative children backwards from greatest level of faithfulness to the least faithful
for (int i = alternative.Count - 1; i >= 0 && body == null; i--)
alternative[i].Accept (this);
}
protected override void VisitMultipartRelated (MultipartRelated related)
{
var root = related.Root;
// push this multipart/related onto our stack
stack.Add (related);
// visit the root document
root.Accept (this);
// pop this multipart/related off our stack
stack.RemoveAt (stack.Count - 1);
}
// look up the image based on the img src url within our multipart/related stack
bool TryGetImage (string url, out MimePart image)
{
UriKind kind;
int index;
Uri uri;
if (Uri.IsWellFormedUriString (url, UriKind.Absolute))
kind = UriKind.Absolute;
else if (Uri.IsWellFormedUriString (url, UriKind.Relative))
kind = UriKind.Relative;
else
kind = UriKind.RelativeOrAbsolute;
try {
uri = new Uri (url, kind);
} catch {
image = null;
return false;
}
for (int i = stack.Count - 1; i >= 0; i--) {
if ((index = stack[i].IndexOf (uri)) == -1)
continue;
image = stack[i][index] as MimePart;
return image != null;
}
image = null;
return false;
}
// Save the image to our temp directory and return a "file://" url suitable for
// the browser control to load.
// Note: if you'd rather embed the image data into the HTML, you can construct a
// "data:" url instead.
string SaveImage (MimePart image, string url)
{
string fileName = url.Replace (':', '_').Replace ('\\', '_').Replace ('/', '_');
string path = Path.Combine (tempDir, fileName);
if (!File.Exists (path)) {
using (var output = File.Create (path))
image.ContentObject.DecodeTo (output);
}
return "file://" + path.Replace ('\\', '/');
}
// Replaces <img src=...> urls that refer to images embedded within the message with
// "file://" urls that the browser control will actually be able to load.
void HtmlTagCallback (HtmlTagContext ctx, HtmlWriter htmlWriter)
{
if (ctx.TagId == HtmlTagId.Image && !ctx.IsEndTag && stack.Count > 0) {
ctx.WriteTag (htmlWriter, false);
// replace the src attribute with a file:// URL
foreach (var attribute in ctx.Attributes) {
if (attribute.Id == HtmlAttributeId.Src) {
MimePart image;
string url;
if (!TryGetImage (attribute.Value, out image)) {
htmlWriter.WriteAttribute (attribute);
continue;
}
url = SaveImage (image, attribute.Value);
htmlWriter.WriteAttributeName (attribute.Name);
htmlWriter.WriteAttributeValue (url);
} else {
htmlWriter.WriteAttribute (attribute);
}
}
} else if (ctx.TagId == HtmlTagId.Body && !ctx.IsEndTag) {
ctx.WriteTag (htmlWriter, false);
// add and/or replace oncontextmenu="return false;"
foreach (var attribute in ctx.Attributes) {
if (attribute.Name.ToLowerInvariant () == "oncontextmenu")
continue;
htmlWriter.WriteAttribute (attribute);
}
htmlWriter.WriteAttribute ("oncontextmenu", "return false;");
} else {
// pass the tag through to the output
ctx.WriteTag (htmlWriter, true);
}
}
protected override void VisitTextPart (TextPart entity)
{
TextConverter converter;
if (body != null) {
// since we've already found the body, treat this as an attachment
attachments.Add (entity);
return;
}
if (entity.IsHtml) {
converter = new HtmlToHtml {
HtmlTagCallback = HtmlTagCallback
};
} else if (entity.IsFlowed) {
var flowed = new FlowedToHtml ();
string delsp;
if (entity.ContentType.Parameters.TryGetValue ("delsp", out delsp))
flowed.DeleteSpace = delsp.ToLowerInvariant () == "yes";
converter = flowed;
} else {
converter = new TextToHtml ();
}
string text = entity.Text;
body = converter.Convert (entity.Text);
}
protected override void VisitTnefPart (TnefPart entity)
{
// extract any attachments in the MS-TNEF part
attachments.AddRange (entity.ExtractAttachments ());
}
protected override void VisitMessagePart (MessagePart entity)
{
// treat message/rfc822 parts as attachments
attachments.Add (entity);
}
protected override void VisitMimePart (MimePart entity)
{
// realistically, if we've gotten this far, then we can treat this as an attachment
// even if the IsAttachment property is false.
attachments.Add (entity);
}
}
And then to use this custom HtmlPreviewVisitor class, you'd have a method something like this:
void Render (WebBrowser browser, MimeMessage message)
{
var tmpDir = Path.Combine (Path.GetTempPath (), message.MessageId);
var visitor = new HtmlPreviewVisitor (tmpDir);
Directory.CreateDirectory (tmpDir);
message.Accept (visitor);
browser.DocumentText = visitor.HtmlBody;
}
I know that this seems like a lot of code, but it's covering a lot more than just the simple cases. You'll notice that it also handles rendering text/plain as well as text/plain; format=flowed bodies if the HTML is not available. It also correctly only uses images that are part of the encapsulating multipart/related tree.
One way you could modify this code is to embed the images into the img tags instead of using a temp directory. To do that, you'd modify the SaveImage method to be something like this (be warned, this next segment of code is untested):
string SaveImage (MimePart image, string url)
{
using (var output = new MemoryStream ()) {
image.ContentObject.DecodeTo (output);
var buffer = output.GetBuffer ();
int length = (int) output.Length;
return string.Format ("data:{0};base64,{1}", image.ContentType.MimeType, Convert.ToBase64String (buffer, 0, length));
}
}

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.

Load image from resources

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;

Categories