برمجة تطبيق لقراءة QR Code

قد تحتاج في احد مشاريعك خدمة لقراءة Bar Code او QR code ولكن كانت الطريقة معقدة بسبب استخدام api خارجي واتصال بالانترنت وايضا بعض القوانين والشروط ولكن في هذا الدرس سنقوم باستخدام هذه الخدمة والتي قامت قوقل بتقديمها في خدمتها الجديدة تحت اسم vision api والتي تحتوي على التعرف على الوجوه وايضا قراءة bar و Qr كود مباشرة دون الحاجة لمكتبات الطرف ثالث . وقدم تم اصدارها مع Google Play services 7.8.

وتتميز هذه الخدمة بـ

  • لاتحتاج للاتصال بالانترنت.
  • يتعرف على جميع انواع الاكواد.
  • يستطيع التعرف على الكود في وضعيات مختلفة مقلوب او معتدل الخ.
  • يدعم جميع الانواع AN-13 EAN-8 UPC-A UPC-E Code-39 Code-93 Code-128 ITF Codabar.
  • يحدد النوع صورة او رابط او جهة اتصال .

سنقوم الان بالبدء في الدرس ومعرفة طريقة الاستخدام ?.

  • قراء Bar Code من صورة :

١ – انشاء مشروع اندرويد جديد :

قم بانشاء مشروع جديد في الاندرويد ستديو وقم باضافة dependnies التالية :

compile 'com.android.support:appcompat-v7:23.0.0'
    compile 'com.google.android.gms:play-services:7.8.0'

الان وبعد اضافة المكتبات سنقوم الان بالقيام بالمهمة البسيطة وهي طريقة الاستخدام?.

٢ – اضف الى manifest :

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

٣ – انشاء التصميم للتطبيق :

سنقوم بانشاء واجهة تطبيق بسيطة تحتوي على :

  • ImageView صورة لقراءة الباركود منها .
  • TextView لعرض النتيجة .
  • Button لبدء عملية القراءة.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            android:id="@+id/txtContent"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="" />

        <Button
            android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentStart="true"
            android:layout_alignParentTop="true"
            android:text="Process" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_conten
            android:id="@+id/imgview"/>
    </LinearLayout>
</RelativeLayout>

٤ – الانتقال للـActivity -> MainActivity.class :

سنقوم بقراء BarCode من صورة فسنحتاج الى تعريف الصورة كـBitmap 

Bitmap myBitmap = BitmapFactory.decodeResource(getApplicationContext().getResources(), 
    R.drawable.qrcode);

الان سنقوم باضافة هذا السطر :

   BarcodeDetector detector =
                        new BarcodeDetector.Builder(getApplicationContext())
                                .build();

الان قمنا باستدعاء BarCodeDetector والذي سيقوم افتراضيا يبحث عن جمبع انواع الباركود . 

لكن اذا اردنا تخصيص نوع معين من البار كود سنقوم باضافة هذا السطر وتحديد الانواع التي نريد البحث عنها فقط 

 .setBarcodeFormats(Barcode.DATA_MATRIX | Barcode.QR_CODE)

سيكون الكود بهذا الشكل :

 BarcodeDetector detector =
                        new BarcodeDetector.Builder(getApplicationContext())
                                .setBarcodeFormats(Barcode.DATA_MATRIX | Barcode.QR_CODE)
                                .build();

حددنا انواع الباركود التي نريدها .

  • الان نقوم بعملية المعالجة :
Frame frame = new Frame.Builder().setBitmap(myBitmap).build();
SparseArray<Barcode> barcodes = detector.detect(frame);

نلاحظ استخدام Array وهذا لان  Api يستطيع الكشف عن اكثر من BarCode .

  • الوصول للنتيجة :

عند كتابة سطر الكود التالي سنكون وصلنا للنتيجة والتي ربما تكون رابط او جهة اتصال او Wifi او ايميل .. الخ

Barcode thisCode = barcodes.valueAt(0);
  • عرض النتيجة :

سنقوم الان بعرض النتيجة في TextView بكتابة السطر التالي :

 txtView.setText(thisCode.rawValue);
  • ستكون النتيجة كما نلاحظ في الصورة التالية :
device-2015-09-03-094559
النتيجة كانت : ان شاء الله يكون الدرس سهل وممتع

 

 

  • تتبع الباركود بالكاميرا :

ايضا من الخدمات الجميلة والتي نتوفر في API وهي تتبع اباركود وعرض النتيجة مباشرة على الشاشة كما سنلاحظ في الصورة التالية :

نلاحظ ان التطبيق عرض نتيجة الباركود مباشرة وهي " ان شاء الله يكون الدرس ممتع وسهل "
نلاحظ ان التطبيق عرض نتيجة الباركود مباشرة وهي
” ان شاء الله يكون الدرس ممتع وسهل “
  • نقوم باضافة صلاحية الكاميرا الى manifest :

<uses-permission android:name="android.permission.CAMERA" />
  • الان سنقوم باضافة هذا الكود الى ملف Layout الخاص بـActivity :

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context="com.tatbigy.barcode.BarcodeTracking">

    <com.tatbigy.barcode.camera.CameraSourcePreview
        android:id="@+id/preview"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <com.tatbigy.barcode.camera.GraphicOverlay
            android:id="@+id/faceOverlay"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
</com.tatbigy.barcode.camera.CameraSourcePreview>
</RelativeLayout>

اذا استخدمت المثال المرفق غير مسار package الخاص بك

  • الان سنقوم بكتابة الكود الى ملف  Activity  :

  • نقوم بتهيئة عناصر الشاشة :

mPreview = (CameraSourcePreview) findViewById(R.id.preview);
        mGraphicOverlay = (GraphicOverlay) findViewById(R.id.faceOverlay);
  • بناء متتبع Barcode :

يستخدم متتع barcode عمليات MultiProcessor لاكتشاف BarCode الظاهر في الكاميرا وايضا سنتخدم BarcodeTrackerFactory لعرض وتوليد نتائج جديدة .

BarcodeDetector barcodeDetector = new BarcodeDetector.Builder(context).build();
        BarcodeTrackerFactory barcodeFactory = new BarcodeTrackerFactory(mGraphicOverlay);
        barcodeDetector.setProcessor(
                new MultiProcessor.Builder<>(barcodeFactory).build());
  • اعداد الكاميرا :

mCameraSource = new CameraSource.Builder(getApplicationContext(), multiDetector)
                .setFacing(CameraSource.CAMERA_FACING_BACK)
                .setRequestedPreviewSize(1600, 1024)
                .setRequestedFps(15.0f)
                .build();
    }

    /**
     * Restarts the camera.
     */
    @Override
    protected void onResume() {
        super.onResume();

        startCameraSource();
    }

    /**
     * Stops the camera.
     */
    @Override
    protected void onPause() {
        super.onPause();
        mPreview.stop();
    }

    /**
     * Releases the resources associated with the camera source, the associated detectors, and the
     * rest of the processing pipeline.
     */
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mCameraSource != null) {
            mCameraSource.release();
        }
    }

    /**
     * Starts or restarts the camera source, if it exists.  If the camera source doesn't exist yet
     * (e.g., because onResume was called before the camera source was created), this will be called
     * again when the camera source is created.
     */
    private void startCameraSource() {

        // check that the device has play services available.
        int code = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(
                getApplicationContext());
        if (code != ConnectionResult.SUCCESS) {
            Dialog dlg =
                    GoogleApiAvailability.getInstance().getErrorDialog(this, code, RC_HANDLE_GMS);
            dlg.show();
        }

        if (mCameraSource != null) {
            try {
                mPreview.start(mCameraSource, mGraphicOverlay);
            } catch (IOException e) {
                Log.e(TAG, "Unable to start camera source.", e);
                mCameraSource.release();
                mCameraSource = null;
            }
        }
    }
  • رسم المستطيل والقيمة :

في كلاس BarcodeGraphic سنقوم باستخدام paint لرسم المستطيل والقيمة الخاصة بـBarCode :

 mRectPaint = new Paint();
        mRectPaint.setColor(selectedColor);
        mRectPaint.setStyle(Paint.Style.STROKE);
        mRectPaint.setStrokeWidth(4.0f);

        mTextPaint = new Paint();
        mTextPaint.setColor(selectedColor);
        mTextPaint.setTextSize(36.0f);
  • في دالة draw سيكون الكود بهذا الشكل :

 // Draws the bounding box around the barcode.
        RectF rect = new RectF(barcode.getBoundingBox());
        rect.left = translateX(rect.left);
        rect.top = translateY(rect.top);
        rect.right = translateX(rect.right);
        rect.bottom = translateY(rect.bottom);
        canvas.drawRect(rect, mRectPaint);

        // Draws a label at the bottom of the barcode indicate the barcode value that was detected.
        canvas.drawText(barcode.rawValue, rect.left, rect.bottom, mTextPaint);

 

الان قم بتشغيل التطبيق وستظهر لك نتيجة مشابهه لما تم عرضه بالاعلى .

شاركوني في التعليقات للاسئلة والاستفسارات .

 

المثال مرفقع على github

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *

6 أفكار عن “برمجة تطبيق لقراءة QR Code”

  1. ما شاء الله شرح رائع اخي احمد
    لكن هل ممكن استخدام هذه الطريقة بأخذ صورة لبطاقة الفيزا كارت وثم لتحولها لارقام ممكن نسخها او التعديل عليها ؟

  2. السلام عليكم
    انا طالبة .. مشروع تخرجي عن البصمه .. ابغا اعرف كيف اضيف البصمه في الاندرويد و ما هي الدوال المستخدمه