How to display image from a video stream using image control - c#

I'm c# begginer.I used wpf image control to show image from my camera. It's work normally in winform pictureBox but not in WPF image control. It's all blank! And I'm sure the data stream exist.
The icImagingControl1 is the control of my camera SDK.
It's can return image data in many forms. Like Intptr,Byte,Bitmap.
I want load data in image control from memory.
And the function would be triggered everytime the camera snap.
Here is my code.
private void icImagingControl1_ImageAvailable(object sender, XXX.Imaging.ICImagingControl.ImageAvailableEventArgs e)
{
XXX.Imaging.ImageBuffer CurrentBuffer = null;
CurrentBuffer = icImagingControl1.ImageBuffers[e.bufferIndex];
try
{
using (MemoryStream memory = new MemoryStream())
{
CurrentBuffer.Bitmap.Save(memory, ImageFormat.Bmp);
memory.Position = 0;
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.StreamSource = memory;
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.EndInit();
image1.Source = bitmapImage;
}
}
catch (Exception ex)
{
System.Diagnostics.Trace.WriteLine(ex.Message);
}
}
Hope anyone could help me.

Related

Memory 'leak' with MemoryStream and BitmapCacheOption.OnLoad

I have to get a BitmapSource from an Image and for this I use an extension method like this:
public static BitmapSource ToBitmapSource(this Image image)
{
LogEx.FunctionEnter();
if (image == null)
throw new ArgumentNullException("image");
BitmapImage bitmapImage = null;
using (MemoryStream memory = new MemoryStream())
{
image.Save(memory, ImageFormat.Jpeg);
memory.Position = 0;
bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.StreamSource = memory;
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.EndInit();
}
LogEx.FunctionLeave("Rendered image as BitmapSource");
return bitmapImage;
}
If I now release the handle of this and dispose the original Image it stays in the memory, even after calling the GC by hand multiple times. I tested to use files instead of streams with this little piece of code:
string filename = $"c:\\temp\\{page}.jpg";
if (File.Exists(filename))
{
File.Delete(filename);
}
_highResPageImages[page].Save(filename, ImageFormat.Jpeg);
Uri uri = new Uri(filename);
BitmapImage source = new BitmapImage();
source.BeginInit();
source.UriSource = uri;
source.CacheOption = BitmapCacheOption.OnLoad;
source.EndInit();
Document.PageImage = source;
// Ducument.PageImage = _highResPageImages[page].ToBitmapSource();
And even if there is also an OnLoad, it gets disposed when the handle is released. So it must be something with the MemoryStream. But what? I tried this WrapperStream I found somewhere else and to use the Freeze() Method of BitmapImage, but both to no a avail. The problem is, that I cannot cache the images on the drive of the customer (even if it wouldn't cost a huge amount of time to do so) and I get the Image from another DLL, so I cannot change it beforehand. Has someone else an idea?
Edit: I use WPF and the value of the handle is being used in a Binding for display. Maybe that matters somehow. Or that I use BitmapSource in the Binding and handle and not the original BitmapImage.
Try this in ToBitmapSource:
...
bitmapImage.StreamSource = null;
return bitmapImage

WPF image control does not update images

I am working on a project that requires me to get bunch of images and display them as a video. Which means, I will update Image control of WPF 30 times a second.
So far no luck.
BitmapImage img = BitmapToImageSource((Bitmap)image);
this.image_box.Dispatcher.Invoke(() =>
{
//this.image_box.Source.Freeze();
this.image_box.Source = img;
});
BitmapImage BitmapToImageSource(Bitmap bitmap)
{
using (MemoryStream memory = new MemoryStream())
{
bitmap.Save(memory, System.Drawing.Imaging.ImageFormat.Bmp);
memory.Position = 0;
BitmapImage bitmapimage = new BitmapImage();
bitmapimage.BeginInit();
bitmapimage.StreamSource = memory;
bitmapimage.CacheOption = BitmapCacheOption.OnLoad;
bitmapimage.EndInit();
return bitmapimage;
}
}
image_box is the image control (wpf).
So, I was expecting this code to update image and give an illusion of video being played. Whereas it does nothing. I see waiting cursor on the window.
Edited ---- More Info ----
I created a simple program to check if images can be changed in image control. But the results are same. I see waiting cursor and no image.
private void Window_Loaded(object sender, RoutedEventArgs e)
{
ImageSource s1;
ImageSource s2;
s1 = new BitmapImage(new Uri(#"IMAGE_PATH", UriKind.Absolute));
s2 = new BitmapImage(new Uri(#"IMAGE_PATH", UriKind.Absolute));
while (true)
{
try
{
if (image.Source == s1)
image.Source = s2;
else
image.Source = s1;
System.Threading.Thread.Sleep(1000);
}
catch(Exception ex)
{
MessageBox.Show("Error");
}
}
}
Although I knew this fact, but still made the same mistake.
We are not allowed to update GUI in a loop. If we want to do so, we need to create a separate thread.

C#: Getting black image after initiliazing Image with Bitmapimage in WPF

Hi Developer,
I have an issue to display a bitmap image in my System.Windows.Controls.Image,
Am I using Pixelformat correctly?
I am able to display the image, but it shows me just a black rectangle.
I am trying to get the image from the Scanner.
Thank you very much in advance.
Bitmap b = new Bitmap(displayW, displayH, image.PixelFormat);
VCardScan.MainWindow.AppWindow.setImageSource(BitmapToImageSource(b));
public void setImageSource(BitmapImage bitmap)
{
CardBox.Source = bitmap;
}
BitmapImage BitmapToImageSource(Bitmap bitmap)
{
using (MemoryStream memory = new MemoryStream())
{
System.Console.WriteLine(bitmap.ToString());
bitmap.Save(memory, ImageFormat.Png);
memory.Position = 0;
BitmapImage bitmapimage = new BitmapImage();
bitmapimage.BeginInit();
bitmapimage.StreamSource = memory;
bitmapimage.CacheOption = BitmapCacheOption.OnLoad;
bitmapimage.EndInit();
return bitmapimage;
}
}

Xaml C# replacing images from an array of images

Ik in windows forms I could add images in resources and then change the images as users click on an event handler not sure whats changed in Xaml but I cant figure it out.
private void guessClick(object sender, RoutedEventArgs e)
{
wrongGuesses++;
hangmanPicture.Image = hangmanImage[wrongGuesses];
}
if I just put hangmanPicture = hangmanImage[wrongGuesses];
I get can not convert. I don't understand why its trying to convert anything.
if your hangmanImage array is an array of ImageSource or BitmapImage, you can use it like this:
private void guessClick(object sender, RoutedEventArgs e)
{
wrongGuesses++;
hangmanPicture.Source = hangmanImage[wrongGuesses];
}
Otherwise, you have to convert anything in hangmanImage into ImageSource or BitmapImage.
If it's Bitmap you can use below converter before that code:
public static BitmapImage ConvertToBitmapImageFromBitmap(Bitmap bitmap)
{
using(var memory = new MemoryStream())
{
BitmapImage bitmapImage;
bitmap.Save(memory, ImageFormat.Png);
memory.Position = 0;
bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.StreamSource = memory;
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.EndInit();
return bitmapImage;
}
}
So, then it will be like this:
hangmanPicture.Source = ConvertToBitmapImageFromBitmap(hangmanImage[wrongGuesses]);

How can I decode a byte array using a JpegBitmapDecoder

I cannot decode images back from their encoded form as a (Jpeg) byte array retrieved from my database to be used as image sources for my WPF application.
The code I am using to encode them as a Jpeg byte array is as follows:
public byte[] bytesFromBitmap(BitmapImage bit)
{
byte[] data;
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bit));
using (MemoryStream ms = new MemoryStream())
{
encoder.Save(ms);
data = ms.ToArray();
}
return data;
}
This is taking my Image taken directly from a webpage and assigned to an Image control like so:
var img = new BitmapImage(new Uri(entity.Image.ImageSrc)); //the entity has been saved in my DB, having been parsed from html
pbImage.Source = img;
This works just fine, I encode the BitmapImage and it saves just fine. But when I retrieve it from the DB and try to display it in another window, I cannot get it to work after trying every example I can see online - all either render nothing, or a black box or a visual mess not at all similar to the image I encoded.
Neither of the following have worked for me:
public BitmapSource GetBMImage(byte[] data)
{
using (var ms = new MemoryStream(data))
{
JpegBitmapDecoder decoder = new JpegBitmapDecoder(ms, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
BitmapSource frame = decoder.Frames[0];
return frame;
}
}
public static BitmapImage ImageFromBytes(byte[] imageData)
{
if (imageData == null)
{
return null;
}
else
{
var image = new BitmapImage();
using (var mem = new MemoryStream())
{
mem.Position = 0;
image.BeginInit();
image.CreateOptions = BitmapCreateOptions.PreservePixelFormat;
image.CacheOption = BitmapCacheOption.OnLoad;
image.UriSource = null;
image.StreamSource = mem;
image.EndInit();
}
image.Freeze();
return image;
}
} //this throws a 'No imaging component suitable to complete this operation was found' exception
Among other uses of memory streams and decoders I just can't get this to work - can anyone help?

Categories

Resources