title: How to create a BitmapImage from a pixel byte array (live video display)
body: <p>I need to display live images on a WPF control. I'm looking for the fastest way to do this using WPF.</p>
  
  <p>I'm capturing images from a camera using its dll API (<a href="http://www.alliedvisiontec.com/us/products/software/windows/avt-pvapi-sdk.html" rel="nofollow noreferrer">AVT</a>).</p>
  
  <p>The image is writen by the dll and the camera rises a callback with an IntPtr to a Image struct called <strong>tFrame</strong> (described below). The pixel data is stored at the ImageBuffer propertie with is an InPtr to a byte array.</p>
  
  <p>I know how to create a Bitmap from the pixel byte array, but not a BitmapImage. So it is possible to create a Bitmap and then create a BitmapImagem from it.
  <a href="https://stackoverflow.com/questions/1118496/using-image-control-in-wpf-to-display-system-drawing-bitmap/1118557#1118557">Here there is a way to create a BitmapImage from a Bitmap on the memory</a>. But I want to create the <strong>BitmapImage</strong> directly from the data source (tFrame). How can I do that?</p>
  
  <p>I know that BitmapImage have a CopyPixels method, but it laks of a SetPixels.</p>
  
  <pre><code>public struct tFrame
  {
      public IntPtr AncillaryBuffer;
      public uint AncillaryBufferSize;
      public uint AncillarySize;
      public tBayerPattern BayerPattern;
      public uint BitDepth;
      public tFrameCtx Context;
      public tImageFormat Format;
      public uint FrameCount;
      public uint Height;
      public IntPtr ImageBuffer;
      public uint ImageBufferSize;
      public uint ImageSize;
      public uint RegionX;
      public uint RegionY;
      public tErr Status;
      public uint TimestampHi;
      public uint TimestampLo;
      public uint Width;
  }
  </code></pre>
  
  <p>Here is how I create a Bitmap from a pixel byte array. This was used at the WinForm version of the software.</p>
  
  <pre><code>private void CreateBitmap(tFrame frame)
  {
      //This sample is for a 8bpp captured image
      PixelFormat pxFormat = PixelFormat.Format8bppIndexed;
  
      //STRIDE
      //[https://stackoverflow.com/questions/1983781/why-does-bitmapsource-create-throw-an-argumentexception/1983886#1983886][3]
      //float bitsPerPixel = System.Drawing.Image.GetPixelFormatSize(format);
      int bitsPerPixel = ((int)pxFormat &gt;&gt; 8) &amp; 0xFF;
      //Number of bits used to store the image data per line (only the valid data)
      int validBitsPerLine = ((int)frame.Width) * bitsPerPixel;
      //4 bytes for every int32 (32 bits)
      int stride = ((validBitsPerLine + 31) / 32) * 4;
  
      Bitmap bmp = new Bitmap((int)frame.Width, (int)frame.Height, stride, pxFormat, frame.ImageBuffer);
  }
  </code></pre>
  
  <hr>
  
  <p>EDIT 1:</p>
  
  <p>Thanks to dr.mo, now I'm able to display 60 FPS 1024x1024 images with ~3% CPU usage!
  What I'm doing is:</p>
  
  <pre><code>//@ UI Thread
  public WriteableBitmap wbm = new WriteableBitmap(1024, 1024, (double)96, (double)96, System.Windows.Media.PixelFormats.Gray8, null);
  this.wbBackBuffer = this.wbm.BackBuffer;
  
  //This can be called by a timer in the UI thread or at the grab Thread for every image, the CPU usage is almost the same.
  void UpdateDisplayImage()
  {
  wbm.Lock();
  wbm.AddDirtyRect(new Int32Rect(0, 0, wbm.PixelWidth, wbm.PixelHeight));
  wbm.Unlock();
  }
  
  //@ Grab Thread
  //Update the backbuffer with new camera image data.
  UpdateBackBuffer(...);
  
  /// &lt;summary&gt;
  /// [http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.writeablebitmap.aspx]
  /// &lt;/summary&gt;
  public void UpdateBackBuffer(IntPtr pData, int w, int h, int ch)
  {
      //Can not acess wbm from outside UI thread
      //CopyMemory(wbm.BackBuffer, pData, (uint)(w * h * ch));
      //I dont know if it is safe to write to it buffer like this:
      CopyMemory(this.wbBackBuffer, pData, (uint)(w * h * ch));
  }
  </code></pre>