I'm trying to crop a Bitmap. I found this code which seems to be the fastest solution, since it reuses the bitmap data instead of creating a copy (like the copy constructor does). That's fine since I don't need the original at all, and I'd even modify the original if that was possible. The whole point is to work around a bug in another library:
private static Bitmap GetBitmap(ChromiumWebBrowser browser, DefaultRenderHandler renderHandler)
{
Bitmap oldBitmap = null;
try
{
var bitmap = renderHandler.BitmapBuffer.CreateBitmap();
// Taking care of https://bitbucket.org/chromiumembedded/cef/issues/2864/osr-resize
if (bitmap.Size != browser.Size)
{
oldBitmap = bitmap;
var newWidth = Math.Min(bitmap.Size.Width, browser.Size.Width);
var newHeight = Math.Min(bitmap.Size.Height, browser.Size.Height);
var newX = (bitmap.Size.Width - newWidth) / 2;
var newY = (bitmap.Size.Height - newHeight) / 2;
return bitmap.Clone(new Rectangle(newX, newY, newWidth, newHeight), bitmap.PixelFormat);
}
else
return bitmap;
}
finally
{
oldBitmap?.Dispose();
Monitor.Exit(renderHandler.BitmapLock);
}
}
So here renderHandler.BitmapBuffer.CreateBitmap()
creates a new bitmap that must be disposed. Originally, when there was no bug in the library, I just returned bitmap
, which the caller disposed. But now I need all that cropping logic because CreateBitmap
will sometimes return a bitmap with white edges around that need to be cropped off. The problem is that, I'm not sure if I need to dispose both the original bitmap and the clone. Here I'm disposing the original whenever I clone it (and the caller disposes the clone), but I'm afraid that it may sometimes break the clone. According to this explanation, Clone
doesn't actually create a clone but reuses the original data, so perhaps disposing the original will sometimes release the memory used by the clone and throw an error when the caller tries to use it.
On the other hand, if I don't dispose the original, I'm not sure if disposing the clone will also dispose everything that needs to be disposed off in the original. Haven't found anything in the docs, and looking at the source code I see it calls some native methods which I have no idea what they do.