خواندن QR کدها با استفاده از Mobile Vision API

خواندن QR کدها با استفاده از Mobile Vision API

اخیرا QR کدها محبوبیت زیادی یافته اند و در دسترس همگان قرار دارند، مطمئنا شما نیز به وفور به آنها برخورده اید، این کدها حتی در تبلیغات روزنامه ها و یا بیلبوردهای تبلیغاتی نیز جای گرفته اند، QRکدها مانند سایر بارکدها تصاویری هستند که برای خواندن توسط ماشین ها ساخته شده اند و معمولا یک رشته کوچک مانند URL خلاصه شده و یا شماره تلفن را به نمایش می گذارند. در زیر یک نمونه QR کد را مشاهده می کنید که دربرگیرنده URL سایت +Tuts می باشد.

blog_16015_1

برخلاف بارکدهای سنتی که به یک سخت افزار مخصوص نیازمندند، QRکدها به راحتی و با دقت تمام توسط هر اسمارت فونی با یک دوربین مناسب خوانده می شوند.

آخرین نسخه منتشر شده از Google Play services SDK دربرگیرنده mobile vision API است که کار ساخت اپلیکیشن های مجهز به تشخیص و خواندن QR کدها در ریل تایم را برای توسعه دهنده تسهیل بخشیده است. در این مطلب آموزشی نحوه استفاده از آن به شما ارائه می شود.

پیش نیازها

- آخرین نسخه از اندروید استودیو.

- یک گوشی اندروید دوربین دار.

1. نصب Google Play Services SDK

پیش از استفاده mobile vision API در اپلیکیشن لازم است آخرین نسخه Google Play services SDK را به عنوان یک وابستگی در build.gradle ماژول اپلیکیشن خود بیفزایید.

compile 'com.google.android.gms:play-services:7.8.0'

با فشردن دکمه Sync Now خطایی مطابق زیر به نمایش در می آید:

blog_16015_2

جهت نصب SDK بر روی لینک Install repository and sync project کلیک کنید.

2. ویرایش فایل منیفست اپلیکیشن

خط زیر را به فایل AndroidManifest.xm اپلیکیشن خود بیفزایید تا به طور خودکار کتابخانه های تشخیص بارکد برای گوشی های موردنظر را نصب کند.

<meta-data android:name="com.google.android.gms.vision.DEPENDENCIES" android:value="barcode"/>

به منظور خواندن QR کدها شما به دوربین گوشی نیازمندید و باید مجوز استفاده از آن یعنی android.permission.CAMERA را درخواست کنید.

<uses-permission android:name="android.permission.CAMERA" />

3. خواندن QR کد از یک عکس

حال می خواهیم قطعه کدی را بنویسیم که یک QR کد ذخیره شده در پوشه asset را که به عنوان عکس ذخیره شده می خواند. عکس موردنظر myqrcode.jpg نام دارد، چنانچه عکسی دربرگیرنده QR ندارید می توانید آنها را در Flickr پیدا کنید.

گام 1: تبدیل عکس به یک Bitmap

از آنجایی که mobile vision API برای ورودی به یک Bitmap نیاز دارد در گام اول نیاز است تا تصویر خود را به یک Bitmap تبدیل کنید. برای انجام این کار تصویر را با کمک متد open از کلاس AssetManager باز کنید و InputStream بازگشتی از متد DecodeStream متعلق به BitmapFactory را ارسال کنید، به منظور سادگی می توانید این کار را در متد onCreate اکتیویتی خود انجام دهید.

Bitmap myQRCode = BitmapFactory.decodeStream(

getAssets().open("myqrcode.jpg")

);

گام 2: ساخت یک بارکدخوان

برای تشخیص QR کدها و سایر انواع بارکدها باید یک نمونه از کلاس BarcodeDetector را مورد استفاده قرار دهید. کد زیر نحوه انجام این کار با استفاده از BarcodeDetecor.Builder را به نمایش می گذارد.

BarcodeDetector barcodeDetector = 

new BarcodeDetector.Builder(this)

.setBarcodeFormats(Barcode.QR_CODE)

.build();

توجه داشته باشید که تشخیص دهنده به طور پیش فرض بارکدهایی با فرمت های پشتیبانی شده را تشخیص می دهد. در اینجا از متد setBarcodeFormats برای مشخص کردن اینکه تنها QR کدها شناسایی شوند استفاده شده است.

گام 3: خواندن QR کد

از Frame.Builder برای ساخت یک فریم با Bitmap که قبلا ساخته اید استفاده کنید.

Frame myFrame = new Frame.Builder()

.setBitmap(myQRCode)

.build();

متد detect از BarocdeDetector را فراخوانی کرده و یک SparseArray تولید کنید که شامل تمامی QR کدهایی که BarcodeDetector در تصویر شناسایی کرده می باشد.

SparseArray<Barcode> barcodes = barcodeDetector.detect(myFrame);

هر آیتمی از SparseArray شامل یک آبجکت Barcode می باشد. برای درآوردن محتویات خام QR کد شما می توانید فیلد rawVlaue از آبجکت Barcode را مورد استفاده قرار دهید، اما استفاده از فیلد displayValue ساده تر است. کد زیر محتویات نخستین QRکدی را که API تشخیص داده به نمایش می گذارد:

// Check if at least one barcode was detected

if(barcodes.size() != 0) {

// Print the QR code's message

Log.d("My QR Code's Data",

barcodes.valueAt(0).displayValue

);

}

چنانچه در این مرحله اکتیویتی را به اجرا در آورید باید قادر به مشاهده پیامی در QR کد تصویر خود باشید.

4. خواندن QR کد با استفاده از دوربین

Mobile vision API عملیات خواندن و تشخیص بارکدها با استفاده از دوربین گوشی را نیز تسهیل بخشیده است، برای این کار لازم است یک اکتیویتی بسازیم.

گام 1: تعریف لی اوت

ساخت یک فایل XML لی اوت جدید به نام activity_main.xml. لی اوت باید دارای یک SurfaceView برای نمایش فریم های پیش نمایشی که توسط دوربین گرفته شده اند باشد. در صورت تمایل می توانید یک TextView برای نمایش محتویات QR کدها که API تشخیص داده است نیز بیفزایید.

پس از استفاده از RelativeLayout برای تعیین مکان هر دو ویجت ها فایل لی اوت XML چیزی شبیه زیر خواهد بود.

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent" android:layout_height="match_parent"

android:padding="16dp">

<SurfaceView

android:layout_width="640px"

android:layout_height="480px"

android:layout_centerVertical="true"

android:layout_alignParentLeft="true"

android:id="@+id/camera_view"

/>

<TextView

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:id="@+id/code_info"

android:layout_toRightOf="@+id/camera_view"

android:textSize="20sp"

android:layout_marginLeft="16dp"

android:text="Nothing to read."

android:layout_alignParentTop="true"

/>

</RelativeLayout>

گام 2: ساخت اکتیویتی

یک کلاس جاوا جدید به نام MainActivity.java بسازید و آن را زیر کلاس اکتیویتی کرده و متد onCreate آن را اورراید نمایید. درون متد onCreate برای تایید لی اوتی که در مرحله قبل ساخته بودید setContentView را فراخوانی کنید. سپس از findViewById استفاده کرده و مراجع به ویجت های تعریف شده در لی اوت را بگیرید.

setContentView(R.layout.activity_main);

cameraView = (SurfaceView)findViewById(R.id.camera_view);

barcodeInfo = (TextView)findViewById(R.id.code_info);

برای بدست آوردن یک رشته از تصاویر از دوربین گوشی و نمایش آنها در SurfaceView با استفاده از CameraSoure.Builder یک نمونه جدید از کلاس CameraSource را بسازید. به دلیل اینکه cameraSource نیازمند BarcodeDetector است، آن را با استفاده از کلاس BarcodeDetector.Builder بسازید. در صورت تمایل می توانید ابعاد مورد نظر را نیز با کمک متد setRequestedPreviewSize مشخص کنید.

barcodeDetector = 

new BarcodeDetector.Builder(this)

.setBarcodeFormats(Barcode.QR_CODE)

.build();

cameraSource = new CameraSource

.Builder(this, barcodeDetector)

.setRequestedPreviewSize(640, 480)

.build();

در مرحله بعد یک کال بک به surfaceView متعلق به surfaceHolder بیفزایید، با این کار زمان شروع رسم فریم های پیش نمایشی معلوم می شود.

cameraView.getHolder().addCallback(new SurfaceHolder.Callback() {

@Override

public void surfaceCreated(SurfaceHolder holder) {

}

@Override

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

}

@Override

public void surfaceDestroyed(SurfaceHolder holder) {

}

});

درون متد surfaceCreated متد start را فراخوانی کنید تا ترسیم فریم های پیش نمایش آغاز شود. چرا که متد start از شما انتظار مدیریت IOException را دارد باید آن را از درون بلوک try…catch فراخوانی کنید.

try {

cameraSource.start(cameraView.getHolder());

} catch (IOException ie) {

Log.e("CAMERA SOURCE", ie.getMessage());

}

به طور مشابه درون متد surfaceDestroyed متد stop از CmeraSource را فراخوانی کنید تا ترسیم فریم های پیش نمایشی متوقف شود.

cameraSource.stop();

اکتیویتی شما تقریبا آماده است، اما با این حال نیاز است که به BarcodeDetetor بگویید در زمان تشخیص یک QR کد چکار کند. یک نمونه از کلاسی که واسط Detector.Precessor را جاسازی کرده بسازید و آن را به متد setProcessor  از BarcodeDetector ارسال کنید.

barcodeDetector.setProcessor(new Detector.Processor<Barcode>() {

@Override

public void release() {

}

@Override

public void receiveDetections(Detector.Detections<Barcode> detections) {

}

});

در داخل متد receiveDetection لازم است sparseArray از آبجکت های Barcode را با فراخوانی متد getDetectedItems از کلاس Detector.Detection بگیرید. در این مرحله می توانید کدی بنویسید که عملیاتی بر روی QRکدهای تشخیص داده شده انجام دهد.

در زیر نحوه نمایش displayValue مربوط به QR کد در TextView نشان داده شده است:

final SparseArray<Barcode> barcodes = detections.getDetectedItems();

if (barcodes.size() != 0) {

barcodeInfo.post(new Runnable() { // Use the post method of the TextView

public void run() {

barcodeInfo.setText( // Update the TextView

barcodes.valueAt(0).displayValue

);

}

});

}

توجه داشته باشید که لازم است فراخوانی به متد setTect را در یک فراخوانی به متد post مربوط به TextView جاسازی کنید زیرا receiveDetections در ترد UI اجرا نمی شود و عدم انجام این کار به خطایی منجر می شود.

در این مرحله می توانید اپلیکیشن را کامپایل کرده  و به اجرا در آورید و با دوربین گوشی کد موردنظر را اسکن کنید، در صورت انجام درست مراحل محتویات QR کد نمایش داده می شود.

blog_16015_3

نتیجه گیری

در این مطلب آموزشی شما با نحوه استفاده از mobile vision API جهت خواندن QR کدها از تصاویر ثابت و یا دوربین گوشی آشنا شدید. در این مطلب تنها به QR کدها پرداخته شد اما شما می توانید API را برای خواندن سایر فرمت های بارکد مانند UPC-A و EAN-13 نیز مورد استفاده قرار دهید. به منظور کسب اطلاعات جزئی تر درباره mobile vision API می توانید به documentation آن مراجعه نمایید.

 

http://code.tutsplus.com برگرفته از

 

اینها را هم بخوانید