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

时间:2012-04-16 15:49:26

标签: c#

我有以下两个类:

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()方法,则会出现Out Of Memory异常。

我该如何解决?

2 个答案:

答案 0 :(得分:1)

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

你在做:

_CurrentBitmap = _CurrentBitmap.Clone();

当你应该做的时候:

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

答案 1 :(得分:0)

我刚刚处理了一个具有相同错误的类似问题。

Clone()对象上调用Bitmap只会创建一个浅表副本;它仍将引用相同的基础图像数据,因此在其中一个对象上调用Dispose()将同时删除原始数据和副本的数据。在已处置的RotateFlip()对象上调用Bitmap会导致出现以下异常:

  

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)