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 BarcodeRecv; public event EventHandler 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" /// /// 8bpp 이미지의 팔레트를 설정합니다 /// /// 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(); 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; } } }