/// <summary> /// Checks parameters of <see cref="INativeBitmapSource.CopyToBitmap"/>. /// </summary> public static void CopyToBitmap(INativeBitmapSource source, Rectangle sourceArea, IntPtr bitmap, int stride, out int requiredBufferSize) { if (bitmap == IntPtr.Zero) { throw new NullReferenceException($"Pointer to bitmap cannot be {nameof(IntPtr.Zero)}."); } if (sourceArea.Left < 0 || sourceArea.Top < 0 || sourceArea.Right > source.Width || sourceArea.Bottom > source.Height) { throw new InvalidOperationException ( $"Source area ({sourceArea}) does not fit within the area of this source ({new Rectangle(0, 0, source.Width, source.Height)})." ); } if (sourceArea.Width < 0) { throw new InvalidOperationException($"Width of source area ({sourceArea.Width}) cannot be negative."); } if (sourceArea.Height < 0) { throw new InvalidOperationException($"Height of source area ({sourceArea.Height}) cannot be negative."); } if (stride < 0) { throw new InvalidOperationException($"Stride ({stride}) cannot be negative."); } if (stride < 4L * sourceArea.Width) { throw new InvalidOperationException($"Stride ({stride}) is less than 4 * (width of source area ({sourceArea.Width}))."); } if (sourceArea.Height == 0) { requiredBufferSize = 0; } else { long requiredBufferSizeL = (sourceArea.Height - 1L) * stride + sourceArea.Width * 4L; if (requiredBufferSizeL > int.MaxValue) { throw new InvalidOperationException($"Required size of target buffer ({requiredBufferSizeL}) exceeds {int.MaxValue}."); } requiredBufferSize = (int)requiredBufferSizeL; } }
private static INativeImage CreateImage(INativeBitmapSource source) { byte[] pixels = new byte[4 * source.Width * source.Height]; GCHandle pixelsHandle = GCHandle.Alloc(pixels, GCHandleType.Pinned); try { source.CopyToBitmap(new Rectangle(0, 0, source.Width, source.Height), pixelsHandle.AddrOfPinnedObject(), 4 * source.Width); } finally { pixelsHandle.Free(); } return(new Win32Image(source.Width, source.Height, pixels)); }