如何修复克隆和处置源位图后的“参数无效”异常

本文关键字:参数 无效 参数无效 异常 位图 何修复 | 更新日期: 2023-09-27 18:31:28

我有以下两个类:

public class ImageHandler
{
    private Bitmap _currentBitmap;
    private Bitmap _bitmapbeforeProcessing;
    public Bitmap CurrentBitmap
    {
        get
        {
            if (_currentBitmap == null)
            {
                _currentBitmap = new Bitmap(1, 1);
            }
            return _currentBitmap;
        }
        set { _currentBitmap = value; }
    }
    public string CurrentBitmapPath { get; set; }
    public void ResetBitmap()
    {
        if (_currentBitmap != null && _bitmapbeforeProcessing != null)
        {
             Bitmap temp = (Bitmap)_currentBitmap.Clone();
            _currentBitmap = (Bitmap)_bitmapbeforeProcessing.Clone();
            _bitmapbeforeProcessing = (Bitmap)temp.Clone();
        }
    }
    internal void RestorePrevious()
    {
        _bitmapbeforeProcessing = _currentBitmap;
    }
 }

和:

public class RotationHandler
{
    private ImageHandler imageHandler;
    public void Flip(RotateFlipType rotateFlipType)
    {
        this.imageHandler.RestorePrevious();
        Bitmap bitmap = (Bitmap) this.imageHandler.CurrentBitmap.Clone();
        this.imageHandler.CurrentBitmap.Dispose(); // dispose of current bitmap
        bitmap.RotateFlip(rotateFlipType);
        this.imageHandler.CurrentBitmap = bitmap;
   }
 }

当轮换后调用ResetBitmap()时,它会显示:

参数无效

但是,如果:

this.imageHandler.CurrentBitmap.Dispose();

被评论,然后它工作正常。 但是,如果多次调用该方法Flip()则会发生内存不足异常。

我该如何解决?

如何修复克隆和处置源位图后的“参数无效”异常

虽然位图是一个 C# 对象,但它实际上是一个 win32 对象,因此,当你完成它时,你必须调用 Dispose()。

您正在执行:

_CurrentBitmap = _CurrentBitmap.Clone();

你应该什么时候做:

_Temp = _CurrentBitmap.Clone();
_CurrentBitmap.Dispose();
_CurrentBitmap = _Temp;

我刚刚处理了一个类似的问题,同样的错误。

Bitmap对象调用Clone()只会创建一个浅拷贝;它仍将引用相同的基础图像数据,因此对其中一个对象调用Dispose()将删除原始对象和副本的数据。 对已释放的Bitmap对象调用RotateFlip()会导致您看到的异常:

System.ArgumentException: 参数无效

解决此问题的一种方法是基于原始对象创建一个新的Bitmap对象,而不是使用 Clone() 。 这将复制图像数据以及托管对象数据。

例如,代替:

Bitmap bitmap = (Bitmap) this.imageHandler.CurrentBitmap.Clone();

用:

Bitmap bitmap = new Bitmap(this.imageHandler.CurrentBitmap);

请注意,如果源位图对象为 null,这也将导致ArgumentException,因此通常以下内容更好(为了简洁起见,我已将源位图重命名为 currentBitmap):

Bitmap bitmap = (currentBitmap == null) ? null : new Bitmap(currentBitmap)