0

I'm currently having a problem with detecting inverted QR code. The problem is that it detects normal QR code well but not inverted QR Code.

I tried to find solution on google and stackoverflow but most of questions have no acceptable answers.

I saw this article and I think this might be helpful but I don't know how to edit c++ file. Invert pixels - zxing

Here's my code.

setContentView(R.layout.activity_simple_scanner);
setupToolbar();
ViewGroup contentFrame = (ViewGroup) findViewById(R.id.content_frame);
mScannerView = new ZBarScannerView(this);
contentFrame.addView(mScannerView);

Here's a link to sample inverted QR code imgae. http://prntscr.com/dijmc8

Is there anybody who knows solution?

Community
  • 1
  • 1
Ioan Moldovan
  • 2,272
  • 2
  • 29
  • 54
  • I'm assuming when you say 'inverted' you mean color inverted instead of flipped/translated in some way. Take a look at ColorMatrix: http://stackoverflow.com/questions/4354939/understanding-the-use-of-colormatrix-and-colormatrixcolorfilter-to-modify-a-draw or http://stackoverflow.com/questions/17841787/invert-colors-of-drawable-android – Morrison Chang Dec 12 '16 at 16:49
  • sorry but how can i implement that in live camera while scanning qr code? – Ioan Moldovan Dec 12 '16 at 17:19
  • @MorrisonChang updated my question, could you please check? – Ioan Moldovan Dec 12 '16 at 17:22

2 Answers2

0

Looked at your image and tried it unsuccessfully on ZXing in Play Store.

All I can suggest is to trace though the ZXing code looking for where it is processing camera frames. Note that the image is in YUV format. (description here: How to render Android's YUV-NV21 camera image on the background in libgdx with OpenGLES 2.0 in real-time?)

You'll have to experiment to see what kind of camera input shading would be required to get the correct contrast to get ZXing to detect (or even if its only a particular 'plane' that ZXing is searching through). At that point you are doing a live camera image filter which could be done in OpenGL ES 2.0 shader language or RenderScript or your own JNI C/C++ code for performance reasons. See this site: http://www.bigflake.com/mediacodec/ and Grafika project https://github.com/google/grafika for general details - specifically the CameraCaptureActivity

Additional reading: Android: how to display camera preview with callback?

Community
  • 1
  • 1
Morrison Chang
  • 11,691
  • 3
  • 41
  • 77
  • sorry but i'm new to android, so you mean i have to edit ZXing library? – Ioan Moldovan Dec 12 '16 at 19:13
  • If you want live camera detection then yes you will have to modify ZXing. If you can work with a static bitmap, you can alter bitmap before feeding it into ZXing. Or get QR code maker to use different colors - compatible with ZXing. – Morrison Chang Dec 12 '16 at 19:22
  • if we use static images, how can i get results ? i only see startCamera() and no functions for static images in ZXing. – Ioan Moldovan Dec 12 '16 at 19:34
  • Look at how the regular Java side of ZXing is done in regards to passing over a bitmap and retrieving results. – Morrison Chang Dec 12 '16 at 19:51
0

If you are using camera barcode scanner. Please update your component code with this.

import { BarcodeFormat, HTMLCanvasElementLuminanceSource } from '@zxing/library';

and override this HTMLCanvasElementLuminanceSource.makeBufferFromCanvasImageData function in ngOnInit()

HTMLCanvasElementLuminanceSource.makeBufferFromCanvasImageData = function (canvas) {
      var imageData = canvas.getContext('2d').getImageData(0, 0, canvas.width, canvas.height);
      if(localStorage.inverted.toString()==="true"){
        
        
        for (var i = 0; i < imageData.data.length; i += 4) {
          var r = imageData.data[i]; // Red color lies between 0 and 255
          var g = imageData.data[i + 1]; // Green color lies between 0 and 255
          var b = imageData.data[i + 2]; // Blue color lies between 0 and 255
          var a = imageData.data[i + 3]; // Transparency lies between 0 and 255
  
          var invertedRed = 255 - r;
          var invertedGreen = 255 - g;
          var invertedBlue = 255 - b;
  
          imageData.data[i] = invertedRed;
          imageData.data[i + 1] = invertedGreen;
          imageData.data[i + 2] = invertedBlue;
        }
      }
     
      return HTMLCanvasElementLuminanceSource.toGrayscaleBuffer(imageData.data, canvas.width, canvas.height);
  };

Update export type of toGrayscaleBuffer from private to public.