Skip to content

Instantly share code, notes, and snippets.

@immengineer
Created September 29, 2017 08:40
Show Gist options
  • Save immengineer/03c0facbab6d88af83e470b9c731cb2b to your computer and use it in GitHub Desktop.
Save immengineer/03c0facbab6d88af83e470b9c731cb2b to your computer and use it in GitHub Desktop.

Revisions

  1. immengineer created this gist Sep 29, 2017.
    500 changes: 500 additions & 0 deletions Form1.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,500 @@
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using Jai_FactoryDotNET;
    using System.Threading;
    using System.Runtime.InteropServices;
    using System.Diagnostics;

    namespace ImageDelegateSample
    {
    public partial class Form1 : Form
    {
    // Main factory object
    CFactory myFactory = new CFactory();

    // Opened camera object
    CCamera myCamera;

    // GenICam nodes
    CNode myWidthNode;
    CNode myHeightNode;
    CNode myGainNode;
    CNode myPixelFormatNode;

    // ClipBoard Copy
    String sClipBd = "";

    // Mono10 Packed : 10bit * 4pixel = 40bit -> 5byte
    struct Mono10p
    {
    public byte bData1;
    public byte bData2;
    public byte bData3;
    public byte bData4;
    public byte bData5;
    }

    // Mono12 Packed : 12bit * 2pixel = 24bit -> 3byte
    struct Mono12p
    {
    public byte bData1;
    public byte bData2;
    public byte bData3;
    }

    public Form1()
    {
    InitializeComponent();

    Jai_FactoryWrapper.EFactoryError error = Jai_FactoryWrapper.EFactoryError.Success;

    // Open the factory with the default Registry database
    error = myFactory.Open("");

    // Search for cameras and update all controls
    SearchButton_Click(null, null);
    }

    private void WidthNumericUpDown_ValueChanged(object sender, EventArgs e)
    {
    if (myWidthNode != null)
    {
    myWidthNode.Value = int.Parse(WidthNumericUpDown.Value.ToString());
    SetFramegrabberValue("Width", (Int64)myWidthNode.Value);
    }
    }

    private void HeightNumericUpDown_ValueChanged(object sender, EventArgs e)
    {
    if (myHeightNode != null)
    {
    myHeightNode.Value = int.Parse(HeightNumericUpDown.Value.ToString());
    SetFramegrabberValue("Height", (Int64)myHeightNode.Value);
    }
    }

    private void GainTrackBar_Scroll(object sender, EventArgs e)
    {
    if (myGainNode != null)
    myGainNode.Value = int.Parse(GainTrackBar.Value.ToString());

    GainLabel.Text = myGainNode.Value.ToString();
    }

    private void StartButton_Click(object sender, EventArgs e)
    {
    if (myCamera != null)
    {
    myCamera.NewImageDelegate += new Jai_FactoryWrapper.ImageCallBack(HandleImage);
    myCamera.StartImageAcquisition(true, 5);
    }
    }

    private void StopButton_Click(object sender, EventArgs e)
    {
    if (myCamera != null)
    {
    myCamera.StopImageAcquisition();
    myCamera.NewImageDelegate -= new Jai_FactoryWrapper.ImageCallBack(HandleImage);
    }
    // Copy to ClipBoard
    if (sClipBd != "") Clipboard.SetText(sClipBd);
    }

    private void SearchButton_Click(object sender, EventArgs e)
    {
    if (null != myCamera)
    {
    if (myCamera.IsOpen)
    {
    myCamera.Close();
    }

    myCamera = null;
    }

    // Discover GigE and/or generic GenTL devices using myFactory.UpdateCameraList(in this case specifying Filter Driver for GigE cameras).
    myFactory.UpdateCameraList(Jai_FactoryDotNET.CFactory.EDriverType.FilterDriver);

    // Open the camera - first check for GigE devices
    for (int i = 0; i < myFactory.CameraList.Count; i++)
    {
    myCamera = myFactory.CameraList[i];
    if (Jai_FactoryWrapper.EFactoryError.Success == myCamera.Open())
    {
    break;
    }
    }

    if (null != myCamera && myCamera.IsOpen)
    {
    CameraIDTextBox.Text = myCamera.CameraID;

    if (myCamera.NumOfDataStreams > 0)
    {
    StartButton.Enabled = true;
    StopButton.Enabled = true;
    }
    else
    {
    StartButton.Enabled = false;
    StopButton.Enabled = false;
    }

    int currentValue = 0;

    // Get the Width GenICam Node
    myWidthNode = myCamera.GetNode("Width");
    if (myWidthNode != null)
    {
    currentValue = int.Parse(myWidthNode.Value.ToString());

    // Update range for the Numeric Up/Down control
    // Convert from integer to Decimal type
    WidthNumericUpDown.Maximum = decimal.Parse(myWidthNode.Max.ToString());
    WidthNumericUpDown.Minimum = decimal.Parse(myWidthNode.Min.ToString());
    WidthNumericUpDown.Value = decimal.Parse(currentValue.ToString());

    WidthNumericUpDown.Enabled = true;
    }
    else
    WidthNumericUpDown.Enabled = false;

    SetFramegrabberValue("Width", (Int64)myWidthNode.Value);

    // Get the Height GenICam Node
    myHeightNode = myCamera.GetNode("Height");
    if (myHeightNode != null)
    {
    currentValue = int.Parse(myHeightNode.Value.ToString());

    // Update range for the Numeric Up/Down control
    // Convert from integer to Decimal type
    HeightNumericUpDown.Maximum = decimal.Parse(myHeightNode.Max.ToString());
    HeightNumericUpDown.Minimum = decimal.Parse(myHeightNode.Min.ToString());
    HeightNumericUpDown.Value = decimal.Parse(currentValue.ToString());

    HeightNumericUpDown.Enabled = true;
    }
    else
    HeightNumericUpDown.Enabled = false;

    SetFramegrabberValue("Height", (Int64)myHeightNode.Value);

    SetFramegrabberPixelFormat();

    // Get the GainRaw GenICam Node
    myGainNode = myCamera.GetNode("GainRaw");
    if (myGainNode != null)
    {
    currentValue = int.Parse(myGainNode.Value.ToString());

    // Update range for the TrackBar Controls
    GainTrackBar.Maximum = int.Parse(myGainNode.Max.ToString());
    GainTrackBar.Minimum = int.Parse(myGainNode.Min.ToString());
    GainTrackBar.Value = currentValue;
    GainLabel.Text = myGainNode.Value.ToString();

    GainLabel.Enabled = true;
    GainTrackBar.Enabled = true;
    }
    else
    {
    GainLabel.Enabled = false;
    GainTrackBar.Enabled = false;
    }

    // Get the PixelFormat
    myPixelFormatNode = myCamera.GetNode("PixelFormat");
    }
    else
    {
    StartButton.Enabled = true;
    StopButton.Enabled = true;
    WidthNumericUpDown.Enabled = false;
    HeightNumericUpDown.Enabled = true;
    GainLabel.Enabled = false;
    GainTrackBar.Enabled = false;

    MessageBox.Show("No Cameras Found!");
    }
    }

    // Local callback function used for handle new images
    void HandleImage(ref Jai_FactoryWrapper.ImageInfo ImageInfo)
    {
    // Jai_FactoryWrapper.EFactoryError error = Jai_FactoryWrapper.EFactoryError.Success;

    // This is in fact a callback, so we would need to handle the data as fast as possible and the frame buffer
    // we get as a parameter will be recycled when we terminate.
    // This leaves us with two choises:
    // 1) Get the work we need to do done ASAP and return
    // 2) Make a copy of the image data and process this afterwards
    //
    // We have the access to the buffer directly via the ImageInfo.ImageBuffer variable
    //
    // We can access the raw frame buffer bytes if we use "unsafe" code and pointer
    // To do this we need to set the "Allow unsafe code" in the project properties and then access the data like:
    //
    // unsafe
    // {
    // // Cast IntPtr to pointer to byte
    // byte* pArray = (byte*)ImageInfo.ImageBuffer;
    // // Do something with the data
    // // Read values
    // byte value = pArray[10];
    // // Write values
    // for (int i = 0; i < 1000; i++)
    // pArray[i] = (byte)(i % 255);
    // }
    //
    // // If we want to copy the data instead we can do like this without Unsafe code:
    // byte[] array = null;
    //
    // if (ImageInfo.ImageBuffer != IntPtr.Zero)
    // {
    // // Allocate byte array that can contain the copy of data
    // array = new byte[ImageInfo.ImageSize];
    // // Do the copying
    // Marshal.Copy(ImageInfo.ImageBuffer, array, 0, (int)ImageInfo.ImageSize);
    //
    // // Do something with the raw data
    // byte val = array[10];
    //}
    Debug.WriteLine("Buf=" + ImageInfo.ImageSize.ToString());
    unsafe
    {
    byte bvalue;
    ushort usvalue;

    sClipBd = "";
    int i;

    if (myPixelFormatNode.Value.ToString() == "8 Bit Monochrome")
    {
    // Cast IntPtr to pointer to byte
    byte* pArray = (byte*)ImageInfo.ImageBuffer;

    // Get Top Row data
    for (i = 0; i < 2560; i++)
    {
    bvalue = pArray[i];
    sClipBd += bvalue.ToString() + "\r\n";
    }
    }
    else if (myPixelFormatNode.Value.ToString() == "10 Bit Monochrome"
    || myPixelFormatNode.Value.ToString() == "12 Bit Monochrome")
    {
    // Cast IntPtr to pointer to ushort
    ushort* psArray = (ushort*)ImageInfo.ImageBuffer;

    // Get Top Row data
    for (i = 0; i < 2560; i++)
    {
    usvalue = psArray[i];
    sClipBd += usvalue.ToString() + "\r\n";
    }
    }
    else if (myPixelFormatNode.Value.ToString() == "10 Bit Monochrome Packed")
    {
    // Cast IntPtr to pointer Mono10p
    Mono10p* mono10pArray = (Mono10p*)ImageInfo.ImageBuffer;

    // Get Top Row data
    for (i = 0; i < 2560; i+=4)
    {
    usvalue = (ushort)mono10pArray->bData1;
    usvalue |= (ushort)((mono10pArray->bData2 & 0x03) << 8);
    sClipBd += usvalue.ToString() + "\r\n";

    usvalue = (ushort)(mono10pArray->bData2 >> 2);
    usvalue |= (ushort)((mono10pArray->bData3 & 0x0F) << 6);
    sClipBd += usvalue.ToString() + "\r\n";

    usvalue = (ushort)(mono10pArray->bData3 >> 4);
    usvalue |= (ushort)((mono10pArray->bData4 & 0x3F) << 4);
    sClipBd += usvalue.ToString() + "\r\n";

    usvalue = (ushort)(mono10pArray->bData4 >> 6);
    usvalue |= (ushort)((mono10pArray->bData5) << 2);
    sClipBd += usvalue.ToString() + "\r\n";

    mono10pArray++;
    }
    }
    else if (myPixelFormatNode.Value.ToString() == "12 Bit Monochrome Packed")
    {
    // Cast IntPtr to pointer Mono12p
    Mono12p* mono12pArray = (Mono12p*)ImageInfo.ImageBuffer;

    // Get Top Row data
    for (i = 0; i < 2560; i += 2)
    {
    usvalue = (ushort)mono12pArray->bData1;
    usvalue |= (ushort)((mono12pArray->bData2 & 0x0F) << 8);
    sClipBd += usvalue.ToString() + "\r\n";

    usvalue = (ushort)((mono12pArray->bData2 & 0xF0) >> 4);
    usvalue |= (ushort)(mono12pArray->bData3 << 4);
    sClipBd += usvalue.ToString() + "\r\n";

    mono12pArray++;
    }
    }
    }
    return;
    }

    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
    if (myCamera != null)
    {
    StopButton_Click(null, null);
    myCamera.Close();
    return;
    }
    }

    private void SetFramegrabberValue(String nodeName, Int64 int64Val)
    {
    if (null == myCamera)
    {
    return;
    }

    IntPtr hDevice = IntPtr.Zero;
    Jai_FactoryWrapper.EFactoryError error = Jai_FactoryWrapper.J_Camera_GetLocalDeviceHandle(myCamera.CameraHandle, ref hDevice);
    if (Jai_FactoryWrapper.EFactoryError.Success != error)
    {
    return;
    }

    if (IntPtr.Zero == hDevice)
    {
    return;
    }

    IntPtr hNode;
    error = Jai_FactoryWrapper.J_Camera_GetNodeByName(hDevice, nodeName, out hNode);
    if (Jai_FactoryWrapper.EFactoryError.Success != error)
    {
    return;
    }

    if (IntPtr.Zero == hNode)
    {
    return;
    }

    error = Jai_FactoryWrapper.J_Node_SetValueInt64(hNode, false, int64Val);
    if (Jai_FactoryWrapper.EFactoryError.Success != error)
    {
    return;
    }

    //Special handling for Active Silicon CXP boards, which also has nodes prefixed
    //with "Incoming":
    if ("Width" == nodeName || "Height" == nodeName)
    {
    string strIncoming = "Incoming" + nodeName;
    IntPtr hNodeIncoming;
    error = Jai_FactoryWrapper.J_Camera_GetNodeByName(hDevice, strIncoming, out hNodeIncoming);
    if (Jai_FactoryWrapper.EFactoryError.Success != error)
    {
    return;
    }

    if (IntPtr.Zero == hNodeIncoming)
    {
    return;
    }

    error = Jai_FactoryWrapper.J_Node_SetValueInt64(hNodeIncoming, false, int64Val);
    }
    }

    private void SetFramegrabberPixelFormat()
    {
    String nodeName = "PixelFormat";

    if (null == myCamera)
    {
    return;
    }

    IntPtr hDevice = IntPtr.Zero;
    Jai_FactoryWrapper.EFactoryError error = Jai_FactoryWrapper.J_Camera_GetLocalDeviceHandle(myCamera.CameraHandle, ref hDevice);
    if (Jai_FactoryWrapper.EFactoryError.Success != error)
    {
    return;
    }

    if (IntPtr.Zero == hDevice)
    {
    return;
    }

    long pf = 0;
    error = Jai_FactoryWrapper.J_Camera_GetValueInt64(myCamera.CameraHandle, nodeName, ref pf);
    if (Jai_FactoryWrapper.EFactoryError.Success != error)
    {
    return;
    }
    UInt64 pixelFormat = (UInt64)pf;

    UInt64 jaiPixelFormat = 0;
    error = Jai_FactoryWrapper.J_Image_Get_PixelFormat(myCamera.CameraHandle, pixelFormat, ref jaiPixelFormat);
    if (Jai_FactoryWrapper.EFactoryError.Success != error)
    {
    return;
    }

    StringBuilder sbJaiPixelFormatName = new StringBuilder(512);
    uint iSize = (uint)sbJaiPixelFormatName.Capacity;
    error = Jai_FactoryWrapper.J_Image_Get_PixelFormatName(myCamera.CameraHandle, jaiPixelFormat, sbJaiPixelFormatName, iSize);
    if (Jai_FactoryWrapper.EFactoryError.Success != error)
    {
    return;
    }

    IntPtr hNode;
    error = Jai_FactoryWrapper.J_Camera_GetNodeByName(hDevice, nodeName, out hNode);
    if (Jai_FactoryWrapper.EFactoryError.Success != error)
    {
    return;
    }

    if (IntPtr.Zero == hNode)
    {
    return;
    }

    error = Jai_FactoryWrapper.J_Node_SetValueString(hNode, false, sbJaiPixelFormatName.ToString());
    if (Jai_FactoryWrapper.EFactoryError.Success != error)
    {
    return;
    }

    //Special handling for Active Silicon CXP boards, which also has nodes prefixed
    //with "Incoming":
    string strIncoming = "Incoming" + nodeName;
    IntPtr hNodeIncoming;
    error = Jai_FactoryWrapper.J_Camera_GetNodeByName(hDevice, strIncoming, out hNodeIncoming);
    if (Jai_FactoryWrapper.EFactoryError.Success != error)
    {
    return;
    }

    if (IntPtr.Zero == hNodeIncoming)
    {
    return;
    }
    error = Jai_FactoryWrapper.J_Node_SetValueString(hNodeIncoming, false, sbJaiPixelFormatName.ToString());
    }
    }
    }