using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Media.Imaging; using System.Runtime.InteropServices; using System.Windows.Media; using System.Windows; using DirectShowLib; using System.Windows.Interop; using System.IO; namespace Tango.Video.DirectShow { #region MakeBitmapSource public class BitmapHelper { [DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory")] internal static extern void CopyMemory(IntPtr Destination, IntPtr Source, uint Length); public static WriteableBitmap FromNativePointer(IntPtr pData, long dataLength, int w, int h, int ch, bool flipImage) { PixelFormat format = PixelFormats.Default; int bitCount = 8; if (ch == 1) format = PixelFormats.Gray8; //grey scale image 0-255 if (ch == 3) { format = PixelFormats.Bgr24; //RGB bitCount = 24; } if (ch == 4) { format = PixelFormats.Bgr32; //RGB + alpha bitCount = 32; } WriteableBitmap wbm = new WriteableBitmap(w, h, 96, 96, format, null); if (flipImage) { int stride = ((w * bitCount / 8) + 3) & ~3; unsafe { var pDest = (byte*)wbm.BackBuffer; var pSrc = (byte*)pData; pSrc += dataLength; for (int i = 0; i < h; i++) { byte* pDstTmp = pDest + i * stride; byte* pSrcTemp = pSrc - (i + 1) * stride; CopyMemory((IntPtr)pDstTmp, (IntPtr)pSrcTemp, (uint)stride); } } } else { CopyMemory(wbm.BackBuffer, pData, (uint)(w * h * ch)); } wbm.Lock(); wbm.AddDirtyRect(new Int32Rect(0, 0, wbm.PixelWidth, wbm.PixelHeight)); wbm.Unlock(); return wbm; } public static BitmapSource FromArray(byte[] data, int w, int h, int ch) { PixelFormat format = PixelFormats.Default; if (ch == 1) format = PixelFormats.Gray8; //grey scale image 0-255 if (ch == 3) format = PixelFormats.Bgr24; //RGB if (ch == 4) format = PixelFormats.Bgr32; //RGB + alpha WriteableBitmap wbm = new WriteableBitmap(w, h, 96, 96, format, null); wbm.WritePixels(new Int32Rect(0, 0, w, h), data, ch * w, 0); return wbm; } public static BitmapSource CreateEmptySource(System.Windows.Size size, System.Windows.Media.Color color) { int width = (int)size.Width; int height = (int)size.Height; int stride = width / 8; byte[] pixels = new byte[height * stride]; try { return BitmapSource.Create(width, height, 96, 96, PixelFormats.Indexed1, new BitmapPalette(new List { color }), pixels, stride); } catch { width = 1920; height = 1080; stride = width / 8; pixels = new byte[height * stride]; return BitmapSource.Create(width, height, 96, 96, PixelFormats.Indexed1, new BitmapPalette(new List { color }), pixels, stride); } } public static WriteableBitmap BitmapSourceToWriteableBitmap(BitmapSource source) { int stride = source.PixelWidth * (source.Format.BitsPerPixel / 8); // Create data array to hold source pixel data byte[] data = new byte[stride * source.PixelHeight]; // Copy source image pixels to the data array source.CopyPixels(data, stride, 0); // Create WriteableBitmap to copy the pixel data to. WriteableBitmap target = new WriteableBitmap( source.PixelWidth, source.PixelHeight, source.DpiX, source.DpiY, source.Format, null); // Write the pixel data to the WriteableBitmap. target.WritePixels( new Int32Rect(0, 0, source.PixelWidth, source.PixelHeight), data, stride, 0); return target; } } #endregion }