Scanner mit einer bestimmten IP-Adresse mithilfe von wia ansteuern.

  • VB.NET

Es gibt 5 Antworten in diesem Thema. Der letzte Beitrag () ist von dive26.

    Scanner mit einer bestimmten IP-Adresse mithilfe von wia ansteuern.

    Hallo :)

    Ich steuere einen Scanner in vb.net mithilfe der wia Technologie an. Das funktioniert soweit.
    In meiner Testumgebung gibt es allerdings nur einen Scanner. Im Echtbetrieb wird es mehrere Scanner im Netzwerk geben.

    Benutzt wia standardmäßig den Standarddrucker vom PC oder kann man sogar via code die ip-Adresse des gewünschten Druckers angeben?

    Hier der Code den ich benutze:

    VB.NET-Quellcode

    1. Public Sub configure(device As WIA.Device, dpi As Integer, colorMode As Integer)
    2. 'Dim device As WIA.Device = dialog.ShowSelectDevice(WIA.WiaDeviceType.ScannerDeviceType, True, True)
    3. device.Items(1).Properties("6146").Value = colorMode
    4. device.Items(1).Properties("6147").Value = dpi
    5. device.Items(1).Properties("6148").Value = dpi
    6. 'device.Items(1).Properties("CENTERED").Value = getde
    7. 'device.Properties("WIA_DPS_SHEET_FEEDER_REGISTRATION").Value = device.Items(1).Properties("CENTERED").Value
    8. 'device.Items(1).Properties("3078").Value = "CENTERED"
    9. End Sub
    10. Public Function pdfScannen(sPfad As String) As Boolean
    11. Try
    12. Dim d As New WIA.CommonDialog()
    13. Dim dev As WIA.Device = d.ShowSelectDevice(WIA.WiaDeviceType.ScannerDeviceType, False, False)
    14. configure(dev, 300, 1)
    15. Try
    16. For Each itm As WIA.Item In dev.Items
    17. Dim img As WIA.ImageFile = itm.Transfer()
    18. Dim buffer As Byte() = CType(img.FileData.BinaryData, Byte())
    19. Dim ms As MemoryStream = New MemoryStream(buffer)
    20. convertToPDF(ms, sPfad)
    21. Next
    22. Catch ex As Exception
    23. Return False
    24. End Try
    25. Return True
    26. Catch ex As Exception
    27. MsgBox("Scannen nicht möglich: " & ex.Message)
    28. Return False
    29. End Try
    30. End Function



    MfG
    Greenbear
    We are all suckerz for something ...
    Dim dev As WIA.Device = d.ShowSelectDevice(WIA.WiaDeviceType.ScannerDeviceType, False, False)


    Der Scanner-Auswahldialo kommt mit TRUE statt false - also wo man den WIA-Treiber auswählen kann. Egal ob lokal oder im Netzwerk.
    Ich habe bisher nur mit TWAIN gearbeitet, brauche aber diese WIA Ansteuerung auch demnächst. Hänge mich hier mal dran und probiere gleich was aus.

    convertToPDF(ms, sPfad)

    Mich würde auch der Code von convertToPDF interessieren ;)

    Liebe Grüße
    Roland Berghöfer

    Bei der Entwicklung meiner Anwendung(en) steht nicht "Code nach .NET Lehrbuch" im Vordergrund, sondern eine stabile und brauchbare Anwendung die der Anwender ordentlich verwenden kann. Usability für den Kunden und Supportbarkeit beim Kunden stehen an oberster Stelle. Das spiegelt sich auch in meinen Fragen und Antworten wider. Bitte verzeiht, dass meine VB.NET Quellcodes etwas VB6-lastig sind aber das ist für das funktionierende Endergebnis nicht wirklich relevant.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „dive26“ ()

    @GreenBear

    Ich habe Deinen Code einmal ausgetestet und (für meine Zwecke) angepasst.
    Mit meinem Code bekomme ich einen Scanner-Dialog, eine Fortschrittsanzeige und die Datei wird im JPG Format mit wählbarer Kompressionsrate gespeichert.
    (im Anhang auch der Screenshot vom Scannerdialog)

    Button und Picturebox zur Anzeige auf einer Form zum Aufruf des Scanvorganges

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    2. Me.Cursor = Cursors.WaitCursor
    3. Dim ScanDatei As String = "c:/demoscan.jpg"
    4. Dim Rueckgabewert As Boolean = WIAScan(ScanDatei, 100, 2, 50) '100dpi, graustufe und 50% JPG Qualität
    5. If Rueckgabewert = True Then
    6. Dim BildSpeicher As Image = System.Drawing.Image.FromFile(ScanDatei)
    7. PictureBox5.Image = New Bitmap(BildSpeicher)
    8. BildSpeicher.Dispose()
    9. End If
    10. Me.Cursor = Cursors.Default
    11. End Sub



    Modul mit den Funktionen

    VB.NET-Quellcode

    1. Imports System.IO
    2. Imports System.Drawing.Imaging
    3. Module mdl_scanner
    4. ''' <summary>
    5. ''' 1. zeigt den Scannerdialog zur Auswahl des Scanners
    6. ''' 2. Scannt in der angegebenen Auflösung und im angegebenen Farbmodus
    7. ''' 3. Speichert die Datei an den angegebenen Zielpfad als jpg-Datei mit angegebener Kompression
    8. ''' </summary>
    9. ''' <param name="WIAZieldatei"></param>
    10. ''' <param name="WIAResolution"></param>
    11. ''' <param name="WIAColorMode"></param>
    12. ''' <returns></returns>
    13. ''' <remarks></remarks>
    14. Public Function WIAScan(WIAZieldatei As String, WIAResolution As Integer, WIAColorMode As Integer, JPEGCompression As Integer) As Boolean
    15. Try
    16. Dim WIACommDlg As New WIA.CommonDialog()
    17. Dim WIADevice As WIA.Device = WIACommDlg.ShowSelectDevice(WIA.WiaDeviceType.ScannerDeviceType, True, False)
    18. WIADevice.Items(1).Properties("6146").Value = WIAColorMode '1=Farbe, 2=Graustufen, 4=schwarz/weiß
    19. WIADevice.Items(1).Properties("6147").Value = WIAResolution 'X-DPI
    20. WIADevice.Items(1).Properties("6148").Value = WIAResolution 'Y-DPI
    21. For Each WIAitem As WIA.Item In WIADevice.Items
    22. Dim WIAImage As WIA.ImageFile
    23. WIAImage = WIACommDlg.ShowTransfer(WIAitem, WIA.FormatID.wiaFormatJPEG, False)
    24. Dim BytePuffer As Byte() = CType(WIAImage.FileData.BinaryData, Byte())
    25. Dim MemStream As MemoryStream = New MemoryStream(BytePuffer)
    26. Dim BildZwischenspeicher As Image = Image.FromStream(MemStream)
    27. Dim KleinesBild As New Bitmap(BildZwischenspeicher)
    28. If File.Exists(WIAZieldatei) Then File.Delete(WIAZieldatei)
    29. SaveJpeg(WIAZieldatei, KleinesBild, JPEGCompression)
    30. Return True
    31. Next
    32. Catch ex As Exception
    33. MsgBox("Scannen nicht möglich: " & ex.Message)
    34. Return False
    35. End Try
    36. Return False
    37. End Function
    38. ''' <summary>
    39. ''' Speichert ein Image als .JPEG Datei mit angegebener Qualität von 0 bis 100 (100=beste Qualität)
    40. ''' </summary>
    41. ''' <param name="path"></param>
    42. ''' <param name="img"></param>
    43. ''' <param name="quality"></param>
    44. ''' <remarks></remarks>
    45. Private Sub SaveJpeg(ByVal path As String, ByVal img As Image, ByVal quality As Long)
    46. Dim qualityParam As New EncoderParameter(Encoder.Quality, quality)
    47. Dim jpegCodec As ImageCodecInfo = GetEncoderInfo("image/jpeg")
    48. Dim encoderParams As New EncoderParameters(1)
    49. encoderParams.Param(0) = qualityParam
    50. img.Save(path, jpegCodec, encoderParams)
    51. End Sub
    52. Private Function GetEncoderInfo(ByVal mimeType As String) As ImageCodecInfo
    53. Dim codecs As ImageCodecInfo() = ImageCodecInfo.GetImageEncoders()
    54. For i As Integer = 0 To codecs.Length - 1
    55. If (codecs(i).MimeType = mimeType) Then
    56. Return codecs(i)
    57. End If
    58. Next i
    59. Return Nothing
    60. End Function
    61. End Module

    Bilder
    • 17102018202942.jpg

      66,85 kB, 469×308, 5 mal angesehen
    Liebe Grüße
    Roland Berghöfer

    Bei der Entwicklung meiner Anwendung(en) steht nicht "Code nach .NET Lehrbuch" im Vordergrund, sondern eine stabile und brauchbare Anwendung die der Anwender ordentlich verwenden kann. Usability für den Kunden und Supportbarkeit beim Kunden stehen an oberster Stelle. Das spiegelt sich auch in meinen Fragen und Antworten wider. Bitte verzeiht, dass meine VB.NET Quellcodes etwas VB6-lastig sind aber das ist für das funktionierende Endergebnis nicht wirklich relevant.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „dive26“ ()

    Hallo nochmal. Nun ist es 20 nach Mitternacht und ich habe nochmals alles überarbeitet.
    Bevor ich zu Bett gehe, hier nochmals mein Ergebnis.

    Ich habe nun ein Modul (ja ja, keine Klasse) geschrieben das folgendes für mich erledigen soll:

    1. Scanner auswählen (UI-Dialog)
    2. Scanndialog (UI)
    3. Fortschrittsanzeige
    4. Scan in Graustufen und falls das Bild breiter als X (in meinem Fall 1200) ist, dann wird es automatisch verkleinert
    5. Das Bild wird mit der gewählten Kompressionsrate abgespeichert
    6. DPI wird nicht vorgegeben, da diese in der UI (Punkt2) jederzeit überschrieben und gewählt werden kann/könnte

    Mein Anwendungsbereich: Archivierung von Lieferscheinen - Graustufen und eine Maximalbildgröße für Lesbarkeit und kleinster Dateigröße.


    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    2. Me.Cursor = Cursors.WaitCursor
    3. Dim ScanDatei As String = Path.Combine(BONitERP2_DatenOrdner, "demoscan.jpg")
    4. Dim Rueckgabewert As Boolean = WIAScan(ScanDatei, 2, 50)) 'Graustufen und 50% JPG Qualität
    5. If Rueckgabewert = True Then
    6. Dim BildSpeicher As Image = System.Drawing.Image.FromFile(ScanDatei)
    7. PictureBox5.Image = New Bitmap(BildSpeicher)
    8. BildSpeicher.Dispose()
    9. End If
    10. Me.Cursor = Cursors.Default
    11. End Sub


    VB.NET-Quellcode

    1. Imports System.IO
    2. Imports System.Drawing.Imaging
    3. Module mdl_scanner
    4. ''' <summary>
    5. ''' 1. zeigt den Scannerdialog zur Auswahl des Scanners
    6. ''' 2. Scannt in der angegebenen Auflösung und im angegebenen Farbmodus
    7. ''' 3. Speichert die Datei an den angegebenen Zielpfad als jpg-Datei mit angegebener Kompression
    8. ''' </summary>
    9. ''' <param name="WIAZieldatei"></param>
    10. ''' <param name="WIAColorMode"></param>
    11. ''' <returns></returns>
    12. ''' <remarks></remarks>
    13. Public Function WIAScan(WIAZieldatei As String, WIAColorMode As Integer, JPEGCompression As Long, Optional MaxBildBreite As Integer = 1200) As Boolean
    14. Try
    15. Dim WIACommDlg As New WIA.CommonDialog()
    16. Dim WIAImage As WIA.ImageFile
    17. WIAImage = WIACommDlg.ShowAcquireImage(WIA.WiaDeviceType.ScannerDeviceType, WIAColorMode, WIA.WiaImageBias.MinimizeSize, WIA.FormatID.wiaFormatJPEG, True, True, False)
    18. Dim BytePuffer As Byte() = CType(WIAImage.FileData.BinaryData, Byte())
    19. Dim MemStream As MemoryStream = New MemoryStream(BytePuffer)
    20. Dim BildZwischenspeicher As Image = Image.FromStream(MemStream)
    21. 'Hier könnte man das Bild noch verkleinern ... new Bitmap(image, neue Parameter)
    22. Dim BildBreite As Integer = BildZwischenspeicher.Width
    23. Dim BildHoehe As Integer = BildZwischenspeicher.Height
    24. Dim Ratio As Double = 0
    25. If BildZwischenspeicher.Width > 1200 Then
    26. 'auf MaxBildBreite verkleinern
    27. BildBreite = MaxBildBreite
    28. Ratio = 100 / BildZwischenspeicher.Width * BildBreite
    29. BildHoehe = CInt(BildZwischenspeicher.Height / 100 * Ratio)
    30. End If
    31. Dim KleinesBild As New Bitmap(BildZwischenspeicher, BildBreite, BildHoehe)
    32. If File.Exists(WIAZieldatei) Then File.Delete(WIAZieldatei)
    33. SaveJpeg(WIAZieldatei, KleinesBild, JPEGCompression)
    34. Return True
    35. Catch ex As Exception
    36. If ex.Message.Contains("0x80210015") Then
    37. MessageBox.Show("Kein WIA-fähiger Scanner auf Ihrem System gefunden!", "Scannen nicht möglich", MessageBoxButtons.OK, MessageBoxIcon.Stop)
    38. Else
    39. MessageBox.Show("Fehler beim Scannen: " & vbCrLf & ex.Message & vbCrLf & Err.Number.ToString, "Allgemeiner Scannerfeler", MessageBoxButtons.OK, MessageBoxIcon.Stop)
    40. End If
    41. Return False
    42. End Try
    43. Return False
    44. End Function
    45. ''' <summary>
    46. ''' Speichert ein Image als .JPEG Datei mit angegebener Qualität von 0 bis 100 (100=beste Qualität)
    47. ''' </summary>
    48. ''' <param name="path"></param>
    49. ''' <param name="img"></param>
    50. ''' <param name="quality"></param>
    51. ''' <remarks></remarks>
    52. Private Sub SaveJpeg(ByVal path As String, ByVal img As Image, ByVal quality As Long)
    53. Dim qualityParam As New EncoderParameter(Encoder.Quality, quality)
    54. Dim jpegCodec As ImageCodecInfo = GetEncoderInfo("image/jpeg")
    55. Dim encoderParams As New EncoderParameters(1)
    56. encoderParams.Param(0) = qualityParam
    57. img.Save(path, jpegCodec, encoderParams)
    58. End Sub
    59. Private Function GetEncoderInfo(ByVal mimeType As String) As ImageCodecInfo
    60. Dim codecs As ImageCodecInfo() = ImageCodecInfo.GetImageEncoders()
    61. For i As Integer = 0 To codecs.Length - 1
    62. If (codecs(i).MimeType = mimeType) Then
    63. Return codecs(i)
    64. End If
    65. Next i
    66. Return Nothing
    67. End Function
    68. End Module

    Liebe Grüße
    Roland Berghöfer

    Bei der Entwicklung meiner Anwendung(en) steht nicht "Code nach .NET Lehrbuch" im Vordergrund, sondern eine stabile und brauchbare Anwendung die der Anwender ordentlich verwenden kann. Usability für den Kunden und Supportbarkeit beim Kunden stehen an oberster Stelle. Das spiegelt sich auch in meinen Fragen und Antworten wider. Bitte verzeiht, dass meine VB.NET Quellcodes etwas VB6-lastig sind aber das ist für das funktionierende Endergebnis nicht wirklich relevant.
    Danke @dive26 . Das mit dem Dialogfenster wusste ich schon.

    Ich möchte benutuzerabhängig (mithilfe einer XML-Datei oder der DB) einen bestimmten Scanner aufrufen ohne jedes Mal das Dialogfeld zu sehen. Deswegen die Frage nach dem Scannen über die IP-Adresse.


    Aber für deine Mühen hast du dir trotzdem den Code für convertToPDF verdient :D
    Ich benutze dafür die DLL von PdfSharp:

    VB.NET-Quellcode

    1. Public Sub convertToPDF(ms As Stream, sPfad As String)
    2. Dim pdf As New PdfSharp.Pdf.PdfDocument
    3. Dim page As PdfSharp.Pdf.PdfPage = pdf.AddPage
    4. Dim gfx As XGraphics = XGraphics.FromPdfPage(page)
    5. drawImage(gfx, ms, 0, 0, 605, 850)
    6. pdf.Save(sPfad)
    7. 'Process.Start(sPfad)
    8. End Sub
    9. Public Sub drawImage(gfx As XGraphics, ms As Stream, x As Integer, y As Integer, width As Integer, height As Integer)
    10. Dim image As XImage = XImage.FromStream(ms)
    11. gfx.DrawImage(image, x, y, width, height)
    12. End Sub
    We are all suckerz for something ...
    @GreenBear
    Wenn ich das richtig interpretiere, wird lediglich ein Bild ins PDF gespeichert? Also keine echte OCR.
    Das kann ich dann ja auch mit meiner VPE Komponente machen. Danke für den Tipp.

    Du könnstest einmalig mit ShowSelectDevice den Scanner wählen lassen und die Device-ID dann speichern.
    Wenn Du dann den Scanner ansprichst, dann gleich mit der Device-ID.

    VB.NET-Quellcode

    1. Dim WIACommDlg As New WIA.CommonDialog()
    2. Dim SelectedWIADevice As WIA.Device = WIACommDlg.ShowSelectDevice
    3. MsgBox("Device-ID zur Verwendung im nächsten DIREKTEN Aufruf des WIA Gerätes: " + SelectedWIADevice.DeviceID)

    Liebe Grüße
    Roland Berghöfer

    Bei der Entwicklung meiner Anwendung(en) steht nicht "Code nach .NET Lehrbuch" im Vordergrund, sondern eine stabile und brauchbare Anwendung die der Anwender ordentlich verwenden kann. Usability für den Kunden und Supportbarkeit beim Kunden stehen an oberster Stelle. Das spiegelt sich auch in meinen Fragen und Antworten wider. Bitte verzeiht, dass meine VB.NET Quellcodes etwas VB6-lastig sind aber das ist für das funktionierende Endergebnis nicht wirklich relevant.