【发布时间】:2020-09-17 07:59:41
【问题描述】:
我正在为我们的业务应用程序编写一个小插件,目标是使用条形码阅读器拍照。
一切正常,但问题是条形码阅读器以间隔发送图片,它们非常随机(取决于图像的大小和波特率)。如果不对我收到的字节进行全面分析,就无法判断图片是否已经加载。
目前,我的逻辑尝试通过分别搜索 FF D8 和 FF D9 字节来查找 JPEG 的开始/结束。问题是字节FF D9 可能出现在图像内部。
我显然可以对字节进行一些具体的分析,但是由于 Barcodereader 不断发送数据,在接收字节时执行耗时的操作(调试、CPU、IO 等)最终会出现蓝屏.
我真正想要的是
-
读取显示图像大小的字节(我不能 甚至研究大小是否会占用页眉本身/页脚 考虑到自身...我必须为此计算吗? )。
-
检查我是否收到了所有个字节。
我会将接收和使用字节的代码(它在数据接收事件上,serialPortish)和正确的完整图像(以字节为单位)和损坏的图像放在一起,这可能会有所帮助。
数据接收事件
private void ScannerPort_DataReceived(object sender, DataReceivedEventArgs e)
{
if (_WaitingForImage)
{
List<byte> imageBufferList = new List<byte>(e.RawBuffer);
{
if (imageBufferList[0] == 0x24 && imageBufferList[1] == 0x69)
{
for (int i = 0; i < 17; i++)
{
imageBufferList.RemoveAt(0);
}
}
byte[] imageBuffer = imageBufferList.ToArray();
_ImageReceiving = false;
_WaitingForImage = false;
this.OnImageReceived(imageBuffer);
}
//imageBufferList.AddRange(e.RawBuffer);
}
全字节数组
https://codepen.io/NicolaiWalsemann/pen/KKzxaXg
损坏的字节数组
https://codepen.io/NicolaiWalsemann/pen/YzqONxd
解决方案 1
我可以轻松地做一个 Timer,它在 DataReceived 事件第一次被调用后等待 500ms-2000ms。这将使确定我拥有一切,然后我可以尽可能多地解析它。但显然总是不得不无理等待并不是我想要的。
【问题讨论】:
-
我可能会在里面解释一下 Loop,我们的条码扫描器会在制作图片后发送,“确认”现在将发送图片。它有 17 个字节长。那就是那里的删除循环。但这与图片本身无关......
-
也许这里的答案会有所帮助:Getting Image size of JPEG from its binary
-
例如,有些扫描仪供应商似乎有 API 和库,但您是否可能正在使用这样的供应商? Image capturing via SNAPI.dll API for Symbol barcode scanner DS4208
-
为什么需要
_WaitingForImage守卫?这可能会忽略一些下一个事件处理程序调用,您将丢失下一个接收到的缓冲区。可能它可能包含一些有用的数据。查看 Producer-Consumer 编程模式实现,它可能有助于理解如何正确实现它。例如。使用接收缓冲区的BlockingCollection<byte[]>。条码扫描器是否保证整个图像将立即发送或可以分成多个部分?然后,您必须将这些部分合并到单个数组中。 -
@aepot 我已经减少了代码,只完成了重要的事情,通常那里有条码序列化,_WaitingForImage 关闭了女巫。因为我必须手动将扫描仪设置为图像模式,并且扫描仪没有读取其他内容。并且 WaitingForImage 只会在收到完整图像时设置为 False ,而不是其他方式。所以它实际上对这个问题没有任何作用。
标签: c# stream serial-port jpeg barcode-scanner