public DirectBitmap(Bitmap bmp) { Bitmap _disposelater = null; if (bmp.PixelFormat == PixelFormat.Format32bppRgb) { var newBmp = new Bitmap(bmp); bmp = _disposelater = newBmp.Clone(new Rectangle(0, 0, newBmp.Width, newBmp.Height), PixelFormat.Format32bppArgb); newBmp.Dispose(); } if (bmp.PixelFormat != PixelFormat.Format24bppRgb && bmp.PixelFormat != PixelFormat.Format32bppArgb) { throw new InvalidOperationException(nameof(bmp.PixelFormat)); } var pixelformat = bmp.PixelFormat == PixelFormat.Format32bppRgb ? PixelFormat.Format32bppArgb : bmp.PixelFormat; var bdata = bmp.LockBits(new Rectangle(0, 0, Width = bmp.Width, Height = bmp.Height), ImageLockMode.ReadWrite, pixelformat); try { Bits = new byte[bdata.Stride * bdata.Height]; Copying.MemCopy(bdata.Scan0, Marshal.UnsafeAddrOfPinnedArrayElement(Bits, 0), bdata.Stride * bdata.Height); } finally { bmp.UnlockBits(bdata); } BitsHandle = GCHandle.Alloc(Bits, GCHandleType.Pinned); switch (pixelformat) { case PixelFormat.Format24bppRgb: Bitmap = new Bitmap(bmp.Width, bmp.Height, bmp.Width * 3, pixelformat, BitsHandle.AddrOfPinnedObject()); break; case PixelFormat.Format32bppArgb: Bitmap = new Bitmap(bmp.Width, bmp.Height, bmp.Width * 4, pixelformat, BitsHandle.AddrOfPinnedObject()); break; default: throw new InvalidOperationException(nameof(bmp.PixelFormat)); } Scan0 = Marshal.UnsafeAddrOfPinnedArrayElement(Bits, 0); unsafe { _scan0 = (byte *)Scan0.ToPointer(); } _disposelater?.Dispose(); }
/// <summary> /// Raises the Copying event</summary> /// <param name="e">Event args</param> protected virtual void OnCopying(EventArgs e) { Copying.Raise(this, e); }