条形码扫描器






4.90/5 (9投票s)
这个Windows应用程序可以扫描指定文件夹中的图像,并生成CSV文件以显示每个图像文件的条码。
引言
这个Windows应用程序可以扫描给定文件夹(及其子文件夹)中的图像,并基于输出生成CSV文件。本文使用了Berend Engelbrecht开发的BarcodeImaging.dll库来扫描条码:从图像中读取条码 - III。
背景
我发现BarcodeImaging.dll库做得相当不错,但在某些情况下我需要使用Byte Scout(Bytescout.BarCodeReader.dll)库(需要付费20美元且速度较慢)。我尝试了Byte Scout库进行比较,但将其在应用程序中未选中,以防有人仍然想尝试它。
Using the Code
要使用此程序,只需选择一个文件夹并单击处理。程序将在目标文件夹中创建一个CSV文件。
这是代码
Dim oAppSetting As New AppSetting()
Dim oLogFile As System.IO.StreamWriter
Dim bStartFile As Boolean = True
Private Sub Form1_FormClosing(sender As Object, _
e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
oAppSetting.SetValue("FromPath", txtFrom.Text)
oAppSetting.SetValue("RegName", txtRegName.Text)
oAppSetting.SetValue("RegKey", txtRegKey.Text)
oAppSetting.SetValue("StartFile", txtStartFile.Text)
oAppSetting.SetValue("BarcodeType", cbBarcodeType.SelectedIndex)
oAppSetting.SetValue("Direction", cbDirection.SelectedIndex)
oAppSetting.SetValue("UseBarcodeZones", IIf(chkUseBarcodeZones.Checked, "1", "0"))
oAppSetting.SetValue("Log", IIf(chkLog.Checked, "1", "0"))
oAppSetting.SetValue("ShowTime", IIf(chkShowTime.Checked, "1", "0"))
oAppSetting.SetValue("CSV", IIf(chkCSV.Checked, "1", "0"))
oAppSetting.SetValue("Bytescout", IIf(chkBytescout.Checked, "1", "0"))
oAppSetting.SetValue("Fast", IIf(chkFast.Checked, "1", "0"))
oAppSetting.SaveData()
End Sub
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
oAppSetting.LoadData()
txtFrom.Text = oAppSetting.GetValue("FromPath")
txtRegName.Text = oAppSetting.GetValueDef("RegName", txtRegName.Text)
txtRegKey.Text = oAppSetting.GetValueDef("RegKey", txtRegKey.Text)
txtStartFile.Text = oAppSetting.GetValue("StartFile")
Dim sBarcodeType As String = oAppSetting.GetValue("BarcodeType")
If sBarcodeType <> "" Then
cbBarcodeType.SelectedIndex = CInt(sBarcodeType)
Else
cbBarcodeType.SelectedIndex = 0
End If
Dim sDirection As String = oAppSetting.GetValue("Direction")
If sDirection <> "" Then
cbDirection.SelectedIndex = CInt(sDirection)
Else
cbDirection.SelectedIndex = 0
End If
chkUseBarcodeZones.Checked = oAppSetting.GetValue("UseBarcodeZones") = "1"
chkLog.Checked = oAppSetting.GetValue("Log") <> "0"
chkShowTime.Checked = oAppSetting.GetValue("ShowTime") <> "0"
chkCSV.Checked = oAppSetting.GetValue("CSV") <> "0"
chkBytescout.Checked = oAppSetting.GetValue("Bytescout") = "1"
chkFast.Checked = oAppSetting.GetValue("Fast") = "1"
BytescoutChecked()
End Sub
Public Shared Function GetShortName(ByVal sLongFileName As String) As String
If sLongFileName.Length < 250 Then
Return sLongFileName
End If
Dim lRetVal As Long
Dim iLen As Integer = 1024
Dim sShortPathName As System.Text.StringBuilder = New System.Text.StringBuilder(iLen)
lRetVal = GetShortPathName(sLongFileName, sShortPathName, iLen)
Dim sRet As String = sShortPathName.ToString()
If sRet <> "" Then
Return sRet
Else
Return sLongFileName
End If
End Function
Private Sub btnFrom_Click(sender As System.Object, e As System.EventArgs) Handles btnFrom.Click
fldFrom.SelectedPath = txtFrom.Text
fldFrom.ShowDialog()
txtFrom.Text = fldFrom.SelectedPath
End Sub
Private Sub btnProcess_Click(sender As System.Object, e As System.EventArgs) _
Handles btnProcess.Click
btnProcess.Enabled = False
Dim sFromPath As String = txtFrom.Text
If Not Directory.Exists(sFromPath) Then
btnProcess.Enabled = True
MsgBox("Folder does not exist")
Exit Sub
End If
If chkCSV.Checked Then
Dim sLogFileName As String = Now.Month.ToString() & "-" & _
Now.Day.ToString() & "-" & _
Now.Year.ToString() & "_" & _
Now.Hour.ToString() & "-" & _
Now.Minute.ToString() & "-" & _
Now.Second.ToString() & ".csv"
Dim sLogFilePath As String = IO.Path.Combine(sFromPath, sLogFileName)
oLogFile = New System.IO.StreamWriter(sLogFilePath)
End If
If txtStartFile.Text <> "" Then
bStartFile = False
End If
txtOutput.Text = ""
txtOutput.AppendText("Starting..." & vbCrLf)
ProccessFolder(sFromPath)
txtOutput.AppendText("Done!")
btnProcess.Enabled = True
If chkCSV.Checked Then
oLogFile.Close()
End If
End Sub
Sub ProccessFolder(ByVal sFolderPath As String)
Dim sFromPath As String = txtFrom.Text
Dim oFiles As String() = Directory.GetFiles(sFolderPath)
ProgressBar1.Maximum = oFiles.Length
For i As Integer = 0 To oFiles.Length - 1
Dim sFromFilePath As String = oFiles(i)
If txtStartFile.Text <> "" Then
If Trim(LCase(txtStartFile.Text)) = LCase(sFromFilePath) Then
bStartFile = True
End If
End If
If bStartFile Then
Dim oFileInfo As New FileInfo(GetShortName(sFromFilePath))
Dim sExt As String = PadExt(oFileInfo.Extension)
If sExt = "JPG" Or sExt = "GIF" Or sExt = "PNG" Or sExt = "BMP" Or sExt = "TIF" Then
If chkBytescout.Checked Then
Bytescout_ReadBarcode(sFromFilePath)
Else
ReadBarcode(sFromFilePath)
End If
End If
End If
ProgressBar1.Value = i
Application.DoEvents()
Next
ProgressBar1.Value = 0
Dim oFolders As String() = Directory.GetDirectories(sFolderPath)
For i As Integer = 0 To oFolders.Length - 1
Dim sChildFolder As String = oFolders(i)
Dim iPos As Integer = sChildFolder.LastIndexOf("\")
Dim sFolderName As String = sChildFolder.Substring(iPos + 1)
ProccessFolder(sChildFolder)
Next
End Sub
Private Sub ReadBarcode(sFromFilePath As String)
Dim sFromPath As String = txtFrom.Text
Dim sFileName As String = sFromFilePath.Replace(sFromPath & "\", "")
Dim oImage As System.Drawing.Image = Nothing
Try
oImage = System.Drawing.Image.FromFile(sFromFilePath)
Catch ex As Exception
If chkLog.Checked Then
txtOutput.AppendText(sFileName & vbTab & "Could not open" & vbCrLf)
End If
WriteLog(sFileName & "," & "Could not open")
Exit Sub
End Try
Dim barcodes As New System.Collections.ArrayList
Dim iScans As Integer = 100
Dim dtStart As DateTime = DateTime.Now
BarcodeImaging.UseBarcodeZones = chkUseBarcodeZones.Checked
Dim oBarcodeType As BarcodeImaging.BarcodeType = BarcodeImaging.BarcodeType.All
Select Case cbBarcodeType.Text
Case "Code39"
oBarcodeType = BarcodeImaging.BarcodeType.Code39
Case "Code128"
oBarcodeType = BarcodeImaging.BarcodeType.Code128
Case "EAN"
oBarcodeType = BarcodeImaging.BarcodeType.EAN
End Select
Select Case cbDirection.Text
Case "All"
BarcodeImaging.FullScanBarcodeTypes = oBarcodeType
BarcodeImaging.FullScanPage(barcodes, oImage, iScans)
Case "Vertical"
BarcodeImaging.ScanPage(barcodes, oImage, iScans, _
BarcodeImaging.ScanDirection.Horizontal, oBarcodeType)
Case "Horizontal"
BarcodeImaging.ScanPage(barcodes, oImage, iScans, _
BarcodeImaging.ScanDirection.Vertical, oBarcodeType)
End Select
Dim sSec As String = ""
If chkShowTime.Checked Then
sSec = vbTab & DateTime.Now.Subtract(dtStart).TotalSeconds.ToString("#0.00")
End If
If barcodes.Count = 0 Then
If chkLog.Checked Then
txtOutput.AppendText(sFileName & vbTab & "Failed" & sSec & vbCrLf)
End If
WriteLog(sFileName & "," & "Failed")
Else
For Each bc As Object In barcodes
If chkLog.Checked Then
txtOutput.AppendText(sFileName & vbTab & bc & sSec & vbCrLf)
End If
WriteLog(sFileName & "," & bc)
Next
End If
oImage.Dispose()
End Sub
以下是AppSetting.vb的代码,用于持久化用户设置
Public Class AppSetting
Private oDS As New Data.DataSet
Private oTable As New Data.DataTable
Private sFilePath As String = ""
Public Sub New()
Dim sAssPath As String = System.Reflection.Assembly.GetExecutingAssembly().Location
Dim sPath As String = System.IO.Path.GetDirectoryName(sAssPath)
sFilePath = System.IO.Path.Combine(sPath, "Settings.xml")
End Sub
Public Sub LoadData()
oDS = New Data.DataSet()
If System.IO.File.Exists(sFilePath) Then
oDS.ReadXml(sFilePath)
If oDS.Tables.Count > 0 Then
oTable = oDS.Tables(0)
Exit Sub
End If
End If
'setup New
oTable = New Data.DataTable()
oTable.Columns.Add(New Data.DataColumn("key"))
oTable.Columns.Add(New Data.DataColumn("value"))
oDS.Tables.Add(oTable)
End Sub
Public Sub SaveData()
'If System.IO.File.Exists(sFilePath) Then
' System.IO.File.Delete(sFilePath)
'End If
oTable.DataSet.WriteXml(sFilePath, XmlWriteMode.WriteSchema)
End Sub
Public Sub SetValue(ByVal sKey As String, ByVal sValue As String)
Dim oDataRow As DataRow
Dim oDataRows As DataRow() = oTable.Select("key = '" & Replace(sKey, "'", "''") & "'")
If oDataRows.Length > 0 Then
oDataRows(0)("value") = sValue
Else
oDataRow = oTable.NewRow()
oDataRow("key") = sKey
oDataRow("value") = sValue
oTable.Rows.Add(oDataRow)
End If
End Sub
Public Function GetValue(ByVal sKey As String) As String
Dim oDataRows As DataRow() = oTable.Select("key = '" & Replace(sKey, "'", "''") & "'")
If oDataRows.Length > 0 Then
Return oDataRows(0)("value") & ""
End If
Return ""
End Function
Public Function GetValueDef(ByVal sKey As String, ByVal sDefVal As String) As String
Dim sValue As String = GetValue(sKey)
If sValue <> "" Then
Return sValue
End If
Return sDefVal
End Function
End Class
历史
- 2019年1月16日:初始版本