Leggere codici a barre e QR code

8 marzo 2017

Il progetto Mobile Vision raccoglie una serie di strumenti, messi a disposizione degli sviluppatori Android, finalizzati all’estrazione di informazioni da immagini che raffigurano volti di persone, codici a barre o testo. In questo tutorial, inizieremo a conoscere un suo set di funzionalità, le BarCode API, specializzate nell’acquisizione dei dati memorizzati in forma di codici a barre di vari formati. Questi ultimi sono presenti in molti oggetti quotidiani, e vengono spesso utilizzati in applicazioni di natura logistica e commerciale. Come vedremo, il tutto viene offerto da Google con una sintassi funzionale e snella.

Decodifica di codici a barre

Le Barcode API sono compatibili con tutti i formati più comuni di codici a barre come gli EAN-13, codici formati da 13 cifre che siamo soliti trovare sulle confezioni di oggetti che acquistiamo:

Figura 1. Codice a barre in formato EAN-13 (click per ingrandire)

Codice a barre in formato EAN-13

Sempre più utilizzati sono inoltre i codici QR, di natura bidimensionale, ormai molto diffusi come metodo di distribuzione di informazioni di contatto in formato VCard, URL, indirizzi e-mail o altro.

Figura 2. QR code (click per ingrandire)

QR code

I codici da interpretare possono essere rilevati in vari modi – da immagini, da foto scattate o da riprese effettuate con la fotocamera – ma essenzialmente i passi da percorrere sono, grosso modo, sempre gli stessi:

  • istanzieremo un BarcodeDetector, che inizializzeremo specificando quali tipi di codici siamo interessati a rilevare: ogni codice è riconoscibile mediante le costanti raccolte nella classe Barcode;
  • controlleremo che il detector sia utilizzabile tramite il metodo isOperational, altrimenti non potremo procedere;
  • predisporremo la sorgente dati definendo le immagini da utilizzare o stabilendo connessioni con l’hardware che ci interessa;
  • elaboreremo i risultati ottenuti via via verificando il contenuto degli oggetti BarCode restituiti.

Nell’esempio che segue realizziamo un piccolo lettore di codici a barre che sfrutterà le riprese live raccolte dalla fotocamera, mentre il Detector le vaglierà il più velocemente possibile alla ricerca di codici a barre.

Esempio: lettore di codici a barre

Per poter svolgere il nostro esempio dovremo, per prima cosa, impostare alcuni aspetti della configurazione del progetto:

  • nel file build.gradle del modulo applicativo richiediamo l’utilizzo dei Google Play Services, o almeno la porzione relativa alle API di Mobile Vision:
    dependencies {
        ...
        ...
        compile 'com.google.android.gms:play-services-vision:10.0.0'
    }
    

    sarà necessario, al momento dell’utilizzo, indicare la versione dei Google Play Services che si desidera integrare, purchè questa non sia inferiore alla 7.8;

  • nel file AndroidManifest.xml inseriremo un campo meta-data che servirà ad ottenere le dipendenze necessarie all’interpretazione dei codici a barre, e la permission relativa all’utilizzo della fotocamera di cui avremo bisogno in questo esempio:
  • <meta-data android:name="com.google.android.gms.vision.DEPENDENCIES" android:value="barcode"/>
    <uses-permission android:name="android.permission.CAMERA" />
    

Il layout della nostra applicazione è costituito da una SurfaceView (la superficie in cui proietteremo quanto rilevato dalla fotocamera in tempo reale), una TextView con sfondo celeste in cui vedremo apparire i codici di volta in volta rilevati dal Detector, ed un pulsante con il semplice compito di pulire il contenuto della TextView:

Figura 3. L’app in funzione (click per ingrandire)

L'app in funzione

L’immagine mostra l’app in funzione: nella SurfaceView vediamo inquadrato un codice a barre presente su una bottiglia e la TextView sottostante dimostra come sia stato correttamente riconosciuto.

Il funzionamento ruota attorno a tre componenti: la SurfaceView, il BarcodeDetector ed un oggetto CameraSource, altra classe offerta da Vision che gestisce la fotocamera congiuntamente al BarcodeDetector. Li inizializziamo tutti nel metodo onCreate:

public class MainActivity extends AppCompatActivity {
    ...
    ...
    private BarcodeDetector detector;
    private SurfaceView surfaceView;
    private CameraSource cameraSource;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ...
        ...
        surfaceView = (SurfaceView) findViewById(R.id.surface_view);
        message = (TextView) findViewById(R.id.barcode_text);

	// chiediamo di individuare QR code e EAN 13
        detector = new BarcodeDetector.Builder(getApplicationContext())
                .setBarcodeFormats(Barcode.QR_CODE | Barcode.EAN_13)
                .build();

	// verifichiamo che BarcodeDetector sia operativo
        if (!detector.isOperational()) {
            exit("Detector di codici a barre non attivabile");
            return;
        }

	// istanziamo un oggetto CameraSource collegata al detector
        cameraSource = new CameraSource
                .Builder(this, detector)
                .setAutoFocusEnabled(true)
                .build();

	// gestione delle fasi di vita della SurfaceView
        surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                activateCamera();
            }

            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            }

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                cameraSource.stop();
            }
        });

        detector.setProcessor(new Detector.Processor<Barcode>() {
            @Override
            public void release() {
            }

            @Override
            public void receiveDetections(Detector.Detections<Barcode> detections) {
                final SparseArray<Barcode> items = detections.getDetectedItems();

                if (items.size() != 0)
                    runOnUiThread(new Runnable() {
                        public void run() {
                            String barcode="Rilevato: "+items.valueAt(0).displayValue;
                            message.setText(barcode);
                        }
                    });

            }
        });

    }

    ...

}

Il metodo receiveDetections viene definito in un Processor ed è il punto in cui vengono fornite le informazioni decodificate dal Detector. Se lo SparseArray restituito ha dimensione maggiore di zero, significa che abbiamo riscontrato almeno un risultato. Si noti che receiveDetections lavora su un thread secondario e, per questo motivo, aggiorniamo la TextView utilizzando il metodo runOnUiThread, con cui impacchettiamo operazioni da svolgere sul main thread, ove viene elaborata l’interazione con l’interfaccia utente.

L’attivazione della fotocamera avviene nel nostro metodo activateCamera, in cui gestiamo le permission in modalità dinamica visto che l’autorizzazione necessaria che ci attendiamo dall’utente è tra quelle considerate dangerous, ossia potenzialmente nocive per la privacy dell’utente:

private void activateCamera() {

	// verifichiamo che sia stata concessa la permission CAMERA

        if (ActivityCompat.checkSelfPermission(this, NEEDED_PERMISSION) != PackageManager.PERMISSION_GRANTED) {

            if (ActivityCompat.shouldShowRequestPermissionRationale(this, NEEDED_PERMISSION)) {
                /*
 		 *   OMISSIS: mostriamo finestra di dialogo che fornisce ulteriori  
 		 *            spiegazioni sulla permission richiesta
 		 */
            } else {
                ActivityCompat.requestPermissions(this, new String[]{NEEDED_PERMISSION}, REQUEST_ID);

            }
        } else {
            try {
                cameraSource.start(surfaceView.getHolder());
            } catch (IOException e) {
                exit("Errore nell'avvio della fotocamera");
            }
        }

    }

L’esempio può essere raffinato in base alle proprie necessità, soprattutto sfruttando in maniera più articolata i codici a barre recuperati, ad esempio impiegandoli in ricerche su database locali o remoti. L’attività di estrazione di informazioni da immagini non è banale ma Mobile Vision la mette agevolmente a disposizione di tutti: l’aspetto probabilmente più intrigante di tutto ciò consiste nel vedere come, con tecnologie simili, l’informatica – una sfera spesso un pò astratta – entri in dialogo diretto con oggetti e simbologie del mondo “reale”.

Tutte le lezioni

1 ... 52 53 54 ... 82

Se vuoi aggiornamenti su Leggere codici a barre e QR code inserisci la tua e-mail nel box qui sotto:
Tags:
 
X
Se vuoi aggiornamenti su Leggere codici a barre e QR code

inserisci la tua e-mail nel box qui sotto:

Ho letto e acconsento l'informativa sulla privacy

Acconsento al trattamento di cui al punto 3 dell'informativa sulla privacy