public DirectBitmap(int width, int height, PixelFormat format) { switch (format) { case PixelFormat.Format24bppRgb: Bits = new byte[width * height * 3]; BitsHandle = GCHandle.Alloc(Bits, GCHandleType.Pinned); Bitmap = new Bitmap(width, height, width * 3, format, BitsHandle.AddrOfPinnedObject()); break; case PixelFormat.Format32bppArgb: Bits = new byte[width * height * 4]; BitsHandle = GCHandle.Alloc(Bits, GCHandleType.Pinned); Bitmap = new Bitmap(width, height, width * 4, format, BitsHandle.AddrOfPinnedObject()); break; default: throw new InvalidOperationException(nameof(format)); } Scan0 = Marshal.UnsafeAddrOfPinnedArrayElement(Bits, 0); unsafe { _scan0 = (byte *)Scan0.ToPointer(); } Height = height; Width = width; }
public unsafe void CopyBlock(Rectangle block, ref byte[] dest) { int calc = 0; int WidthSize = block.Width * Info.PixelSize; int CopyOffset = 0; int scan0 = Scan0.ToInt32(); int destSize = WidthSize * block.Height; if (dest == null || dest.Length != destSize) { dest = new byte[destSize]; } calc = (block.Y) * Info.Stride + block.X * Info.PixelSize; fixed(byte *ptr = dest) { for (int i = 0; i < block.Height; i++) { NativeMethods.memcpy(new IntPtr(ptr + CopyOffset), new IntPtr(scan0 + calc), (uint)WidthSize); calc += Info.Stride; CopyOffset += WidthSize; } } }
public void Lock() { if (Locked) { throw new Exception("Already locked"); } lock (ProcessingLock) { bitmapData = bitMap.LockBits(new Rectangle(0, 0, bitMap.Width, bitMap.Height), ImageLockMode.ReadWrite, bitMap.PixelFormat); Info = new SimpleBitmapInfo(bitmapData); Scan0 = bitmapData.Scan0; Scan0_int = Scan0.ToInt32(); } }
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(); }