在C#中从位图创建一个全新的位图副本

时间:2017-03-27 06:15:09

标签: c# image-processing bitmap deep-copy

我需要从另一个位图获得位图的深层副本。现在,大多数解决方案都说this,而不是深层复制。这意味着当我锁定原始位图时,副本也会被锁定,因为克隆是原始位图的浅拷贝。现在以下似乎对我有用,但我不确定它是否适用于所有情况。

public static Bitmap GetCopyOf(Bitmap originalImage)
{
    Rectangle rect = new Rectangle(0, 0, originalImage.Width, originalImage.Height);
    Bitmap retrunImage = new Bitmap(originalImage.Width, originalImage.Height, originalImage.PixelFormat);
    BitmapData srcData = originalImage.LockBits(rect, ImageLockMode.ReadOnly, originalImage.PixelFormat);
    BitmapData destData = retrunImage.LockBits(rect, ImageLockMode.WriteOnly, originalImage.PixelFormat);
    int dataLength = Math.Abs(srcData.Stride) * srcData.Height;
    byte[] data = new byte[dataLength];
    Marshal.Copy(srcData.Scan0, data, 0, data.Length);
    Marshal.Copy(data, 0, destData.Scan0, data.Length);
    destData.Stride = srcData.Stride;
    if (originalImage.Palette.Entries.Length != 0)
        retrunImage.Palette = originalImage.Palette;
    originalImage.UnlockBits(srcData);
    retrunImage.UnlockBits(destData);
    return retrunImage;
}

我需要更好,更优雅的方式来做到这一点。否则,请指出一些上述代码可能失败的情况。 TIA

2 个答案:

答案 0 :(得分:4)

我想我已经通过使用这个片段解决了这个问题。这个想法是由Lanorkin在评论中给出的,并且实现了here。希望这会有所帮助。

public static T Clone<T>(T source)
{
    if (!typeof(T).IsSerializable)
    {
        throw new ArgumentException("The type must be serializable.", "source");
    }

    // Don't serialize a null object, simply return the default for that object
    if (Object.ReferenceEquals(source, null))
    {
        return default(T);
    }

    IFormatter formatter = new BinaryFormatter();
    Stream stream = new MemoryStream();
    using (stream)
    {
        formatter.Serialize(stream, source);
        stream.Seek(0, SeekOrigin.Begin);
        return (T)formatter.Deserialize(stream);
    }
}

答案 1 :(得分:-1)

你可以这样使用它更小更优雅的方式。

public static Bitmap GetCopyOf(Bitmap originalImage)
    {
    Bitmap copy = new Bitmap(originalImage.Width, originalImage.Height);
    using (Graphics graphics = Graphics.FromImage(copy))
    {
      Rectangle imageRectangle = new Rectangle(0, 0, copy.Width, copy.Height);
      graphics.DrawImage( originalImage, imageRectangle, imageRectangle, GraphicsUnit.Pixel);
    }
    return copy;
    }