Reputation: 3743
I need a deep copy of bitmap from another bitmap. Now, most of the solutions say something like this, which is not a deep copy. Meaning that when I lock the original bitmap, then the copy gets locked too, as the clone is a shallow copy of the original bitmap. Now the following seems to work for me, but I am not sure that will work in all cases.
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;
}
I need better and more elegant way of doing this. Otherwise, just point me some cases where the above code may fail. TIA
Upvotes: 5
Views: 5875
Reputation: 3743
I think I have solved the problem by using this snippet. The idea was given by Lanorkin in the comment and the implementaion is found here. Hope this will help somebody later.
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);
}
}
Upvotes: 7
Reputation: 190
You can use like this it is smaller and more elegant way.
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;
}
Upvotes: -1