When passing a Bitmap
to a method using thread.Start()
and later calling bitmap.save()
it throws the exception Invalid parameter
when trying to save it to memory stream. I'm using a WPF project with .NET Framework 4.7.2.
private void StartBtn_Click()
{
//is another class which accesses the stream of an external camera
backEnd = new BackEnd();
backEnd.ImageReceived += backEnd_ImageReceived;
if (backEnd.Start())
{
hasError = false;
}
else
{
hasError = true;
}
}
//is called when backEnd gets an image
private void backEnd_ImageReceived(object sender, Bitmap bitmap)
{
try
{
MemoryStream memoryStream = new MemoryStream();
bitmap.Save(memoryStream , System.Drawing.Imaging.ImageFormat.Bmp);
memoryStream.Position = 0;
BitmapImage bitmapimage = new BitmapImage();
bitmapimage.BeginInit();
bitmapimage.StreamSource = memoryStream ;
bitmapimage.CacheOption = BitmapCacheOption.OnLoad;
bitmapimage.EndInit();
bitmapimage.Freeze();
if (_otherThread == null)
{
_otherThread = new Thread(new ParameterizedThreadStart(ProcessImage));
_otherThread.Start(bitmap);
}
else if (!_otherThread.IsAlive)
{
_otherThread.Start(bitmap);
}
}
catch (Exception e)
{
Debug.WriteLine("--- [MainWindow] Exception: " + e.Message);
backEnd_MessageBoxTrigger(this, "Exception", e.Message);
}
}
//this method could take longer that's why I'm using a second thread
private void ProcessImage(object parameter)
{
if (parameter.GetType() == typeof(Bitmap))
{
Bitmap bitmap = parameter as Bitmap;
byte[] bytes;
using (MemoryStream memoryStream = new MemoryStream())
{
// Throws invalid parameter exception
bitmap.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Jpeg);
bytes = memoryStream.ToArray();
}
...
}
}
The Invalid parameter exception
When debugging and looking at the properties of the bitmap
all properties show a System Argument Exception
.
After searching for quite some time this is what I came up with. It might not be ideal but it works in my case:
private void StartBtn_Click()
{
//is another class which accesses the stream of an external camera
backEnd = new BackEnd();
backEnd.ImageReceived += backEnd_ImageReceived;
if (backEnd.Start())
{
hasError = false;
}
else
{
hasError = true;
}
}
//is called when backEnd gets an image
private void backEnd_ImageReceived(object sender, Bitmap bitmap)
{
try
{
MemoryStream memoryStream = new MemoryStream();
bitmap.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Bmp);
memoryStream.Position = 0;
BitmapImage bitmapimage = new BitmapImage();
bitmapimage.BeginInit();
bitmapimage.StreamSource = memoryStream;
bitmapimage.CacheOption = BitmapCacheOption.OnLoad;
bitmapimage.EndInit();
bitmapimage.Freeze();
if (_otherThread == null)
{
_otherThread = new Thread(new ParameterizedThreadStart(ProcessImage));
_otherThread.Start(ImageToByteArray(bitmap));
}
else if (!_otherThread.IsAlive)
{
_otherThread.Start(ImageToByteArray(bitmap));
}
}
catch (Exception e)
{
Debug.WriteLine("--- [MainWindow] Exception: " + e.Message);
backEnd_MessageBoxTrigger(this, "Exception", e.Message);
}
}
//this method could take longer that's why I'm using a second thread
private void ProcessImage(object parameter)
{
if (parameter.GetType() == typeof(byte[]))
{
Bitmap bitmap = ByteArrayToImage(parameter as byte[]);
byte[] bytes;
using (MemoryStream memoryStream = new MemoryStream())
{
// Throws invalid parameter exception
bitmap.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Jpeg);
bytes = memoryStream.ToArray();
}
...
}
}
public byte[] ImageToByteArray(System.Drawing.Image image)
{
ImageConverter converter = new ImageConverter();
return (byte[])converter.ConvertTo(image, typeof(byte[]));
}
public System.Drawing.Bitmap ByteArrayToImage(byte[] bytes)
{
using (MemoryStream memoryStream = new MemoryStream(bytes))
{
Bitmap bitmap = new Bitmap(memoryStream);
return bitmap;
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.