简体   繁体   中英

Bitmap.Save is throwing Invalid Parameter

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 Invalid parameter异常截图

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM