Files
ATV_STDLabelAttach/Handler/Project/Device/KeyenceBarcode.cs
atvstdla 16da4a5ffa ..
2025-09-26 18:15:59 +09:00

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