sabato 9 novembre 2019

.Net - scansione dei documenti tramite Scanner VB.Net e C# - seconda parte

Si riporta l'articolo scritto per il sito https://www.iprogrammatori.it/articoli/microsoft-net-framework/art_net-scansione-dei-documenti-tramite-scanner-seconda-parte_1644.aspx

Riprendiamo l’articolo riguardante la scansione dei documenti tramite la tecnologia .Net con i linguaggi di programmazione VB.Net e C# qui https://www.iprogrammatori.it/articoli/microsoft-net-framework/art_net-effettuare-la-scansione-dei-documenti-tramite-scanner-prima-parte_1643.aspx la prima parte.
In questa seconda ed ultima parte, vedremo come effettuare la scansione, salvare il file e visualizzare il risultato nella form e precisamente nel controllo picturebox.
Si apre il progetto creato in precedenza, e dobbiamo scrivere le funzione per impostare il tipo di scansione e soprattutto il settaggio delle dimensione della nostra immagine.

Stesura del codice

Passiamo in visualizzazione codice, e nella classe della form, scriviamo la funzione con il quale andremo ad impostare alcuni parametri con tanto di valore per la gestione della scansione.
Le proprietà permetteranno all’oggetto per la scansione di effettuare la scansione in base alle informazioni che gli forniamo, come la grandezza, il formato, ed altro ancora per l’area in cui dovrà rilevare il foglio messo sopra allo scanner.
Questa funzione avrà il compito di impostare un valore a determinate proprietà e sarà richiamata da un’altra funzione.
Qui di seguito la dichiarazione per entrambi i linguaggi.


VB.Net

Private Shared Sub SetWIAProperty(ByVal properties As IProperties, ByVal propName As Object, ByVal propValue As Object)

        Dim prop As [Property] = properties.Item(propName)

        prop.let_Value(propValue)

    End Sub

 

C#

private static void SetWIAProperty(IProperties properties, object propName, object propValue)

        {

            Property prop = properties.get_Item(ref propName);

            prop.set_Value(ref propValue);

        }


Ora dovremmo creare la funzione, che richiama quella precedente per impostare i vari parametri di scansione.
La funzione che andremo a scrivere permetterà di impostare la risoluzione, la larghezza ed altre utili informazioni per gestire al meglio lo scanner.
La funzione avrà dei parametri, tra questi l’oggetto di tipo “IItem” che è l’interfaccia per gestire lo scanner con il quale effettueremo la scansione.
Qui di seguito si riporta la creazione della funzione, con il quale andremo ad impostare i vari parametri.
La dichiarazione delle suddette operazioni per entrambi i linguaggi di programmazione.



VB.Net

Private Shared Sub AdjustScannerSettings(ByVal scannnerItem As IItem, ByVal scanResolutionDPI As Integer, ByVal scanStartLeftPixel As Integer, ByVal scanStartTopPixel As Integer, ByVal scanWidthPixels As Integer, ByVal scanHeightPixels As Integer, ByVal brightnessPercents As Integer, ByVal contrastPercents As Integer, ByVal colorMode As Integer)

        Const WIA_SCAN_COLOR_MODE As String = "6146"

        Const WIA_HORIZONTAL_SCAN_RESOLUTION_DPI As String = "6147"

        Const WIA_VERTICAL_SCAN_RESOLUTION_DPI As String = "6148"

        Const WIA_HORIZONTAL_SCAN_START_PIXEL As String = "6149"

        Const WIA_VERTICAL_SCAN_START_PIXEL As String = "6150"

        Const WIA_HORIZONTAL_SCAN_SIZE_PIXELS As String = "6151"

        Const WIA_VERTICAL_SCAN_SIZE_PIXELS As String = "6152"

        Const WIA_SCAN_BRIGHTNESS_PERCENTS As String = "6154"

        Const WIA_SCAN_CONTRAST_PERCENTS As String = "6155"

        SetWIAProperty(scannnerItem.Properties, WIA_HORIZONTAL_SCAN_RESOLUTION_DPI, scanResolutionDPI)

        SetWIAProperty(scannnerItem.Properties, WIA_VERTICAL_SCAN_RESOLUTION_DPI, scanResolutionDPI)

        SetWIAProperty(scannnerItem.Properties, WIA_HORIZONTAL_SCAN_START_PIXEL, scanStartLeftPixel)

        SetWIAProperty(scannnerItem.Properties, WIA_VERTICAL_SCAN_START_PIXEL, scanStartTopPixel)

        SetWIAProperty(scannnerItem.Properties, WIA_HORIZONTAL_SCAN_SIZE_PIXELS, scanWidthPixels)

        SetWIAProperty(scannnerItem.Properties, WIA_VERTICAL_SCAN_SIZE_PIXELS, scanHeightPixels)

        SetWIAProperty(scannnerItem.Properties, WIA_SCAN_BRIGHTNESS_PERCENTS, brightnessPercents)

        SetWIAProperty(scannnerItem.Properties, WIA_SCAN_CONTRAST_PERCENTS, contrastPercents)

        SetWIAProperty(scannnerItem.Properties, WIA_SCAN_COLOR_MODE, colorMode)

    End Sub

 

C#

 

  private static void AdjustScannerSettings(IItem scannnerItem, int scanResolutionDPI, int scanStartLeftPixel, int scanStartTopPixel, int scanWidthPixels, int scanHeightPixels, int brightnessPercents, int contrastPercents, int colorMode)

        {

            const string WIA_SCAN_COLOR_MODE = "6146";

            const string WIA_HORIZONTAL_SCAN_RESOLUTION_DPI = "6147";

            const string WIA_VERTICAL_SCAN_RESOLUTION_DPI = "6148";

            const string WIA_HORIZONTAL_SCAN_START_PIXEL = "6149";

            const string WIA_VERTICAL_SCAN_START_PIXEL = "6150";

            const string WIA_HORIZONTAL_SCAN_SIZE_PIXELS = "6151";

            const string WIA_VERTICAL_SCAN_SIZE_PIXELS = "6152";

            const string WIA_SCAN_BRIGHTNESS_PERCENTS = "6154";

            const string WIA_SCAN_CONTRAST_PERCENTS = "6155";

            SetWIAProperty(scannnerItem.Properties, WIA_HORIZONTAL_SCAN_RESOLUTION_DPI, scanResolutionDPI);

            SetWIAProperty(scannnerItem.Properties, WIA_VERTICAL_SCAN_RESOLUTION_DPI, scanResolutionDPI);

            SetWIAProperty(scannnerItem.Properties, WIA_HORIZONTAL_SCAN_START_PIXEL, scanStartLeftPixel);

            SetWIAProperty(scannnerItem.Properties, WIA_VERTICAL_SCAN_START_PIXEL, scanStartTopPixel);

            SetWIAProperty(scannnerItem.Properties, WIA_HORIZONTAL_SCAN_SIZE_PIXELS, scanWidthPixels);

            SetWIAProperty(scannnerItem.Properties, WIA_VERTICAL_SCAN_SIZE_PIXELS, scanHeightPixels);

            SetWIAProperty(scannnerItem.Properties, WIA_SCAN_BRIGHTNESS_PERCENTS, brightnessPercents);

            SetWIAProperty(scannnerItem.Properties, WIA_SCAN_CONTRAST_PERCENTS, contrastPercents);

            SetWIAProperty(scannnerItem.Properties, WIA_SCAN_COLOR_MODE, colorMode);

        }

Terminata la creazione di queste due funzioni, che hanno l’obiettivo di impostare le informazioni per effettuare una corretta scansione del documento, non resta che creare una funzione, che sarà richiamato dal altra funzione che poi sarà quella del pulsante di scansione, per effettuare la vera scansione.
Questa funzione, avrà un oggetto di tipo “Wia.CommonDialog” con il quale andremo ad effettuare l’avvio della scansione.
Mentre l’oggetto di tipo “DeviceInfo” tramite il metodo “Connect” sarà quello di gestire il dispositivo hardware, infatti passando alle precedenti funzioni la proprietà “Item” si andrà ad impostare la modalità con il quale faremo la scansione.
Tramite il metodo “ShowTransfer” della classe Wia.CommonDialog” verrà avviata la scansione, passando come parametro, l’oggetto Item, il formato di scansione in base al valore selezionato nella casella combinata, ed il risultato della scansione sarà un oggetto di tipo “ImageFile”.
Con il quale salveremo i file sul nostro pc per poi farlo vedere nel controllo Picturebox.
Nella gestione delle eccezioni in base al codice di errore andremo a visualizzare un messaggio personalizzato.
Qui di seguito la dichiarazione delle suddette operazioni.




VB.Net

Public Function ScansionaFormato(ByVal device As DeviceInfo, ByVal formato As String) As ImageFile

        Dim deviceScanner = device.Connect()

        Dim dlg As WIA.CommonDialog = New WIA.CommonDialog()

        Dim item = deviceScanner.Items(1)

        Dim resolution As Integer = 100

        Dim width_pixel As Integer = 1250

        Dim height_pixel As Integer = 1700

        Dim color_mode As Integer = 0

 

 

        Try

            AdjustScannerSettings(item, resolution, 10, 10, 600, 600, 100, 100, color_mode)

            Dim scanRisultato As Object = Nothing

 

            If formato.ToLower() = "jpg" Then

                scanRisultato = dlg.ShowTransfer(item, WIA.FormatID.wiaFormatJPEG, True)

            ElseIf formato.ToLower() = "png" Then

                scanRisultato = dlg.ShowTransfer(item, WIA.FormatID.wiaFormatPNG, True)

            Else

                scanRisultato = dlg.ShowTransfer(item, WIA.FormatID.wiaFormatTIFF, True)

            End If

 

            If scanRisultato IsNot Nothing Then

                Dim imageFile = CType(scanRisultato, ImageFile)

                Return imageFile

            End If

 

        Catch ex As COMException

            Dim errorCode As UInteger = CUInt(ex.ErrorCode)

 

            If errorCode = &H80210006 Then

                MessageBox.Show("Scanner non pronto oppure impegnato")

            ElseIf errorCode = &H80210064 Then

                MessageBox.Show("Annullata la scansione")

            Else

                MessageBox.Show("Errore: " & ex.Message)

            End If

        End Try

 

        Return New ImageFile()

    End Function

 

 

 

C#

 

  public ImageFile ScansionaFormato(DeviceInfo device, string formato)

        {

            //Mi connetto al dispositivo

            var deviceScanner =  device.Connect();

               int resolution = 100;

          int width_pixel = 1250;

          int height_pixel = 1700;

          int color_mode = 0;

            //Visualizzo la dialogo

            WIA.CommonDialog dlg = new WIA.CommonDialog();

 

            var item = deviceScanner.Items[1];

 

            try

            {

                //Imposto le dimensioni di scansione

                AdjustScannerSettings(item, resolution, 10, 10, 600, 600,  100,100, color_mode);

 

 

                object scanRisultato = null;

                if (formato.ToLower() == "jpg")

                {

                    scanRisultato = dlg.ShowTransfer(item, WIA.FormatID.wiaFormatJPEG, true);

                }

                else if (formato.ToLower() == "png")

                {

                    scanRisultato = dlg.ShowTransfer(item, WIA.FormatID.wiaFormatPNG, true);

                }

                else

                {

                    scanRisultato = dlg.ShowTransfer(item, WIA.FormatID.wiaFormatTIFF, true);

                }

               

 

                if (scanRisultato != null)

                {

                    var imageFile = (ImageFile)scanRisultato;

 

                    //ritorno oggetto immagine

                    return imageFile;

                }

            }

            catch (COMException ex)

            {

 

              

                uint errorCode = (uint)ex.ErrorCode;

 

               

                if (errorCode == 0x80210006)

                {

                    MessageBox.Show("Scanner non pronto oppure impegnato");

                }

                else if (errorCode == 0x80210064)

                {

                    MessageBox.Show("Annullata la scansione");

                }

                else

                {

                    MessageBox.Show("Errore: " + ex.Message);

                }

            }

 

            return new ImageFile();

        }
Ora non ci resta creare la funzione che sarà richiamato dal pulsante di scansione, questa funzione richiama la precedente funzione, passando come parametro, lo scanner selezionato, il formato del file immagine, ed altre informazioni utili, inoltre verrà salvata l’immagine e visualizzata in anteprima.
Qui di seguito la dichiarazione del codice.
 

VB.Net

Private Function Scansiona() As Boolean

        Dim risultatoScansione As Boolean = False

 

        Try

            Dim deviceManager = New DeviceManager()

            Dim device As DeviceInfo = Nothing

 

            If listScanner.SelectedIndex < 0 Then

                MessageBox.Show("Selezionare un dispositivo valido", "Esempio Scanner", MessageBoxButtons.OK, MessageBoxIcon.Warning)

                Return False

            End If

 

            For i As Integer = 1 To deviceManager.DeviceInfos.Count

 

                If deviceManager.DeviceInfos(i).Type <> WiaDeviceType.ScannerDeviceType Then

                    Continue For

                End If

 

                If deviceManager.DeviceInfos(i).Properties("Name").Value.ToString() = listScanner.SelectedItem.ToString() Then

                    device = deviceManager.DeviceInfos(i)

                    Exit For

                End If

            Next

 

            If device Is Nothing Then

                MessageBox.Show("Selezionare un dispositivo valido", "Esempio Scanner", MessageBoxButtons.OK, MessageBoxIcon.Warning)

                Return False

            End If

 

            Dim ImmagineScansionata As ImageFile = New ImageFile()

            Dim EstensioneImmagine As String = cmbFormato.SelectedItem.ToString()

            ImmagineScansionata = ScansionaFormato(device, EstensioneImmagine)

            risultatoScansione = True

            Dim Percorso = Path.Combine("D:\Test." & EstensioneImmagine)

 

            If File.Exists(Percorso) Then

                File.Delete(Percorso)

            End If

 

            ImmagineScansionata.SaveFile(Percorso)

            pictureBox1.Image = New System.Drawing.Bitmap(Percorso)

            Return risultatoScansione

        Catch ex As System.Exception

            MessageBox.Show(ex.Message)

            Return risultatoScansione

        End Try

    End Function

 

 

C#

 

private bool Scansiona()

        {

            bool risultatoScansione = false;

            try

            {

 

                var deviceManager = new DeviceManager();

                DeviceInfo device = null;

                if (listScanner.SelectedIndex < 0)

                {

                    MessageBox.Show("Selezionare un dispositivo valido", "Esempio Scanner", MessageBoxButtons.OK, MessageBoxIcon.Warning);

                    return false;

                }

 

                for (int i = 1; i <= deviceManager.DeviceInfos.Count; i++)

                {

 

                    if (deviceManager.DeviceInfos[i].Type != WiaDeviceType.ScannerDeviceType)

                    {

                        continue;

                    }

 

                    if (deviceManager.DeviceInfos[i].Properties["Name"].get_Value().ToString() == listScanner.SelectedItem.ToString())

                    {

                        device = deviceManager.DeviceInfos[i];

                        break;

                    }

 

                   

 

                }

                if (device == null)

                {

                    MessageBox.Show("Selezionare un dispositivo valido", "Esempio Scanner", MessageBoxButtons.OK, MessageBoxIcon.Warning);

                    return false;

                }

                ImageFile ImmagineScansionata = new ImageFile();

 

                string EstensioneImmagine = cmbFormato.SelectedItem.ToString();

             ImmagineScansionata =    ScansionaFormato(device, EstensioneImmagine);

                

 

                risultatoScansione = true;

                var Percorso = Path.Combine("D:\\Test." + EstensioneImmagine);

 

                if (File.Exists(Percorso))

                {

                    File.Delete(Percorso);

                }

 

                ImmagineScansionata.SaveFile(Percorso);

 

                pictureBox1.Image = new Bitmap(Percorso);

                return risultatoScansione;

            }

            catch (System.Exception ex)

            {

                MessageBox.Show(ex.Message);

                return risultatoScansione;

            }

       

       

       

        }

Ora dobbiamo richiamare questa funzione dall’evento click del pulsante, passiamo in visualizzazione grafica del nostro progetto, e nella form, facciamo doppio click sul pulsante, in modo che passiamo in modalità codice dell’evento click.
Nell’evento click, verrà richiamata la funzione illustra in precedenza.


VB.Net

Private Sub BtnScansiona_Click(sender As Object, e As EventArgs) Handles BtnScansiona.Click

        If String.IsNullOrEmpty(txtPercorsoNomeFile.Text) Then

            MessageBox.Show("Inserire il percorso e nome file", "Scanner", MessageBoxButtons.OK, MessageBoxIcon.Warning)

            Return

        End If

 

        If Scansiona() = True Then

            MessageBox.Show("Scansione effettuata con successo.", "Scanner", MessageBoxButtons.OK, MessageBoxIcon.Information)

        End If

 

    End Sub

 

 

C#

private void BtnScansiona_Click(object sender, EventArgs e)

        {

            if (String.IsNullOrEmpty(txtPercorsoNomeFile.Text))

            {

                MessageBox.Show("Inserire il percorso e nome file", "Scanner", MessageBoxButtons.OK, MessageBoxIcon.Warning);

                return;

            }

            if (Scansiona() == true)

                MessageBox.Show("Scansione avvenuta con successo.", "Scanner", MessageBoxButtons.OK, MessageBoxIcon.Information);

          

        }

Manca solo un piccolo dettaglio, quello di abbinare al click del pulsante per il salvataggio del file, il percorso e nome del file.
Qui l’evento click del pulsante, per visualizzare la finestra di dialogo per selezionare la cartella e dare il nome del file immagine relativo alla scansione.


VB.Net

Private Sub btnSalva_Click(ByVal sender As Object, ByVal e As EventArgs)

        Dim DlgpercorsoNomeFile As SaveFileDialog = New SaveFileDialog()

 

        If DlgpercorsoNomeFile.ShowDialog() = System.Windows.Forms.DialogResult.OK Then

            txtPercorsoNomeFile.Text = DlgpercorsoNomeFile.FileName

        End If

    End Sub

 

C#

  private void btnSalva_Click(object sender, EventArgs e)

        {

            SaveFileDialog DlgpercorsoNomeFile = new SaveFileDialog();

            if (DlgpercorsoNomeFile.ShowDialog() == System.Windows.Forms.DialogResult.OK)

            {

                txtPercorsoNomeFile.Text = DlgpercorsoNomeFile.FileName;

            }

        }




Conclusioni

Ora non ci resta che testare il nostro applicativo, collegando al nostro pc uno scanner, ed effettuare la scansione, noteremo come al termine verrà mostrato il file relativo alla scansione.
L’articolo ha voluto fornire al lettore, le conoscenze per dotare i propri applicazioni, Windows Application, più che altro, ma anche Web application, la gestione dello scanner.
Strumento che può tornare molto utile nei progetto nel quale si devono gestire documenti, e quindi applicazioni di gestione documentale. -
Naturalmente può essere anche un punto di partenza per creare programma dedicati alla scansione, quindi non nei propri progetti, ma un vero software.

Nessun commento: