480 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			480 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System;
 | |
| using System.Collections.Generic;
 | |
| using System.Drawing;
 | |
| using System.IO;
 | |
| using System.Linq;
 | |
| using System.Net;
 | |
| using System.Text;
 | |
| using System.Threading;
 | |
| using System.Threading.Tasks;
 | |
| using System.Drawing.Imaging;
 | |
| using System.Runtime.InteropServices;
 | |
| using AR;
 | |
| using System.Security.Cryptography;
 | |
| 
 | |
| namespace Project.Device
 | |
| {
 | |
|     public class KeyenceBarcode : IDisposable
 | |
|     {
 | |
|         public string IP { get; set; }
 | |
|         public int Port { get; set; }
 | |
|         private Winsock_Orcas.Winsock ws;
 | |
|         public event EventHandler<RecvDataEvent> BarcodeRecv;
 | |
|         public event EventHandler<RecvImageEvent> ImageRecv;
 | |
|         RecvDataEvent LastData = null;
 | |
|         RecvImageEvent LastImage = null;
 | |
| 
 | |
|         public Boolean IsTriggerOn { get; set; } = false;
 | |
|         private DateTime LastTrigOnTime = DateTime.Now;
 | |
|         private System.Threading.Thread thliveimage = null;
 | |
|         public int LiveImagetDelay = 500;
 | |
|         public bool disposed = false;
 | |
|         bool bRunConnectionK = true;
 | |
|         public string Tag { get; set; }
 | |
| 
 | |
| 
 | |
|         public string baseZPL { get; set; }
 | |
| 
 | |
|         public class RecvDataEvent : EventArgs
 | |
|         {
 | |
|             public string RawData { get; set; }
 | |
|             public RecvDataEvent(string rawdata)
 | |
|             {
 | |
|                 this.RawData = rawdata;
 | |
|             }
 | |
|         }
 | |
|         public class RecvImageEvent : EventArgs
 | |
|         {
 | |
|             public Image Image { get; set; }
 | |
|             public RecvImageEvent(Image rawdata)
 | |
|             {
 | |
|                 this.Image = rawdata;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public KeyenceBarcode(string ip = "192.168.100.100", int port = 9004)
 | |
|         {
 | |
|             this.IP = ip;
 | |
|             this.Port = port;
 | |
|             ws = new Winsock_Orcas.Winsock();
 | |
|             ws.LegacySupport = true;
 | |
|             ws.DataArrival += Ws_DataArrival;
 | |
|             ws.Connected += Ws_Connected;
 | |
|             thliveimage = new Thread(new ThreadStart(GetLiveImage));
 | |
|             thliveimage.IsBackground = false;
 | |
|             thliveimage.Start();
 | |
|             Console.WriteLine($"{ip} / Port:{port}");
 | |
|         }
 | |
| 
 | |
|         ~KeyenceBarcode()
 | |
|         {
 | |
|             Dispose(disposing: false);
 | |
|         }
 | |
|         public void Dispose()
 | |
|         {
 | |
|             Dispose(disposing: true);
 | |
|             GC.SuppressFinalize(this);
 | |
|         }
 | |
| 
 | |
|         #region "Image Utility"
 | |
| 
 | |
|         /// <summary>
 | |
|         /// 8bpp 이미지의  팔레트를  설정합니다
 | |
|         /// </summary>
 | |
|         /// <param name="bmp"></param>
 | |
|         public void UpdateGrayPallete(ref Bitmap bmp)
 | |
|         {
 | |
|             if (bmp.PixelFormat == System.Drawing.Imaging.PixelFormat.Format8bppIndexed)
 | |
|             {
 | |
|                 System.Drawing.Imaging.ColorPalette pal = bmp.Palette;
 | |
|                 for (int i = 0; i < 256; i++)
 | |
|                 {
 | |
|                     pal.Entries[i] = Color.FromArgb(i, i, i);
 | |
|                 }
 | |
|                 bmp.Palette = pal;
 | |
|             }
 | |
|         }
 | |
|         public void GetImagePtr(Bitmap bmp, out IntPtr ptr, out int stride)
 | |
|         {
 | |
|             stride = 0;
 | |
|             ptr = IntPtr.Zero;
 | |
|             try
 | |
|             {
 | |
|                 BitmapData bmpdata = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, bmp.PixelFormat);
 | |
|                 ptr = bmpdata.Scan0;
 | |
|                 stride = bmpdata.Stride;
 | |
|                 bmp.UnlockBits(bmpdata);
 | |
|             }
 | |
|             catch (Exception ex)
 | |
|             {
 | |
| 
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public bool IsCompatible(Bitmap source, Bitmap target)
 | |
|         {
 | |
|             if (source == null) return false;
 | |
|             try
 | |
|             {
 | |
|                 if (source.Height != target.Height ||
 | |
|                 source.Width != target.Width ||
 | |
|                 source.PixelFormat != target.PixelFormat) return false;
 | |
|                 return true;
 | |
|             }
 | |
|             catch (Exception ex)
 | |
|             {
 | |
|                 PUB.log.AddE("keyence compatiable : " + ex.Message);
 | |
|                 return false;
 | |
|             }
 | |
| 
 | |
| 
 | |
|         }
 | |
|         public bool IsCompatible(Bitmap source, int w, int h, PixelFormat pf)
 | |
|         {
 | |
|             if (source == null) return false;
 | |
|             if (source.Height != h ||
 | |
|                 source.Width != w ||
 | |
|                 source.PixelFormat != pf) return false;
 | |
| 
 | |
|             return true;
 | |
|         }
 | |
| 
 | |
|         public Bitmap CreateBitmap(int w, int h)
 | |
|         {
 | |
| 
 | |
|             Bitmap bmp = new Bitmap(w, h, PixelFormat.Format8bppIndexed);
 | |
|             UpdateGrayPallete(ref bmp);
 | |
|             return bmp;
 | |
|         }
 | |
| 
 | |
|         byte[] memorybuffer;
 | |
|         public void UpdateBitmap(Bitmap source, Bitmap target)
 | |
|         {
 | |
|             if (source.Width < 10 || source.Height < 10) return;
 | |
|             if (target == null || target.Width < 10 || target.Height < 10)
 | |
|             {
 | |
|                 target = CreateBitmap(source.Width, source.Height);
 | |
|             }
 | |
| 
 | |
|             var bitmaperrcnt = AR.VAR.I32[eVarInt32.BitmapCompatErr];
 | |
|             if (IsCompatible(source, target) == false)
 | |
|             {
 | |
|                 PUB.log.AddE($"Keyence bitmap compatibility error Source:{source.Width}x{source.Height} => Target:{target.Width}x{target.Height}");
 | |
| 
 | |
|                 if (bitmaperrcnt > 5)
 | |
|                 {
 | |
|                     var o = target;
 | |
|                     target = CreateBitmap(source.Width, source.Height);
 | |
|                     if (o != null) o.Dispose();
 | |
|                     bitmaperrcnt = 0;
 | |
|                 }
 | |
|                 else AR.VAR.I32[eVarInt32.BitmapCompatErr] += 1;
 | |
| 
 | |
|                 return;
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 if (bitmaperrcnt > 0)
 | |
|                     AR.VAR.I32[eVarInt32.BitmapCompatErr] = 0;
 | |
|             }
 | |
| 
 | |
|             //get image pointer
 | |
|             BitmapData bmpdatas = source.LockBits(new Rectangle(0, 0, source.Width, source.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, source.PixelFormat);
 | |
|             var ptrs = bmpdatas.Scan0;
 | |
|             var strides = bmpdatas.Stride;
 | |
| 
 | |
|             BitmapData bmpdatat = target.LockBits(new Rectangle(0, 0, target.Width, target.Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, target.PixelFormat);
 | |
|             var ptrt = bmpdatat.Scan0;
 | |
|             var stridet = bmpdatat.Stride;
 | |
| 
 | |
|             //read source data
 | |
|             var sourcesize = Math.Abs(bmpdatas.Stride) * source.Height;
 | |
|             if (memorybuffer == null || memorybuffer.Length != sourcesize)
 | |
|             {
 | |
|                 memorybuffer = new byte[sourcesize];
 | |
|             }
 | |
| 
 | |
|             Marshal.Copy(ptrs, memorybuffer, 0, sourcesize);
 | |
| 
 | |
|             //write target data
 | |
|             Marshal.Copy(memorybuffer, 0, ptrt, sourcesize);
 | |
| 
 | |
|             source.UnlockBits(bmpdatas);
 | |
|             target.UnlockBits(bmpdatat);
 | |
| 
 | |
|         }
 | |
| 
 | |
|         public void UpdateBitmap(Bitmap target, byte[] buffer, int w, int h)
 | |
|         {
 | |
|             if (IsCompatible(target, w, h, target.PixelFormat) == false)
 | |
|             {
 | |
|                 throw new Exception("cannot udate incompatible bitmap.");
 | |
|             }
 | |
| 
 | |
|             //get image pointer
 | |
|             BitmapData bmpdata = target.LockBits(new Rectangle(0, 0, target.Width, target.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, target.PixelFormat);
 | |
|             var ptr = bmpdata.Scan0;
 | |
|             var stride = bmpdata.Stride;
 | |
| 
 | |
| 
 | |
|             if (stride == w) //image x4
 | |
|             {
 | |
|                 Marshal.Copy(buffer, 0, ptr, stride * h);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 for (int i = 0; i < target.Height; ++i)
 | |
|                 {
 | |
|                     Marshal.Copy(buffer, i * w, new IntPtr(ptr.ToInt64() + i * stride), w);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             target.UnlockBits(bmpdata);
 | |
| 
 | |
| 
 | |
|         }
 | |
| 
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
| 
 | |
|         protected virtual void Dispose(bool disposing)
 | |
|         {
 | |
|             if (!this.disposed)
 | |
|             {
 | |
|                 if (disposing)
 | |
|                 {
 | |
|                     //dipose managed resources;
 | |
|                     bRunConnectionK = false;
 | |
|                     Trigger(false);
 | |
|                     ws.DataArrival -= Ws_DataArrival;
 | |
|                     ws.Connected -= Ws_Connected;
 | |
|                     Disconnect();
 | |
|                     if (thliveimage != null && thliveimage.IsAlive) thliveimage.Abort();
 | |
|                 }
 | |
| 
 | |
|                 //dispose unmmanged resources;
 | |
|             }
 | |
| 
 | |
|             disposed = true;
 | |
|         }
 | |
| 
 | |
|         void GetLiveImage()
 | |
|         {
 | |
|             while (bRunConnectionK)
 | |
|             {
 | |
|                 if (IsConnect && IsTriggerOn)
 | |
|                 {
 | |
|                     var tagname = this.Tag;
 | |
|                     var img = GetImage();
 | |
|                     this.LastImage = new RecvImageEvent(img);
 | |
|                     ImageRecv?.Invoke(this, this.LastImage);
 | |
|                     System.Threading.Thread.Sleep(LiveImagetDelay);
 | |
|                 }
 | |
|                 else System.Threading.Thread.Sleep(1000);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private void Ws_Connected(object sender, Winsock_Orcas.WinsockConnectedEventArgs e)
 | |
|         {
 | |
|             this.Trigger(true);
 | |
|         }
 | |
| 
 | |
|         public void Connect()
 | |
|         {
 | |
|             if (this.ws.State == Winsock_Orcas.WinsockStates.Closed)
 | |
|             {
 | |
|                 this.ws.RemoteHost = this.IP;
 | |
|                 this.ws.RemotePort = this.Port;
 | |
|                 this.ws.Connect();
 | |
|             }
 | |
| 
 | |
|         }
 | |
|         public void Disconnect()
 | |
|         {
 | |
|             if (this.ws.State != Winsock_Orcas.WinsockStates.Closed)
 | |
|                 this.ws.Close();
 | |
|         }
 | |
| 
 | |
|         private void Ws_DataArrival(object sender, Winsock_Orcas.WinsockDataArrivalEventArgs e)
 | |
|         {
 | |
|             var data = ws.Get<string>();
 | |
|             this.LastData = new RecvDataEvent(data);
 | |
|             BarcodeRecv?.Invoke(this, LastData);
 | |
|         }
 | |
| 
 | |
|         public bool Reset()
 | |
|         {
 | |
|             //if (IsTriggerOn) return;
 | |
|             string cmd = "RESET";
 | |
|             if (IsConnect == false)
 | |
|             {
 | |
|                 PUB.log.AddE("Keyence Not Connected : RESET");
 | |
|                 return false;
 | |
|             }
 | |
|             try
 | |
|             {
 | |
|                 ws.Send(cmd + "\r");
 | |
|                 return true;
 | |
|             }
 | |
|             catch (Exception ex)
 | |
|             {
 | |
|                 PUB.log.AddE(ex.Message);
 | |
|                 return false;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public bool BSave(int no)
 | |
|         {
 | |
|             var cmd = "BSAVE,{no}";
 | |
|             try
 | |
|             {
 | |
|                 ws.Send(cmd + "\r");
 | |
|                 return true;
 | |
|             }
 | |
|             catch {
 | |
|                 return false;
 | |
|             }
 | |
|         }
 | |
|         public bool BLoad(int no)
 | |
|         {
 | |
|             var cmd = "BLOAD,{no}";
 | |
|             try
 | |
|             {
 | |
|                 ws.Send(cmd + "\r");
 | |
|                 return true;
 | |
|             }
 | |
|             catch {
 | |
|                 return false;
 | |
|             }
 | |
|         }
 | |
|         public void Trigger(bool bOn)
 | |
|         {
 | |
|             //if (IsTriggerOn) return;
 | |
|             string cmd = bOn ? "LON" : "LOFF";
 | |
| 
 | |
|             if (bOn) LastTrigOnTime = DateTime.Now;
 | |
| 
 | |
|             try
 | |
|             {
 | |
|                 ws.Send(cmd + "\r");
 | |
|                 IsTriggerOn = bOn;
 | |
|             }
 | |
|             catch { }
 | |
|         }
 | |
|         public void ExecCommand(string cmd)
 | |
|         {
 | |
|             try
 | |
|             {
 | |
|                 ws.Send(cmd + "\r");
 | |
|             }
 | |
|             catch { }
 | |
|         }
 | |
|         public bool IsConnect
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 if (ws == null) return false;
 | |
|                 return ws.State == Winsock_Orcas.WinsockStates.Connected;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private bool readimage = false;
 | |
|         ManualResetEvent mre = new ManualResetEvent(true);
 | |
|         bool mreSetOK = true;
 | |
|         bool mreResetOK = true;
 | |
| 
 | |
|         public Image GetImage()
 | |
|         {
 | |
|             Image oimg = null;
 | |
|             if (mreResetOK && mre.WaitOne(1000) == false)
 | |
|             {
 | |
|                 mreResetOK = false;
 | |
|                 return oimg;
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 mreResetOK = mre.Reset();
 | |
|                 try
 | |
|                 {
 | |
|                     var url = $"http://{this.IP}/liveimage.jpg";
 | |
|                     var data = UTIL.DownloadImagefromUrl(url);
 | |
|                     var ms = new System.IO.MemoryStream(data);
 | |
|                     oimg = Image.FromStream(ms);
 | |
|                 }
 | |
|                 catch (Exception ex)
 | |
|                 {
 | |
|                     PUB.log.AddE("Keyence GetImage:" + ex.Message);
 | |
|                 }
 | |
| 
 | |
|                 if (mreResetOK)
 | |
|                 {
 | |
|                     mreSetOK = mre.Set();
 | |
|                 }
 | |
|             }
 | |
|             return oimg;
 | |
|         }
 | |
| 
 | |
|         public bool SaveImage(string fn)
 | |
|         {
 | |
|             var fi = new System.IO.FileInfo(fn);
 | |
|             if (fi.Directory.Exists == false)
 | |
|                 fi.Directory.Create();
 | |
| 
 | |
| 
 | |
| 
 | |
|             if (mreResetOK && mre.WaitOne(1000) == false)
 | |
|             {
 | |
|                 mreResetOK = false;
 | |
|                 return false;
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 bool retval = false;
 | |
|                 mreResetOK = mre.Reset();
 | |
|                 try
 | |
|                 {
 | |
|                     var url = $"http://{this.IP}/liveimage.jpg";
 | |
|                     var data = UTIL.DownloadImagefromUrl(url);
 | |
|                     using (var ms = new System.IO.MemoryStream(data))
 | |
|                     {
 | |
|                         using (var oimg = Image.FromStream(ms))
 | |
|                             oimg.Save(fi.FullName);
 | |
|                     }
 | |
|                     retval = true;
 | |
|                 }
 | |
|                 catch (Exception ex)
 | |
|                 {
 | |
| 
 | |
|                 }
 | |
|                 if (mreResetOK)
 | |
|                     mre.Set();
 | |
|                 return retval;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public bool UpdateKeyenceImage(ref System.Windows.Forms.PictureBox pic)
 | |
|         {
 | |
|             bool retval = false;
 | |
|             if (readimage)
 | |
|             {
 | |
|                 PUB.log.AddAT("Keyence is receiving image, command not processed");
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 readimage = true;
 | |
|                 var oimg = pic.Image;
 | |
| 
 | |
|                 var newimage = GetImage();
 | |
| 
 | |
|                 pic.Image = newimage;
 | |
|                 retval = newimage != null;
 | |
|                 if (oimg != null) oimg.Dispose();
 | |
| 
 | |
|             }
 | |
|             readimage = false;
 | |
|             return retval;
 | |
|         }
 | |
|     }
 | |
| }
 | 
