Git Product home page Git Product logo

qreader's Introduction

Image

Specs

API

Badges/Featured In

Android Arsenal AndroidDev Digest

Show some ❤️

GitHub stars GitHub forks GitHub watchers GitHub followers Twitter Follow

Android library which makes use of Google's Mobile Vision API to enable reading QR Code.

The library is built for simplicity and ease of use. It not only eliminates most boilerplate code for dealing with setting up QR Code reading , but also provides an easy and simple API to retrieve information from QR Code quickly.

Requires Google Play Services

Changelog

Starting with 1.0.4, Changes exist in the releases tab.

#Integration QREader is available in the Jcenter, so getting it as simple as adding it as a dependency

  • For gradle version < 4.0

    compile 'com.github.nisrulz:qreader:{latest version}'
  • For gradle 4.0+

    implementation 'com.github.nisrulz:qreader:{latest version}'

where {latest version} corresponds to published version in Download

Usage Docs

Steps

  1. Add a SurfaceView to your layout
<SurfaceView
  android:id="@+id/camera_view"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:layout_above="@+id/info"
  />
  1. Setup SurfaceView and QREader in onCreate()
// QREader
private SurfaceView mySurfaceView;
private QREader qrEader;
..

@Override
protected void onCreate(final Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  ..
  ..

  // Setup SurfaceView
  // -----------------
  mySurfaceView = (SurfaceView) findViewById(R.id.camera_view);

  // Init QREader
  // ------------
  qrEader = new QREader.Builder(this, mySurfaceView, new QRDataListener() {
    @Override
    public void onDetected(final String data) {
      Log.d("QREader", "Value : " + data);
      text.post(new Runnable() {
        @Override
        public void run() {
          text.setText(data);
        }
      });
    }
  }).facing(QREader.BACK_CAM)
      .enableAutofocus(true)
      .height(mySurfaceView.getHeight())
      .width(mySurfaceView.getWidth())
      .build();

}
  1. Initialize and Start in onResume()
  @Override
  protected void onResume() {
    super.onResume();

    // Init and Start with SurfaceView
    // -------------------------------
    qrEader.initAndStart(mySurfaceView);
  }
  1. Cleanup in onPause()
  @Override
  protected void onPause() {
    super.onPause();

    // Cleanup in onPause()
    // --------------------
    qrEader.releaseAndCleanup();
  }
  1. Some provided utility functions which you can use
  • To check if the camera is running

    boolean isCameraRunning = qrEader.isCameraRunning()
  • To stop QREader

    qrEader.stop();
  • To start QREader

    qrEader.start();
Check the included sample app for a working example.

Pull Requests

I welcome and encourage all pull requests. It usually will take me within 24-48 hours to respond to any issue or request. Here are some basic rules to follow to ensure timely addition of your request:

  1. Match coding style (braces, spacing, etc.) This is best achieved using CMD+Option+L (Reformat code) on Mac (not sure for Windows) with Android Studio defaults.
  2. If its a feature, bugfix, or anything please only change code to what you specify.
  3. Please keep PR titles easy to read and descriptive of changes, this will make them easier to merge :)
  4. Pull requests must be made against develop branch. Any other branch (unless specified by the maintainers) will get rejected.
  5. Check for existing issues first, before filing an issue.
  6. Have fun!

Created & Maintained By

Nishant Srivastava (@nisrulz)

If you found this library helpful or you learned something from the source code and want to thank me, consider buying me a cup of ☕

  • PayPal
  • Bitcoin Address: 13PjuJcfVW2Ad81fawqwLtku4bZLv1AxCL

qreader's People

Contributors

nisrulz avatar punksta avatar shusshu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

qreader's Issues

Bug : Fail to connect to camera service - With explanation, steps to reproduce and possible fix

Hi.
I had the RuntimeException: Fail to connect to camera service.
Log:

java.lang.RuntimeException: Fail to connect to camera service
    at android.hardware.Camera.<init>(Camera.java:545)
    at android.hardware.Camera.open(Camera.java:385)
    at com.google.android.gms.vision.CameraSource.zzbjo(Unknown Source)
    at com.google.android.gms.vision.CameraSource.start(Unknown Source)
    at github.nisrulz.qreader.QREader.startCameraView(QREader.java:221)
    at github.nisrulz.qreader.QREader.access$400(QREader.java:40)
    at github.nisrulz.qreader.QREader$1.surfaceCreated(QREader.java:68)
    at android.view.SurfaceView.updateWindow(SurfaceView.java:607)
    at android.view.SurfaceView.onWindowVisibilityChanged(SurfaceView.java:246)
    at android.view.View.dispatchWindowVisibilityChanged(View.java:9322)
    at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1285)
    at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1285)
    at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1285)
    at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1285)
    at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1285)
    at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1285)
    at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1285)
    at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1285)
    at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1285)
    at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1285)
    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1468)
    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1191)
    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6642)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:777)
    at android.view.Choreographer.doCallbacks(Choreographer.java:590)
    at android.view.Choreographer.doFrame(Choreographer.java:560)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:763)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:145)
    at android.app.ActivityThread.main(ActivityThread.java:5951)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1400)

This is due to the camera being used from another app and not be released when the app goes to background.

I can give the steps to reproduce this issue if you need.

This exception is thrown in QREader.java in line 221, and is not caught by the IOException beacause it's a RunTimeException and we can't catch it because it's thrown in a background thread when surface is created.

So to just fix the crash just change the IOException for just an Exception.

Although this resolves the issue i think it's important to send feedback to the user and just catch the exception and print the error we cant do that. I think it would be useful some sort of listener so we could know the errors when the camera fails.

Please if you could change this as soon as possible would be very helpful. And if you need any help just ask.

java.lang.IllegalStateException: Camera already started!

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.shanky.qrscanner, PID: 8249
java.lang.IllegalStateException: Camera already started!
at github.nisrulz.qreader.QREader.startCameraView(QREader.java:213)
at github.nisrulz.qreader.QREader.start(QREader.java:176)
at github.nisrulz.qreader.QREader$2.onGlobalLayout(QREader.java:118)
at android.view.ViewTreeObserver.dispatchOnGlobalLayout(ViewTreeObserver.java:981)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2414)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1522)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7098)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:927)
at android.view.Choreographer.doCallbacks(Choreographer.java:702)
at android.view.Choreographer.doFrame(Choreographer.java:638)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:913)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6682)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)

This happens when application goes in paused state while scanning qr code and just resume the application it will crash

This is the code for paused state and resume state

@OverRide
protected void onPause() {
super.onPause();

    if (hasCameraPermission) {

        // Cleanup in onPause()
        // --------------------
        qrEader.releaseAndCleanup();
    }
}

@Override
protected void onResume() {
    super.onResume();

    if (hasCameraPermission) {

        // Init and Start with SurfaceView
        // -------------------------------
        qrEader.initAndStart(mySurfaceView);

    }
}

Restart qreader?

Hello there, thanks for this great QR reader!

I wonder if its possible to restart the qreader object after call .stop() on it.

For example:
On the onDetect listener, after I detect something, I show a Dialog and call qreader.stop()

qrEader = new QREader.Builder(this, surfaceView, new QRDataListener() {
            @Override public void onDetected(final String data) {
                Log.d("QREader", "Value : " + data);
                surfaceView.post(new Runnable() {
                    @Override public void run() {
                        showDialog(data);
                    }
                });
            qrEader.stop();               <------------------------------------- HERE
            }
        }).build();

        qrEader.init();

So when I dismiss my Dialog I call qreader.start() but it doens't read the qrcode anymore

    private void showDialog(String qrcode) {
        AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
        builder.setTitle("Confirmar convidado?");
        builder.setMessage(qrcode);

        String positiveText = getString(android.R.string.ok);
        builder.setPositiveButton(positiveText,
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        System.out.println("OK");
                        surfaceView.post(new Runnable() {
                            @Override public void run() {
                                qrEader.start();      <------------------------- HERE
                            }
                        });

                    }
                });

        String negativeText = getString(android.R.string.cancel);
        builder.setNegativeButton(negativeText,
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        System.out.println("CANCEL");

                        qrEader.start();       <-------------------------------- HERE
                    }
                });

        AlertDialog dialog = builder.create();

        dialog.show();
    }

"Cannot find symbol" when calling QREader.getInstance().stop()

As it says, im calling QREader.getInstane().stop() and can't recognize the method.
public class Home extends AppCompatActivity{

SurfaceView view;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_home);

    init();
    initQRScanner();
    startScanning();
}

private void init() {
    view = (SurfaceView) findViewById(R.id.sview);
    initQRScanner();
}

private void initQRScanner(){
    QREader.getInstance().setUpConfig(true, CameraSource.CAMERA_FACING_BACK);
}

private void startScanning(){
    QREader.getInstance().start(this, view, new QRDataListener() {
        @Override
        public void onDetected(String data) {
            QREader.getInstance().stop();
        }
    });

}

}

Camera Preview Lagging

I just followed the implementation as told in the wiki. The camera preview lags a lot on my Moto g 3rd Gen phone. Can something be done to smooth it out ?

Detector processor must first be set with setProcessor in order to receive detection results.

Hi,
tried to use googles vision api directly but the dectector was for some reason always "not operational" and now I have the same problem with your API and a modified version of your example app.
Log gets continously spammed with the following error message:

05-27 00:52:51.956 30999-709/evco.world.projects.de.evco E/CameraSource: Exception thrown from receiver.
java.lang.IllegalStateException: Detector processor must first be set with setProcessor in order to receive detection results.
at com.google.android.gms.vision.Detector.receiveFrame(Unknown Source)
at com.google.android.gms.vision.CameraSource$zzb.run(Unknown Source)
at java.lang.Thread.run(Thread.java:818)

Is it my device or...?
Code (little bit different from your example code):

@Override
    protected void onStart() {
        super.onStart();
        setContentView(R.layout.camera);

        hsCodes = new HashSet<String>();

        codepreview = (TextView)findViewById(R.id.codepreview);
        cameraView = (SurfaceView)findViewById(R.id.cameraView);

        qrEader = new QREader.Builder(this, cameraView, new QRDataListener() {
            @Override public void onDetected(final String data) {
                final String code = format( data );
                hsCodes.add(code);
                codepreview.post( new Runnable() {
                    @Override
                    public void run() {
                        codepreview.setText(code);
                    }
                });
            }
        }).build();
        qrEader.init();
    }

    @Override
    protected void onResume() {
        super.onResume();

        qrEader.start();
    }

    @Override
    protected void onPause() {
        super.onPause();

        qrEader.stop();
    }

OnDetectMethodCall Multiple times

I want to move from on activity to another on detecting the qrcode.But when i navigate from current activity to another activity its not happening and the detection keeps going on.It works fine if i move back to the parent (the activity which call the qrcode activity) on activity result.But i dont want to go for on activity result.

Unable to initiate QREader

I am getting below error wnen i call: qrEader.init();

"java.lang.NoSuchMethodError: No static method zzC(Ljava/lang/Object;)Lcom/google/android/gms/dynamic/zzd; in class Lcom/google/android/gms/dynamic/zze; or its super classes (declaration of 'com.google.android.gms.dynamic.zze'"

java.lang.IllegalStateException: Detector processor must first be set with setProcessor

Using the sample application at: https://github.com/nisrulz/qreader/tree/master/app

I am receiving an error every few milliseconds while the app is trying to detect a QR code.

The error is:

E/CameraSource: Exception thrown from receiver.
java.lang.IllegalStateException: Detector processor must first be set with setProcessor in order to receive detection results.
at com.google.android.gms.vision.Detector.receiveFrame(Unknown Source)
at com.google.android.gms.vision.CameraSource$zzb.run(Unknown Source)
at java.lang.Thread.run(Thread.java:818)

Customize BarcodeDetector

What do you think about features:

  • Use com.google.android.gms.vision.barcode.BarcodeDetector as singleton by default instead of creating new instance inside init() function. Do we really need different detectors in different readers?
class BarcodeDetectorHolder {
  private static  BarcodeDetector detector;

  static BarcodeDetector getBarcodeDetector(Context context) {
    if (detector == null)
      detector = new BarcodeDetector.Builder(context.getApplicationContext()).setBarcodeFormats(Barcode.QR_CODE).build();
    return detector;
  }
}

  public QREader(final Builder builder) {
    if (barcodeDetector == null)
      barcodeDetector = BarcodeDetectorHolder.getBarcodeDetector(builder.context);
   ...
   }
  • Allow to set external BarcodeDetector to Builder. It can be useful, if someone will want to scan not only qr codes.
BarcodeDetector myDetector = ...; //set few barcode formats.
QRReader r = QREader.Builder(MainActivity.this, surfaceView, listener).setDetector(myDetector)

I already made it in my project and can make PR. But I'm not sure about first case.

Failed resolution of: Lcom/google/android/gms/internal/zzdcc;

Here is my function :

 private void initQRReader() {

        try {
            if (qrEader != null && qrEader.isCameraRunning()) {
                qrEader.releaseAndCleanup();
            }

            qrEader = new QREader.Builder(context, binding.cameraView, new QRDataListener() {
                @Override
                public void onDetected(final String data) {

                   //My work
                }
            }).facing(QREader.BACK_CAM)
                    .enableAutofocus(true)
                    .height(binding.cameraView.getHeight())
                    .width(binding.cameraView.getWidth())
                    .build();
        } catch (Exception e) {
            e.printStackTrace();
            toast("Sorry scanner is not supported on this device.");
        }
    }

And also followed onResume and onPause methods to make this thing work. Please help me.

Facing this issue. Suddenly it started with version 2.1.2 now its even not working with 2.1.1

01-03 10:22:22.227 6808-6808/com.Invoice.maker E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.Invoice.maker, PID: 6808
java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/android/gms/internal/zzdcc;
at com.google.android.gms.vision.barcode.BarcodeDetector$Builder.(Unknown Source:5)
at github.nisrulz.qreader.BarcodeDetectorHolder.getBarcodeDetector(BarcodeDetectorHolder.java:38)
at github.nisrulz.qreader.QREader.(QREader.java:104)
at github.nisrulz.qreader.QREader.(QREader.java:40)
at github.nisrulz.qreader.QREader$Builder.build(QREader.java:357)
at com.invoiceapp.Main.CodeScannerActivity.initQRReader(CodeScannerActivity.java:109)
at com.invoiceapp.Main.CodeScannerActivity.access$000(CodeScannerActivity.java:22)
at com.invoiceapp.Main.CodeScannerActivity$1.onGranted(CodeScannerActivity.java:40)
at com.invoiceapp.Main.BaseActivity$27.onPermissionsGranted(BaseActivity.java:3636)
at com.kishan.askpermission.AskPermissionImp.requestAppPermissions(AskPermissionImp.java:71)
at com.kishan.askpermission.ShadowFragment.onCreate(ShadowFragment.java:41)
at android.app.Fragment.performCreate(Fragment.java:2489)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1237)
at android.app.FragmentManagerImpl.addAddedFragments(FragmentManager.java:2407)
at android.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2186)
at android.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2142)
at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2043)
at android.app.FragmentManagerImpl.dispatchMoveToState(FragmentManager.java:3032)
at android.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:2979)
at android.app.FragmentController.dispatchActivityCreated(FragmentController.java:178)
at android.app.Activity.performCreate(Activity.java:7005)
at android.app.Activity.performCreate(Activity.java:6990)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
Caused by: java.lang.ClassNotFoundException: com.google.android.gms.internal.zzdcc
at java.lang.VMClassLoader.findLoadedClass(Native Method)
at java.lang.ClassLoader.findLoadedClass(ClassLoader.java:738)
at java.lang.ClassLoader.loadClass(ClassLoader.java:363)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
at com.google.android.gms.vision.barcode.BarcodeDetector$Builder.(Unknown Source:5) 
at github.nisrulz.qreader.BarcodeDetectorHolder.getBarcodeDetector(BarcodeDetectorHolder.java:38) 
at github.nisrulz.qreader.QREader.(QREader.java:104) 
at github.nisrulz.qreader.QREader.(QREader.java:40) 
at github.nisrulz.qreader.QREader$Builder.build(QREader.java:357) 
at com.invoiceapp.Main.CodeScannerActivity.initQRReader(CodeScannerActivity.java:109) 
at com.invoiceapp.Main.CodeScannerActivity.access$000(CodeScannerActivity.java:22) 
at com.invoiceapp.Main.CodeScannerActivity$1.onGranted(CodeScannerActivity.java:40) 
at com.invoiceapp.Main.BaseActivity$27.onPermissionsGranted(BaseActivity.java:3636) 
at com.kishan.askpermission.AskPermissionImp.requestAppPermissions(AskPermissionImp.java:71) 
at com.kishan.askpermission.ShadowFragment.onCreate(ShadowFragment.java:41) 
at android.app.Fragment.performCreate(Fragment.java:2489) 
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1237) 
at android.app.FragmentManagerImpl.addAddedFragments(FragmentManager.java:2407) 
at android.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2186) 
at android.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2142) 
at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2043) 
at android.app.FragmentManagerImpl.dispatchMoveToState(FragmentManager.java:3032) 
at android.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:2979) 
at android.app.FragmentController.dispatchActivityCreated(FragmentController.java:178) 
at android.app.Activity.performCreate(Activity.java:7005) 
at android.app.Activity.performCreate(Activity.java:6990) 
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214) 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856) 
at android.app.ActivityThread.-wrap11(Unknown Source:0) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589) 
at android.os.Handler.dispatchMessage(Handler.java:106) 
at android.os.Looper.loop(Looper.java:164) 
at android.app.ActivityThread.main(ActivityThread.java:6494) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807) 
Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/android/gms/internal/zzbck;
at com.google.android.gms.vision.barcode.BarcodeDetector$Builder.(Unknown Source:5) 
at github.nisrulz.qreader.BarcodeDetectorHolder.getBarcodeDetector(BarcodeDetectorHolder.java:38) 
at github.nisrulz.qreader.QREader.(QREader.java:104) 
at github.nisrulz.qreader.QREader.(QREader.java:40) 
at github.nisrulz.qreader.QREader$Builder.build(QREader.java:357) 
at com.invoiceapp.Main.CodeScannerActivity.initQRReader(CodeScannerActivity.java:109) 
at com.invoiceapp.Main.CodeScannerActivity.access$000(CodeScannerActivity.java:22) 
at com.invoiceapp.Main.CodeScannerActivity$1.onGranted(CodeScannerActivity.java:40) 
at com.invoiceapp.Main.BaseActivity$27.onPermissionsGranted(BaseActivity.java:3636) 
at com.kishan.askpermission.AskPermissionImp.requestAppPermissions(AskPermissionImp.java:71) 
at com.kishan.askpermission.ShadowFragment.onCreate(ShadowFragment.java:41) 
at android.app.Fragment.performCreate(Fragment.java:2489) 
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1237) 
at android.app.FragmentManagerImpl.addAddedFragments(FragmentManager.java:2407) 
at android.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2186) 
at android.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2142) 
at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2043) 
at android.app.FragmentManagerImpl.dispatchMoveToState(FragmentManager.java:3032) 
at android.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:2979) 
at android.app.FragmentController.dispatchActivityCreated(FragmentController.java:178) 
at android.app.Activity.performCreate(Activity.java:7005) 
at android.app.Activity.performCreate(Activity.java:6990) 
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214) 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856) 
at android.app.ActivityThread.-wrap11(Unknown Source:0) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589) 
at android.os.Handler.dispatchMessage(Handler.java:106) 
at android.os.Looper.loop(Looper.java:164) 
at android.app.ActivityThread.main(ActivityThread.java:6494) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807) 
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.android.gms.internal.zzbck" on path: DexPathList[[zip file "/data/app/com.Invoice.maker-g0I69RbPTxHTnyU9ounT5A==/base.apk"],nativeLibraryDirectories=[/data/app/com.Invoice.maker-g0I69RbPTxHTnyU9ounT5A==/lib/x86, /data/app/com.Invoice.maker-g0I69RbPTxHTnyU9ounT5A==/base.apk!/lib/x86, /system/lib, /vendor/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:125)
at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
at com.google.android.gms.vision.barcode.BarcodeDetector$Builder.(Unknown Source:5) 
at github.nisrulz.qreader.BarcodeDetectorHolder.getBarcodeDetector(BarcodeDetectorHolder.java:38) 
at github.nisrulz.qreader.QREader.(QREader.java:104) 
at github.nisrulz.qreader.QREader.(QREader.java:40) 
at github.nisrulz.qreader.QREader$Builder.build(QREader.java:357) 
at com.invoiceapp.Main.CodeScannerActivity.initQRReader(CodeScannerActivity.java:109) 
at com.invoiceapp.Main.CodeScannerActivity.access$000(CodeScannerActivity.java:22) 
at com.invoiceapp.Main.CodeScannerActivity$1.onGranted(CodeScannerActivity.java:40) 
at com.invoiceapp.Main.BaseActivity$27.onPermissionsGranted(BaseActivity.java:3636) 
at com.kishan.askpermission.AskPermissionImp.requestAppPermissions(AskPermissionImp.java:71) 
at com.kishan.askpermission.ShadowFragment.onCreate(ShadowFragment.java:41) 
at android.app.Fragment.performCreate(Fragment.java:2489) 
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1237) 
at android.app.FragmentManagerImpl.addAddedFragments(FragmentManager.java:2407) 
at android.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2186) 
at android.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2142) 
at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2043) 
at android.app.FragmentManagerImpl.dispatchMoveToState(FragmentManager.java:3032) 
at android.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:2979) 
at android.app.FragmentController.dispatchActivityCreated(FragmentController.java:178) 
at android.app.Activity.performCreate(Activity.java:7005) 
at android.app.Activity.performCreate(Activity.java:6990) 
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214) 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856) 
at android.app.ActivityThread.-wrap11(Unknown Source:0) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589) 
at android.os.Handler.dispatchMessage(Handler.java:106) 
at android.os.Looper.loop(Looper.java:164) 
at android.app.ActivityThread.main(ActivityThread.java:6494) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807) 

Flash

Hi, thanks for this library.

Question: Could you implement flash functionality, like .enableFlash(true/false)

Damian

Google Play Services Conflict

Issue occurred after including Google Firebase in my project

java.lang.NoSuchMethodError: No static method zzC(Ljava/lang/Object;)Lcom/google/android/gms/dynamic/zzd; in class Lcom/google/android/gms/dynamic/zze; or its super classes (declaration of 'com.google.android.gms.dynamic.zze' appears in /data/app/com.remoteapps.vs-2/base.apk)
at com.google.android.gms.vision.barcode.internal.client.zzd$zza.zzb(Unknown Source)
at com.google.android.gms.vision.barcode.internal.client.zzd$zza.zza(Unknown Source)
at com.google.android.gms.vision.barcode.internal.client.zzd.zzIg(Unknown Source)
at com.google.android.gms.vision.barcode.internal.client.zzd.(Unknown Source)
at com.google.android.gms.vision.barcode.BarcodeDetector$Builder.build(Unknown Source)
at github.nisrulz.qreader.QREader.init(QREader.java:82)

Black Screen on Nexus 5X

Instead of starting the camera, it just shows a black screen. Android M permissions have been taken care of. I'm running Android N (NPD35K).

Can't create handler inside thread that has not called Looper.prepare()

Exception thrown from receiver.
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.(Handler.java:200)
at android.os.Handler.(Handler.java:114)
at android.widget.Toast$TN.(Toast.java:344)
at android.widget.Toast.(Toast.java:100)
at android.widget.Toast.makeText(Toast.java:258)
at com.reasei.hotelmanagementsystem.QRScannerActivity$1.onDetected(QRScannerActivity.java:28)
at github.nisrulz.qreader.QREader$2.receiveDetections(QREader.java:115)
at com.google.android.gms.vision.Detector.receiveFrame(Unknown Source)
at com.google.android.gms.vision.CameraSource$zzb.run(Unknown Source)
at java.lang.Thread.run(Thread.java:818)

surfaceCreated not triggered on resume after unlock screen

all is going well, but if you try to press the power button (lock button) surfaceCreatedis not trigerred (SurfaceHolder.Callback surfaceHolderCallback @ line 90)

so this block (@ line 195)

public void start() { if (surfaceView != null && surfaceHolderCallback != null) { //if surface already created, we can start camera if (surfaceCreated) { startCameraView(context, cameraSource, surfaceView); } else { //startCameraView will be invoke in void surfaceCreated surfaceView.getHolder().addCallback(surfaceHolderCallback); } } }

start camera view will never be called. any fix. ?

Error creating native barcode detector (Error with 4.2.2 only)

I am having this error : NativeBarcodeDetectorHandle: Error creating native barcode detector
Because of that i got this one: QREader: Barcode recognition libs are not downloaded and are not operational

This error is happening with Android 4.2.2 only, the same code runs perfectly fine with 5.1 and 6.0.

Device: smartwatch with a full install of android.
The sample code to detect the QrCodes hasn't been modified.

No instant run.

Flash feature

Flash feature in develop branch to be fixed?

In the develop branch , you can turn flash on and off , but after you scan anything this feature stops, and doesn't function properly.

Fail To connect to camera service

Th scanner is working awesome in api level >21.But it shows error "Fail TO Connect to camera service" with api level<21.Kindly help

qreader does not focus

Hey,
i have implemented your library into a small project of mine. The problem i am facing is that the camera does not focus automatically and therefor i never get a scan result. Any ideas on how i can fix that?

Thanks and greetings
Leo
13054629_1075658902501699_2024864934_o

Camera is stretched

Hello,
I have created a layout on android with a simple menu of 50dp and under a "surfaceview" where I used the library of qr reader to read the qr code, only that the camera is stretched, I also tried to enter 50 dp margin to surface view to keep the spaces, but nothing has changed, how can I solve this problem?

I used version 2.1.2 of the library

Preview:

0f87eb24-820b-480d-ab1e-b83c38809082

Fail to connect to camera service

Fail to connect to camera service
I have two apps which is using QReader, if one of the app is running in background, i have to kill that first app in order to open my second app.
otherwise i am getting Fail to connect to camera service.

E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.RuntimeException: Fail to connect to camera service
at android.hardware.Camera.native_setup(Native Method)
at android.hardware.Camera.(Camera.java:413)
at android.hardware.Camera.open(Camera.java:366)
at com.google.android.gms.vision.CameraSource.zzIb(Unknown Source)
at com.google.android.gms.vision.CameraSource.start(Unknown Source)
at github.nisrulz.qreader.QREader.startCameraView(QREader.java:127)
at github.nisrulz.qreader.QREader.access$100(QREader.java:35)
at github.nisrulz.qreader.QREader$1.surfaceCreated(QREader.java:92)
at android.view.SurfaceView.updateWindow(SurfaceView.java:610)
at android.view.SurfaceView.access$000(SurfaceView.java:93)
at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:182)
at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:864)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2142)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1249)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6364)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:791)
at android.view.Choreographer.doCallbacks(Choreographer.java:591)
at android.view.Choreographer.doFrame(Choreographer.java:561)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:777)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5419)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1209)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1025)
at dalvik.system.NativeStart.main(Native Method)

Also application gets crashed when we get into the activity again (the activity which is initiating the QR start service)

Surface View stops camera preview

Do you want to request a feature or report a bug?

What is the current behavior?

Surface View doesn't show camera preview (Or camera stops) when user locks the device and resume the activity again and this generally happens when u lock your device. Here the part of log:

CAMERA_MSG_STATE_CALLBACK
mCameraStateCallback is null
Camera-JNI: copyAndPost: off=0, size=518400 msg=10
Camera-JNI: copyAndPost: off=0, size=518400 msg=10
Camera-JNI: copyAndPost: off=0, size=518400 msg=10

Any other comments?

I am performing these operations in onPause and onDestroy:
@OverRide
protected void onPause() {
if (null != qrEader) {
qrEader.stop();
}
super.onPause();
}

@Override
protected void onDestroy() {
    super.onDestroy();
    if (null != qrEader) {
        qrEader.releaseAndCleanup();
    }
}

and restrating qrReader in onResume:
qrEader.start();

Device Information: one plus 5
Android Version: android oreo

I also found out this in my log:
W/DynamiteModule: Local module descriptor class for com.google.android.gms.vision.dynamite not found.
W/zygote64: Unsupported class loader
W/zygote64: Skipping duplicate class check due to unsupported classloader
I/DynamiteModule: Considering local module com.google.android.gms.vision.dynamite:0 and remote module com.google.android.gms.vision.dynamite:1702

Skipping duplicate class check due to unsupported classloader
I/Vision: Loading library libbarhopper.so
I/zygote64: The ClassLoaderContext is a special shared library.
The ClassLoaderContext is a special shared library.
Access denied finding property "camera.hal1.packagelist"

Detector processor must first be set

E/CameraSource: Exception thrown from receiver. java.lang.IllegalStateException: Detector processor must first be set with setProcessor in order to receive detection results. at com.google.android.gms.vision.Detector.receiveFrame(Unknown Source) at com.google.android.gms.vision.CameraSource$zzb.run(Unknown Source) at java.lang.Thread.run(Thread.java:818)

i use your sample code exactly, but recive this error

Start activity in onDetected() and then pressing back

I'm trying to scan a qrcode, parse data, put this data into an intent and launch another activity. Everything works fine but when I press the back button to return in the scan activity, surfaceview is completely black. How do you suggest I can solve this? Thank you very much

Here is my code

@Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_qr_code_scan);
      text = findViewById(R.id.text);
      requestPermissions();
      // Setup SurfaceView
      // -----------------
      mySurfaceView = (SurfaceView) findViewById(R.id.camera_view);
      // Init QREader
      // ------------
      qrEader = new QREader.Builder(this, mySurfaceView, new QRDataListener() {
          @Override
          public void onDetected(final String data) {
              Log.d("QREader", "Value : " + data);
              createLetturaQrCode(data);
              text.post(new Runnable() {
                  @Override
                  public void run() {
                      //text.setText(data);
                  }
              });
              Intent intent = new Intent(thisActivity, QrCodeDetailsActivity.class);
              intent.putExtra(QRCODE_DETAILS, data);
              startActivity(intent);
          }
      }).facing(QREader.BACK_CAM)
              .enableAutofocus(true)
              .height(mySurfaceView.getHeight())
              .width(mySurfaceView.getWidth())
              .build();
  }

RuntimeException: Fail to connect to camera service

Hi I'm receiving this a crash bug from play store on Samsung device:

java.lang.RuntimeException: Fail to connect to camera service at android.hardware.Camera.native_setup(Native Method) at android.hardware.Camera.&lt;init&gt;(Camera.java:419) at android.hardware.Camera.open(Camera.java:371) at com.google.android.gms.vision.CameraSource.zzbjo(Unknown Source) at com.google.android.gms.vision.CameraSource.start(Unknown Source) at github.nisrulz.qreader.QREader.startCameraView(QREader.java:221) at github.nisrulz.qreader.QREader.access$400(QREader.java:40) at github.nisrulz.qreader.QREader$1.surfaceCreated(QREader.java:68) at android.view.SurfaceView.updateWindow(SurfaceView.java:586) at android.view.SurfaceView.access$000(SurfaceView.java:88) at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:177) at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:891) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2145) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1239) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6396) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:813) at android.view.Choreographer.doCallbacks(Choreographer.java:613) at android.view.Choreographer.doFrame(Choreographer.java:583) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:799) at android.os.Handler.handleCallback(Handler.java:733) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:146) at android.app.ActivityThread.main(ActivityThread.java:5511) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099) at dalvik.system.NativeStart.main(Native Method)

About using library version and device details:

screen shot 2018-01-14 at 1 20 52 pm

I'm using latest 2.1.1 version library.

Device:
name: samsung SM-G355H
OS : Android 4.4.2

How to read Barcode with qreader

Hi
it is really awesome library, but i can't read Barcode with this library And only support QRcode
As it is very fast library, is it possible ?

Black screen when re opening app

I just copied all the codes from the sample project that is included here.

@Override
protected void onResume() {
super.onResume();
qReader.initAndStart(surfaceView);
}`

@Override
protected void onPause() {
super.onPause();
qReader.releaseAndCleanup();
}`

I think there's something wrong about the SurfaceView, currently tested on Kitkat and Marshmallow both have the same error.

-Thanks

Black screen on one of my two phones

Hello nisrulz,
I have two smartphone:
1 - Note 4 with Android 6.01 and all is OK;
2 - Chinese phone with Android 6.0 and screen is black; when I press START/STOP the button text is always STOP.
Inside onCreate():
stateBtn.setOnClickListener(new View.OnClickListener() {
@OverRide
public void onClick(View v) {
if (qrEader.isCameraRunning()) { // THIS PIECE OF CODE IS NEVER EXECUTED!!
stateBtn.setText(getString(R.string.btn_start_qrcode));
qrEader.stop();
}
else {// THIS PIECE OF CODE IS ALWAYS EXECUTED!!
stateBtn.setText(getString(R.string.btn_stop_qrcode));
qrEader.start();
}
}
});

Any idea?
Thanks in advance. Rocco

Error building with proguard

I have build my project with proguard using QReader Libs but it throw error "can't find common super class ...LatLngBounds (google gms), but when I remove QReader Libs, my project build successfully.
I've tried to add into proguard-rule.pro
-dontwarn github.nisrulz.qreader.**
-keep class github.nisrulz.qreader.** { *; }

But error still appear. Please guide me how to fix this. Thanks

Add feature to TextureView

It would be great to add support for TextureView to be able to do this:

myTexture = (TextureView) findViewById(R.id.textureView);
myTexture.setSurfaceTextureListener(mSurfaceTextureListener);
// ...
QREader.getInstance().init(this, myTexture);

Why? Because for a better integration with the Camera2 API, it's recommended to use a TextureView, because:

Unlike SurfaceView, TextureView does not create a separate window but behaves as a regular View. This key difference allows a TextureView to be moved, transformed, animated, etc.

References:

https://developer.android.com/reference/android/hardware/camera2/package-summary.html
https://developer.android.com/reference/android/view/TextureView.html

Thanks for the good work!

Null pointer for on resume

I got Null pointer exception sometimes
Process: com.sparktech.wowcherryscanner, PID: 18639 java.lang.IllegalArgumentException: Null image data supplied. at com.google.android.gms.vision.Frame$Builder.setImageData(Unknown Source) at com.google.android.gms.vision.CameraSource$zzb.run(Unknown Source) at java.lang.Thread.run(Thread.java:818)

Problem access camera in marshmallow

Hai Mate..

Thanks for your qreader that help me so much in my apps,

my apps works fine in my device with Android 5.0 Lolipop, but I have problem when I test it in Android 6.0 Marshmallow, my apps cannot access the camera, the surface view only display a blank black screen, I already try update my SDK platform to Android 8.0 Oreo and update my JDK to JDK8, but still don't resolve the problem,

I hope you can help me, maybe it's my mistake,
I really appreciate your effort and everything you have done,

Best Regards and Thanks a lot..

Attachment :
77c6c6b0-9002-4488-9bf9-b6549bef8f61

Possible to handle a granted camera permission without restarting the activity?

Currently, the sample app calls restartActivity() in onPermissionGranted() on granting the camera permission.

Is it instead possible to handle this without re-inflating the SurfaceView or restarting the activity?

Using the QREader.Builder plus initAndStart() in onPermissionGranted() does not work on and still displays a black screen.

Proguard

I'm getting error, while trying to use the library with proguard.

how can i use button in recyclerview??

i tried setOnClickListener in onBindViewHolder and ItemViewHolder...
but it happened nothing when i clicked.
should i use different way to set button in a row in recyclerView?
may i see some example?
even i tried in activty not adapter, it shows same.
and how can i change drag clickevent recyclerview to imageview or button?
thank you.

getCamera() or openFlash()

你好(Hello):
我是來自台灣(Taiwan)的開發者(Developer)
非常抱歉英文不好所以使用中文
您寫的 QREader 掃描非常好用(QREader very good)
但我的專案需要打開閃光燈(open flash)

import android.hardware.Camera;
public void openFlash() {
    Camera camera = Camera.open();
    Camera.Parameters parameters = camera.getParameters();
    parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
    camera.setParameters(parameters);
}

為此希望能在 QREader.class 加入 getCamera() 或 openFlash() / closeFlash()
(QREader.class add method to getCamera() or openFlash() and closeFlash())

CameraSource cameraSource = new CameraSource.Builder(...)...
public Camera getCamera() {
    Field[] declaredFields = CameraSource.class.getDeclaredFields();
    for (Field field : declaredFields) {
        if (field.getType() == Camera.class) {
            field.setAccessible(true);
            try {
                Camera camera = (Camera) field.get(cameraSource);
                if (camera != null) {
                    return camera;
                }
                return null;
            } catch (Exception e) {
                e.printStackTrace();
            }
            break;
        }
    }
    return null;
}

public void openFlash() {
    Camera camera = getCamera();
    Camera.Parameters parameters = camera.getParameters();
    parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
    camera.setParameters(parameters);
}

public void closeFlash() {
    Camera camera = getCamera();
    Camera.Parameters parameters = camera.getParameters();
    parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
    camera.setParameters(parameters);
}

謝謝您(Thank you)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.