MVS4.4 Samples C# MvCameraControlNet_V2 Grab_Callback取图Bmp

 新建Winform 应用类型选择命令行 因为会自动添加

using System.Drawing;
using System.Drawing.Imaging;

的引用避免手动添加 其实是懒得;

其实之前写过一篇类似的 但是那个是旧版本 新版本据说是事件,调试半天我没仔细看

贴出官方README.txt

工业相机SDK提供了两套.Net接口,命名空间分别为:
1. namespace MvCamCtrl.NET:	示例程序位于 MvCameraControlNet 文件夹下。
2. namespace MvCameraControl:	示例程序位于 MvCameraControlNet_V2 文件夹下。

推荐使用 namespace MvCameraControl 的接口


namespace MvCamCtrl.NET:
1. 基于 .Net Framework 3.5 开发,演示如何将SDK的C语言接口封装成.Net接口,再调用封装的.Net接口实现SDK功能
2. 源码位于 MvCameraControlNet\MVCameraSDK\Source\MVCamera.cs


namespace MvCameraControl:
1. 基于 .Net Framework 4.0 开发,是SDK提供的新的.Net程序集(MvCameraControl.Net.dll)
2. 库文件位于客户端安装路径下的 Development\DotNet\AnyCpu\MvCameraControl.Net.dll,同时提供了win32 和 win64版本
3. 具体的调用方法可参考文档目录下的工业相机SDK开发指南(.Net)
using System;

using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using MvCameraControl;

using System.Runtime.InteropServices;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Xml.Linq;


using HalconDotNet;







namespace MVS44V2
{
    public partial class Form1 : Form
    {
        public Form1()
        {



            Runn();
            InitializeComponent();
        }



        private void InitializeComponent()
        {
            this.SuspendLayout();
            // 
            // Form1
            // 
            this.ClientSize = new System.Drawing.Size(725, 465);
            this.Name = "Form1";
            this.ResumeLayout(false);

        }

        const DeviceTLayerType devLayerType = DeviceTLayerType.MvGigEDevice | DeviceTLayerType.MvUsbDevice | DeviceTLayerType.MvGenTLCameraLinkDevice
            | DeviceTLayerType.MvGenTLCXPDevice | DeviceTLayerType.MvGenTLXoFDevice;

        public static void SaveBmp(int width, int height, int stride, byte[] imageData, string fileName, MvGvspPixelType pixelType)
        {
            // 创建 Bitmap 对象
            Bitmap bitmap = null;

            if (pixelType == MvGvspPixelType.PixelType_Gvsp_Mono8)
            {
                // 灰度图
                bitmap = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
            }
            else
            {
                // RGB 图
                bitmap = new Bitmap(width, height, PixelFormat.Format24bppRgb);
            }

            // 锁定 Bitmap 数据
            Rectangle rect = new Rectangle(0, 0, width, height);
            BitmapData bitmapData = bitmap.LockBits(rect, ImageLockMode.WriteOnly, bitmap.PixelFormat);

            // 将图像数据复制到 Bitmap
            if (pixelType == MvGvspPixelType.PixelType_Gvsp_Mono8)
            {
                // 灰度图需要设置调色板
                ColorPalette palette = bitmap.Palette;
                for (int i = 0; i < 256; i++)
                {
                    palette.Entries[i] = Color.FromArgb(i, i, i);
                }
                bitmap.Palette = palette;

                // 灰度图数据直接复制
                Marshal.Copy(imageData, 0, bitmapData.Scan0, imageData.Length);
            }
            else
            {
                // RGB 图数据直接复制
                Marshal.Copy(imageData, 0, bitmapData.Scan0, imageData.Length);
            }

            // 解锁 Bitmap 数据
            bitmap.UnlockBits(bitmapData);

            // 保存为 BMP 文件
            bitmap.Save(fileName, ImageFormat.Bmp);

            // 释放资源
            bitmap.Dispose();
        }

        // 只能 RGB图 灰度图 需要设置调色板
        public static void SaveBmp(int width, int height, int stride, byte[] imageData, string fileName)
        {
            // 创建 Bitmap 对象
            Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format24bppRgb);

            // 锁定 Bitmap 数据
            Rectangle rect = new Rectangle(0, 0, width, height);
            BitmapData bitmapData = bitmap.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);

            // 将图像数据复制到 Bitmap
            Marshal.Copy(imageData, 0, bitmapData.Scan0, imageData.Length);

            // 解锁 Bitmap 数据
            bitmap.UnlockBits(bitmapData);

            // 保存为 BMP 文件
            bitmap.Save(fileName, ImageFormat.Bmp);
        }
        public static Bitmap GetBmp(int width, int height, int stride, byte[] imageData, MvGvspPixelType pixelType)
        {
            // 创建 Bitmap 对象
            Bitmap bitmap = null;

            if (pixelType == MvGvspPixelType.PixelType_Gvsp_Mono8)
            {
                // 灰度图
                bitmap = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
            }
            else
            {
                // RGB 图
                bitmap = new Bitmap(width, height, PixelFormat.Format24bppRgb);
            }

            // 锁定 Bitmap 数据
            Rectangle rect = new Rectangle(0, 0, width, height);
            BitmapData bitmapData = bitmap.LockBits(rect, ImageLockMode.WriteOnly, bitmap.PixelFormat);

            // 处理图像数据
            if (pixelType == MvGvspPixelType.PixelType_Gvsp_Mono8)
            {
                // 设置调色板
                ColorPalette palette = bitmap.Palette;
                for (int i = 0; i < 256; i++)
                {
                    palette.Entries[i] = Color.FromArgb(i, i, i);
                }
                bitmap.Palette = palette;

                // 复制灰度图数据
                Marshal.Copy(imageData, 0, bitmapData.Scan0, imageData.Length);
            }
            else
            {
                // 复制 RGB 数据
                Marshal.Copy(imageData, 0, bitmapData.Scan0, imageData.Length);
            }

            // 解锁 Bitmap 数据
            bitmap.UnlockBits(bitmapData);

            return bitmap;
        }

        public static HTuple ByteToHTuple(byte[] byteArray)
        {
            var tuple = new HTuple(byteArray.Length);
            for (int i = 0; i < byteArray.Length; i++)
            {
                tuple[i] = byteArray[i];
            }
            return tuple;
        }




        static void FrameGrabedEventHandler(object sender, FrameGrabbedEventArgs e)
        {
            Console.WriteLine($@"                 | 灰度图                 | 彩色图
                {e.FrameOut.Image.Width}          | 1280                   | 1280
                {e.FrameOut.Image.Height}         | 1024                   | 1024
                {e.FrameOut.Image.ImageSize}      | 1310720                | 3932160
                {e.FrameOut.FrameNum}             | 58                     | 3
                {e.FrameOut.Image.PixelData}      | System.Byte[]          | System.Byte[]
                {e.FrameOut.Image.PixelDataPtr}   | 549359688              | 538144840
                {e.FrameOut.Image.PixelType}      | PixelType_Gvsp_Mono8   | PixelType_Gvsp_RGB8_Packed

                ");

     
            int width = (int)e.FrameOut.Image.Width;
            int height = (int)e.FrameOut.Image.Height;


            IntPtr pixelData = e.FrameOut.Image.PixelDataPtr; // 托管指针
            int imageSize = (int)e.FrameOut.Image.ImageSize;



            
            int stride = width; // 每行字节数等于宽度 // 假设像素格式是 GrayScale (Mono8)


            if (e.FrameOut.Image.PixelType == MvGvspPixelType.PixelType_Gvsp_RGB8_Packed)
            {
                stride = width * 3; // RGB 图像,每像素 3 字节
            }
            else if (e.FrameOut.Image.PixelType == MvGvspPixelType.PixelType_Gvsp_Mono8)
            {
                stride = width; // 灰度图,每像素 1 字节
            }
             //stride = width * (e.FrameOut.Image.PixelType == MvGvspPixelType.PixelType_Gvsp_Mono8 ? 1 : 3);// 计算宽度和字节数




            // 将托管指针转换为字节数组
            byte[] imageData = new byte[imageSize];
            Marshal.Copy(pixelData, imageData, 0, imageSize);



   


            DateTime now = DateTime.Now;
            // 提取年、月、日、时、分、秒、毫秒
            string year = now.Year.ToString();
            string month = now.Month.ToString("D2"); // 补零,保证两位数
            string day = now.Day.ToString("D2");
            string hour = now.Hour.ToString("D2");
            string minute = now.Minute.ToString("D2");
            string second = now.Second.ToString("D2");
            string millisecond = now.Millisecond.ToString("D6"); // 毫秒
            string folderPath = $@"{year}{month}{day}{hour}{minute}{second}{millisecond}";



            if (!Directory.Exists($@"{Environment.CurrentDirectory}\Image"))
            {
                Directory.CreateDirectory($@"{Environment.CurrentDirectory}\Image");
            }

            if (!Directory.Exists($@"{Environment.CurrentDirectory}\HAImage"))
            {
                Directory.CreateDirectory($@"{Environment.CurrentDirectory}\HAImage");
            }




            if (e.FrameOut.Image.PixelType == MvGvspPixelType.PixelType_Gvsp_RGB8_Packed)
            {


                // SaveBmp(width, height, stride, imageData, "output_rgb.bmp", MvGvspPixelType.PixelType_Gvsp_RGB8_Packed);  //保存

                //   Bitmap rgbBitmap = GetBmp(width, height, stride, imageData, MvGvspPixelType.PixelType_Gvsp_RGB8_Packed); // 转bmp
         
                Bitmap rgbBitmap = GetBmp(width, height, stride, e.FrameOut.Image.PixelData, MvGvspPixelType.PixelType_Gvsp_RGB8_Packed); //转 bmp



                rgbBitmap.Save($@"{Environment.CurrentDirectory}\Image\{folderPath}rgb.bmp");



             


            }
            else if (e.FrameOut.Image.PixelType == MvGvspPixelType.PixelType_Gvsp_Mono8)
            {
    
             //   SaveBmp(width, height, stride, imageData, "output_gray.bmp", MvGvspPixelType.PixelType_Gvsp_Mono8); //保存
                Bitmap grayBitmap = GetBmp(width, height, stride, imageData, MvGvspPixelType.PixelType_Gvsp_Mono8); //转bmp
                grayBitmap.Save($@"{Environment.CurrentDirectory}\Image\{folderPath}gray.bmp");

 

            }


       
         //   HOperatorSet.WriteImage(halconImage, "bmp",0,$@"{Environment.CurrentDirectory}\HAImage\{folderPath}gray.bmp");


            string currentDirectory = Environment.CurrentDirectory;
            Console.WriteLine("当前工作目录: " + currentDirectory);



            // 构建文件夹路径
          //  string folderPath = Path.Combine(year, month, day);

        }




        static void Runn()
        {
            // ch: 初始化 SDK | en: Initialize SDK
            SDKSystem.Initialize();




            IDevice device = null;





            try
            {
                List<IDeviceInfo> devInfoList;

                // ch:枚举设备 | en:Enum device
                int ret = DeviceEnumerator.EnumDevices(devLayerType, out devInfoList);
                if (ret != MvError.MV_OK)
                {
                    Console.WriteLine("Enum device failed:{0:x8}", ret);
                    return;
                }

                Console.WriteLine("Enum device count : {0}", devInfoList.Count);

                if (0 == devInfoList.Count)
                {
                    return;
                }

                // ch:打印设备信息 en:Print device info
                int devIndex = 0;
                foreach (var devInfo in devInfoList)
                {
                    Console.WriteLine("[Device {0}]:", devIndex);
                    if (devInfo.TLayerType == DeviceTLayerType.MvGigEDevice || devInfo.TLayerType == DeviceTLayerType.MvVirGigEDevice || devInfo.TLayerType == DeviceTLayerType.MvGenTLGigEDevice)
                    {
                        IGigEDeviceInfo gigeDevInfo = devInfo as IGigEDeviceInfo;
                        uint nIp1 = ((gigeDevInfo.CurrentIp & 0xff000000) >> 24);
                        uint nIp2 = ((gigeDevInfo.CurrentIp & 0x00ff0000) >> 16);
                        uint nIp3 = ((gigeDevInfo.CurrentIp & 0x0000ff00) >> 8);
                        uint nIp4 = (gigeDevInfo.CurrentIp & 0x000000ff);
                        Console.WriteLine("DevIP: {0}.{1}.{2}.{3}", nIp1, nIp2, nIp3, nIp4);
                    }

                    Console.WriteLine("ModelName:" + devInfo.ModelName);
                    Console.WriteLine("SerialNumber:" + devInfo.SerialNumber);
                    Console.WriteLine();
                    devIndex++;
                }

                Console.Write("Please input index(0-{0:d}):", devInfoList.Count - 1);

                devIndex = Convert.ToInt32(Console.ReadLine());

                if (devIndex > devInfoList.Count - 1 || devIndex < 0)
                {
                    Console.Write("Input Error!\n");
                    return;
                }

                // ch:创建设备 | en:Create device
                device = DeviceFactory.CreateDevice(devInfoList[devIndex]);

                ret = device.Open();
                if (ret != MvError.MV_OK)
                {
                    Console.WriteLine("Open device failed:{0:x8}", ret);
                    return;
                }

                // ch:探测网络最佳包大小(只对GigE相机有效) | en:Detection network optimal package size(It only works for the GigE camera)
                if (device is IGigEDevice)
                {
                    int packetSize;
                    ret = (device as IGigEDevice).GetOptimalPacketSize(out packetSize);
                    if (packetSize > 0)
                    {
                        ret = device.Parameters.SetIntValue("GevSCPSPacketSize", packetSize);
                        if (ret != MvError.MV_OK)
                        {
                            Console.WriteLine("Warning: Set Packet Size failed {0:x8}", ret);
                        }
                        else
                        {
                            Console.WriteLine("Set PacketSize to {0}", packetSize);
                        }
                    }
                    else
                    {
                        Console.WriteLine("Warning: Get Packet Size failed {0:x8}", ret);
                    }
                }

                // ch:设置触发模式为off || en:set trigger mode as off
                ret = device.Parameters.SetEnumValue("TriggerMode", 0);
                if (ret != MvError.MV_OK)
                {
                    Console.WriteLine("Set TriggerMode failed:{0:x8}", ret);
                    return;
                }

                //ch: 设置合适的缓存节点数量 | en: Setting the appropriate number of image nodes
                device.StreamGrabber.SetImageNodeNum(5);

                // ch:注册回调函数 | en:Register image callback
                device.StreamGrabber.FrameGrabedEvent += FrameGrabedEventHandler;
                // ch:开启抓图 || en: start grab image
                ret = device.StreamGrabber.StartGrabbing();
                if (ret != MvError.MV_OK)
                {
                    Console.WriteLine("Start grabbing failed:{0:x8}", ret);
                    return;
                }

                Console.WriteLine("Press enter to exit");
                Console.ReadLine();


                // ch:停止抓图 | en:Stop grabbing
                ret = device.StreamGrabber.StopGrabbing();
                if (ret != MvError.MV_OK)
                {
                    Console.WriteLine("Stop grabbing failed:{0:x8}", ret);
                    return;
                }

                // ch:关闭设备 | en:Close device
                ret = device.Close();
                if (ret != MvError.MV_OK)
                {
                    Console.WriteLine("Close device failed:{0:x8}", ret);
                    return;
                }

                // ch:销毁设备 | en:Destroy device
                device.Dispose();
                device = null;
            }
            catch (Exception e)
            {
                Console.Write("Exception: " + e.Message);
            }
            finally
            {
                // ch:销毁设备 | en:Destroy device
                if (device != null)
                {
                    device.Dispose();
                    device = null;
                }

                // ch: 反初始化SDK | en: Finalize SDK
                SDKSystem.Finalize();

                Console.WriteLine("Press enter to exit");
                Console.ReadKey();
            }
        }










    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值