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()); } } }