B4A Library 1D and 2D Barcode Scanner with ZXING - another Barcode Scanner that is 100% embedded in B4A

Discussion in 'Additional libraries, classes and official updates' started by Johan Schoeman, Feb 20, 2016.

  1. Johan Schoeman

    Johan Schoeman Expert Licensed User

    The attached project wraps the ZXING part of this Github project. I have not tested all the barcode formats but it should scan the following types:

    BarcodeFormat.UPC_A
    BarcodeFormat.UPC_E
    BarcodeFormat.EAN_13
    BarcodeFormat.EAN_8
    BarcodeFormat.RSS_14
    BarcodeFormat.CODE_39
    BarcodeFormat.CODE_93
    BarcodeFormat.CODE_128
    BarcodeFormat.ITF
    BarcodeFormat.CODABAR
    BarcodeFormat.QR_CODE
    BarcodeFormat.DATA_MATRIX
    BarcodeFormat.PDF_417

    Please take note of the xml files in the /Objects/res/layout and Objects/res/values folders of the B4A project should you start a new project from scratch.

    Posting the following:
    1. B4A project demonstrating the Barcode Scanner
    2. B4A library files - copy them to your additional library folder
    3. You also need android-support.v4.jar and core-3.2.1.jar to be in your additional library folder. I have zipped them together and you can download them from this link:
    https://www.dropbox.com/s/h9ts6cjfoo5et6h/core-3.2.1.zip?dl=0

    You can use it in portrait mode and landscape mode by changing the B4A project's attribute and the code in the Designer:
    #SupportedOrientations: portrait

    Code:
    zx1.Left = 2%x
    zx1.Top = 
    5%y
    zx1.Width = 
    96%x
    zx1.Height = 
    80%y

    b1.Left = 
    2%x
    b1.Top = zx1.Bottom + 
    2%y
    b1.Width = 
    15%x
    b1.Height = 
    10%y

    b2.Left = 
    45%x
    b2.Top = zx1.Bottom + 
    2%y
    b2.Width = 
    15%x
    b2.Height = 
    10%y

    b3.Left = 
    83%x
    b3.Top = zx1.Bottom + 
    2%y
    b3.Width = 
    15%x
    b3.Height = 
    10%y
    1.png


    2.png
    Sample code:
    Code:
    #Region  Project Attributes
        
    #ApplicationLabel: ZxingBarcodeScanner
        
    #VersionCode: 1
        
    #VersionName:
        
    'SupportedOrientations possible values: unspecified, landscape or portrait.
        #SupportedOrientations: portrait
        
    #CanInstallToExternalStorage: False
    #End Region

    #Region  Activity Attributes
        
    #FullScreen: False
        
    #IncludeTitle: True
    #End Region

    Sub Process_Globals
        
    'These global variables will be declared once when the application starts.
        'These variables can be accessed from all modules.

    End Sub

    Sub Globals
        
    'These global variables will be redeclared each time the activity is created.
        'These variables can only be accessed from this module.

        
    Private zx1 As ZxingBarcodeScanner
        
    Private b1 As Button
        
    Private b2 As Button
        
    Private b3 As Button
    End Sub

    Sub Activity_Create(FirstTime As Boolean)
        
    'Do not forget to load the layout file created with the visual designer. For example:
        Activity.LoadLayout("main")

        zx1.LaserColor = 
    Colors.Yellow
        zx1.MaskColor = 
    Colors.ARGB(15000200)
        zx1.BorderColor = 
    Colors.Magenta
        zx1.BorderStrokeWidth = 
    5
        zx1.BorderLineLength = 
    40
        zx1.Visible = 
    False

    End Sub

    Sub Activity_Resume


    End Sub

    Sub Activity_Pause (UserClosed As Boolean)
        zx1.Visible = 
    False
        zx1.stopScanner

    End Sub


    Sub b1_Click

        zx1.toggleFlash

    End Sub

    Sub b2_Click

        zx1.Visible = 
    True
        zx1.startScanner

    End Sub

    Sub b3_Click

        zx1.Visible = 
    False
        zx1.stopScanner

    End Sub

    Sub zx1_scan_result (scantext As String, scanformat As String)

        
    Log ("B4A scan text = " & scantext)
        
    Log ("B4A scan format = " & scanformat)


    End Sub
    The library:

    ZxingBarcodeScanner
    Author:
    Github: Dushyanth Maguluru, Wrapped by: Johan Schoeman
    Version: 1
    ZxingBarcodeScanner
    Events:

    • scan_result (scantext As String, scanformat As String)
    Fields:
    • ba As BA
    Methods:
    • BringToFront
    • DesignerCreateView (base As PanelWrapper, lw As LabelWrapper, props As Map)
    • Initialize (EventName As String)
    • Invalidate
    • Invalidate2 (arg0 As Rect)
    • Invalidate3 (arg0 As Int, arg1 As Int, arg2 As Int, arg3 As Int)
    • IsInitialized As Boolean
    • RemoveView
    • RequestFocus As Boolean
    • SendToBack
    • SetBackgroundImage (arg0 As Bitmap)
    • SetColorAnimated (arg0 As Int, arg1 As Int, arg2 As Int)
    • SetLayout (arg0 As Int, arg1 As Int, arg2 As Int, arg3 As Int)
    • SetLayoutAnimated (arg0 As Int, arg1 As Int, arg2 As Int, arg3 As Int, arg4 As Int)
    • SetVisibleAnimated (arg0 As Int, arg1 As Boolean)
    • handleResult (rawResult As Result)
    • startScanner
    • stopScanner
    • toggleFlash
    Permissions:
    • android.permission.CAMERA
    • android.permission.FLASHLIGHT
    Properties:
    • Background As Drawable
    • BorderColor As Int [write only]
    • BorderLineLength As Int [write only]
    • BorderStrokeWidth As Int [write only]
    • Color As Int [write only]
    • Enabled As Boolean
    • Height As Int
    • LaserColor As Int [write only]
    • Left As Int
    • MaskColor As Int [write only]
    • Tag As Object
    • Top As Int
    • Visible As Boolean
    • Width As Int
    You can download and test any posting of mine in this thread but if you want to use it then you need to [​IMG]
     

    Attached Files:

    Last edited: May 2, 2016
  2. freedom2000

    freedom2000 Well-Known Member Licensed User

    Very nice.

    You should add in the title "barcode and QR code" as it seems to work also with QR codes !
     
    Johan Schoeman likes this.
  3. Johan Schoeman

    Johan Schoeman Expert Licensed User

    Yes, see post #1 for the barcode formats that is should be able to scan
     
  4. susu

    susu Well-Known Member Licensed User

    Thank you Johan. Is this lib different your other barcode libs?
     
    Johan Schoeman likes this.
  5. Johan Schoeman

    Johan Schoeman Expert Licensed User

    Yes, it is a different Github project that I have wrapped. It seems to be more responsive than some of the other barcode scanning projects that I have wrapped
     
    krebsi83, MarcoRome and susu like this.
  6. jrat

    jrat Member Licensed User

    I'am trying lib and get the error
     
  7. MarcoRome

    MarcoRome Expert Licensed User

    Great Johan +10 ;)
     
    Johan Schoeman likes this.
  8. Johan Schoeman

    Johan Schoeman Expert Licensed User

    Read post #1 thoroughly. You are missing files in /Objects/res/layout and Objects/res/values folders.
     
  9. Johan Schoeman

    Johan Schoeman Expert Licensed User

    Posting updated B4A library files only. It adds no new methods to the B4A project. Added a notification sound upon a successful scan in the library. You would still require the 2 x jar files mentioned in point 3 of post #1
     

    Attached Files:

    Cristian Rufino and krebsi83 like this.
  10. krebsi83

    krebsi83 Member Licensed User

    GREAT!!! THANK YOU!!!
     
    Johan Schoeman likes this.
  11. JackKirk

    JackKirk Well-Known Member Licensed User

    Johan,

    Firstly thanks for building this library.

    Some months ago I wrote a B4A app that scans barcodes, amongst other things.

    At the time I used the original ABZXing library:

    https://www.b4x.com/android/forum/threads/abzxing-barcode-reader.7303/

    One of the main reasons for using this library, rather than one of the "built-in" options, was that the native ZXing app has a unique setting that allows you to set torch mode to auto - meaning that the torch automatically turns on in poor light conditions - an important consideration for my app which will be used in all sorts of light conditions by all sorts of people - some of whom will have great difficulty just holding a phone to allow the barcode to focus let alone toggling a torch on/off.

    I subsequently ported the app to B4I - the iBarcode library was equally deficient but I eventually managed to solve this, see:

    https://www.b4x.com/android/forum/t...roid-zxing-app-with-full-torch-control.63177/

    This B4I app actually uses the camera on the torch side to sense ambient light conditions.

    I am now revisiting the original B4A app and have discovered, to my dismay, that the native ZXing app actually uses the light sensor on the screen side of my Samsung S5, not a sensor on the torch side. This can be decidedly less than perfect in certain lighting conditions e.g. where the light source is behind the user forcing him to shadow the barcode by the phone.

    I have been playing around with the CameraEx class, as modified by Jim Brown:

    https://www.b4x.com/android/forum/t...ibrary-functionality.23801/page-8#post-191819

    This has GetSupportedFlashModes and get/setFlashMode subs that burrow into the low level code via the Reflections library (way out of my league).

    A bit of experimentation with this class on my Samsung S5 with the Auto flash mode suggests that it is actually turning the torch on when light conditions on the torch side are poor - which is what I am after.

    So my question to you is: how hard would it be to add functionality to your library that adds an Auto torch capability, possibly similar to the GetSupportedFlashModes and get/setFlashMode subs in the CameraEx class?

    Thanks in anticipation...
     
    Last edited: Mar 3, 2016
  12. Johan Schoeman

    Johan Schoeman Expert Licensed User

    I will try and add the AUTO option and if it works I will post an updated library. Give me time until this coming weekend to do the mods and to test them
     
    JackKirk likes this.
  13. JackKirk

    JackKirk Well-Known Member Licensed User

    Johan,

    Just an additional thought - if you get it to work and there is some sort of threshold value which triggers the torch to automatically turn on - could you expose the threshold so it is adjustable?

    Thanks again...
     
  14. Johan Schoeman

    Johan Schoeman Expert Licensed User

    Have amended the code in the wrapper and in the original Github project to allow for the torch mode to be switched either manually or automatically. Please note that it uses the light sensor of your device when you set it in AUTO mode in order to determine if the torch should be switched on or off based on the lower and upper ambient light settings. I have also added code so that the upper and lower ambient light threshold values can be set from B4A for the AUTO mode. Also added an event to the B4A project that will be raised when the ambient light (as measured by the light sensor) changes.

    Posting the following:
    1. Updated B4A project demonstrating the added features
    2. Updated B4A library files. Please note that you will still need the jar files from this link to also be in your additional library folder as what I have posted in post #1 of this thread: https://www.dropbox.com/s/h9ts6cjfoo5et6h/core-3.2.1.zip?dl=0

    Sample code:

    Code:
    #Region  Project Attributes
        
    #ApplicationLabel: ZxingBarcodeScanner
        
    #VersionCode: 1
        
    #VersionName:
        
    'SupportedOrientations possible values: unspecified, landscape or portrait.
        #SupportedOrientations: landscape
        
    #CanInstallToExternalStorage: False
    #End Region

    #Region  Activity Attributes
        
    #FullScreen: False
        
    #IncludeTitle: True
    #End Region

    Sub Process_Globals
        
    'These global variables will be declared once when the application starts.
        'These variables can be accessed from all modules.

    End Sub

    Sub Globals
        
    'These global variables will be redeclared each time the activity is created.
        'These variables can only be accessed from this module.

        
    Private zx1 As ZxingBarcodeScanner
        
    Private b1 As Button
        
    Private b2 As Button
        
    Private b3 As Button
    End Sub

    Sub Activity_Create(FirstTime As Boolean)
        
    'Do not forget to load the layout file created with the visual designer. For example:
        Activity.LoadLayout("main")
       
        zx1.LaserColor = 
    Colors.Yellow
        zx1.MaskColor = 
    Colors.ARGB(15000200)
        zx1.BorderColor = 
    Colors.Magenta
        zx1.BorderStrokeWidth = 
    5
        zx1.BorderLineLength = 
    40
       
        zx1.LowerLuxLimit = 
    500.0              'ADDED 5 MARCH 2016
        zx1.UpperLuxLimit = 1000.0             'ADDED 5 MARCH 2016
        zx1.AutoTorchMode = False              'ADDED 5 MARCH 2016
       
        zx1.Visible = 
    False

    End Sub

    Sub Activity_Resume
       

    End Sub

    Sub Activity_Pause (UserClosed As Boolean)
        zx1.Visible = 
    False
        zx1.stopScanner

    End Sub


    Sub b1_Click
       
        zx1.toggleFlash
       
    End Sub

    Sub b2_Click
       
        zx1.Visible = 
    True
        zx1.startScanner
       
    End Sub

    Sub b3_Click
       
        zx1.Visible = 
    False
        zx1.stopScanner
       
    End Sub

    Sub zx1_scan_result (scantext As String, scanformat As String)
       
        
    Log ("B4A scan text = " & scantext)
        
    Log ("B4A scan format = " & scanformat)
       
       
    End Sub


    Sub zx1_ambient_light_changed (ambientLight As Float)             'ADDED 5 MARCH 2016
       
        
    Log ("Ambient Light Lux Value = " & zx1.AmbientLightLux)      'ADDED 5 MARCH 2016
       
    End Sub
    Updated Library:

    ZxingBarcodeScanner
    Author:
    Github: Dushyanth Maguluru, Wrapped by: Johan Schoeman
    Version: 1
    • ZxingBarcodeScanner
      Events:
      • ambient_light_changed (ambientLight As Float)
      • scan_result (scantext As String, scanformat As String)
      Fields:
      • ba As BA
      Methods:
      • BringToFront
      • DesignerCreateView (base As PanelWrapper, lw As LabelWrapper, props As Map)
      • Initialize (EventName As String)
      • Invalidate
      • Invalidate2 (arg0 As Rect)
      • Invalidate3 (arg0 As Int, arg1 As Int, arg2 As Int, arg3 As Int)
      • IsInitialized As Boolean
      • RemoveView
      • RequestFocus As Boolean
      • SendToBack
      • SetBackgroundImage (arg0 As Bitmap)
      • SetColorAnimated (arg0 As Int, arg1 As Int, arg2 As Int)
      • SetLayout (arg0 As Int, arg1 As Int, arg2 As Int, arg3 As Int)
      • SetLayoutAnimated (arg0 As Int, arg1 As Int, arg2 As Int, arg3 As Int, arg4 As Int)
      • SetVisibleAnimated (arg0 As Int, arg1 As Boolean)
      • handleResult (rawResult As Result)
      • startScanner
      • stopScanner
      • toggleFlash
        Toggle the Torch between ON and OFF
      Permissions:
      • android.permission.CAMERA
      • android.permission.FLASHLIGHT
      Properties:
      • AmbientLightLux As Float [read only]
        Get the current Lux value
      • AutoTorchMode As Boolean [write only]
        Set control of the Torch to Auto or Manual
      • Background As Drawable
      • BorderColor As Int [write only]
      • BorderLineLength As Int [write only]
      • BorderStrokeWidth As Int [write only]
      • Color As Int [write only]
      • Enabled As Boolean
      • Height As Int
      • LaserColor As Int [write only]
      • Left As Int
      • LowerLuxLimit As Float [write only]
        Switch ON the torch if the Lux value is lower than this
      • MaskColor As Int [write only]
      • Tag As Object
      • Top As Int
      • UpperLuxLimit As Float [write only]
        Switch OFF the torch if the Lux value is lower than this
      • Visible As Boolean
      • Width As Int
     

    Attached Files:

    konradwalsh, JackKirk and DonManfred like this.
  15. Johan Schoeman

    Johan Schoeman Expert Licensed User

    Forgot to mention in the above post...if you just touch the scanner while the scanner is active it will also toggle the torch. It works in conjunction with the "Toggle Flash" button. You can therefore switch on the torch with the button or by touching the scanner when the scanner is active and then switch it off again by either using the button or by touching the scanner.
     
    JackKirk likes this.
  16. JackKirk

    JackKirk Well-Known Member Licensed User

    Johan,

    Let me commend you on your responsiveness - very impressive.

    But (bet you knew that was coming)...

    Firstly (minor) - you didn't update the version number in the XML - wasn't sure if I had installed the new library correctly.

    Secondly (bug?) - when I configure your new example with LowerLuxLimit of 100 and AutoTorchMode = True the torch only momentarily flashes on when I [Start Scan].

    Thirdly - on my Samsung S5 it is using the light sensor on the screen side - which is what the native ZXing app does but is not what is needed (have a look at my initial post #11)

    From what I can see of both my Samsung S5 and iPhone 4S:
    • neither of them have a simple light sensor on the torch side.
    • both their built in camera apps will flash when set to auto-flash and light conditions are poor on the torch side.
    • the built in camera apps seem to be sensing light on the torch side through the camera.
    I managed to resolve this for the iPhone/B4I version of my barcode app by a bit of Objective C, see:

    https://www.b4x.com/android/forum/threads/a-solution-for-getting-ambient-light-brightness.63106/ (post #2)

    This appears to take a photo and then analyse it for brightness - sounds dirty but it would appear this is the way the auto-flash works on iPhones.

    I haven't found a low level way to something similar on B4A, however I have been mucking around with Jim Brown's extension of the CameraEx class:

    https://www.b4x.com/android/forum/t...ibrary-functionality.23801/page-8#post-191819

    where I have tricked up the Camera1_PictureTaken sub to analyse the picture just taken for "brightness" (the mathematical definition of which seems to be very open):
    Code:
    '***********************************************************
    '***********************************************************
    '***********************************************************
    'JK's brightness fudge
       
        
    Dim jpg As InputStream
        jpg.InitializeFromBytesArray(Data,
    0,Data.Length)

        
    Dim bmp As Bitmap
        bmp.Initialize2(jpg)
        jpg.Close

        
    Dim pixels(bmp.Width * bmp.Height) As Int
        
    Dim jo = bmp As JavaObject
        jo.RunMethod(
    "getPixels"Array As Object(pixels, 0, bmp.Width, 00, bmp.Width, bmp.Height))

        
    Dim start_dt, samples As Long
        
    Dim xxx, yyy, spacing, single_pix, rrr, ggg, bbb As Int
        
    Dim brightness As Double
        
    Dim log_msg As String
       
        log_msg=
    ""
       
        
    For spacing = 0 To 6
           
            start_dt = 
    DateTime.Now   

            brightness = 
    0
           
            samples = 
    0

            
    For xxx = 0 To bmp.Width - 1 Step Power(2, spacing)

                
    For yyy = 0 To bmp.Height - 1 Step Power(2, spacing)
               
                    single_pix = pixels(xxx + yyy * bmp.Width)
                    rrr = 
    Bit.UnsignedShiftRight(Bit.And(single_pix, 0xff0000), 16)
                    ggg = 
    Bit.UnsignedShiftRight(Bit.And(single_pix, 0xff00), 8)
                    bbb = 
    Bit.And(single_pix, 0xff)
                    
    'According to this webpage:
                    'http://alienryderflex.com/hsp.html
                    'following formula is close to as used by PhotoShop
                    brightness = brightness + Sqrt(.299 * rrr * rrr + .587 * ggg * ggg + .114 * bbb * bbb)
                    samples = samples + 
    1
           
                
    Next
           
            
    Next

            brightness = brightness / samples / 
    255

            log_msg = log_msg & 
    CRLF & "brightness=" & NumberFormat2(brightness, 144False) & " in " & (DateTime.Now - start_dt)  & " millisecs with 1 in " & Power(2, spacing) & " sampling"
       
        
    Next

        
    Msgbox(log_msg, "")

    '***********************************************************
    '***********************************************************
    '***********************************************************
    This also sounds dirty but seems to work well - it can analyse a 1920 x 1080 image with full 1:1 sampling in less than half a second.

    I have attached the entire exercise as a zip below...
     

    Attached Files:

  17. Johan Schoeman

    Johan Schoeman Expert Licensed User

    Attached is the Java code. Change it to whatever might suite your needs. The changes that you require is not in the wrapper but in the code of the original project. What you are asking for is beyond the scope of the wrapper as it requires major changes to the original project code - some of which I have tried to accommodate in the last library that I have posted. I have already changed the original code more than what one should do - it just becomes so much more difficult to maintain the library when there are updates to the original project. So, if the library as it stands at present does not work for you then I suggest you either change the attached code (and recompile it into a lib) or choose something that works for you...;)

    In order to compile the attached source code you will need to add a libs folder on the same folder level as the attached scr folder and have android-support-v4.jar and core-3.2.1.jar in the libs folder. You can download the two jars from here https://www.dropbox.com/s/h9ts6cjfoo5et6h/core-3.2.1.zip?dl=0. You also need to have them in your additional library folder.
     

    Attached Files:

    • src.zip
      File size:
      16.2 KB
      Views:
      71
  18. Johan Schoeman

    Johan Schoeman Expert Licensed User

    I have set...
    zx1.LowerLuxLimit = 30.0
    ...and it works just fine on my S4 mini. Unfortunately I am limited to the devices that I can test it on.
     
  19. JackKirk

    JackKirk Well-Known Member Licensed User

    Johan,
    I re-installed your new example code, changed the top and bottom lines of these 3:
    Code:
    zx1.LowerLuxLimit = 100.0              'ADDED 5 MARCH 2016
    zx1.UpperLuxLimit = 1000.0             'ADDED 5 MARCH 2016
    zx1.AutoTorchMode = True              'ADDED 5 MARCH 2016
    and recompiled it to my Samsung S5.

    I then went into a totally dark room and launched it - same result as before - a momentary flash.

    I then launched the native ZXing app (with setting [Use front light] > [Automatic]) under the same light conditions and the torch automatically came on and stayed on.

    I understand your position. I believe I can come up with a solution that works for me by using your library and code similar to what I alluded to in post #16.

    I am also happy to post it as a class similar to what I have done for iOS:

    https://www.b4x.com/android/forum/t...roid-zxing-app-with-full-torch-control.63177/

    I was a bit reluctant to go down that path for a couple of reasons:

    (1) you obviously are infinitely more versed in Java and wrapping of GitHub projects than I - you quite likely would be able to find a much more elegant solution than the rather dirty solution I am contemplating.

    (2) from what I can see, you have pretty much taken ownership of "in-built" B4A barcode scanner solutions - I am new around here, not well versed in the local etiquette and not wanting to put anyone offside.

    I would appreciate your response/s...
     
  20. Johan Schoeman

    Johan Schoeman Expert Licensed User

    What is the range of brightness values that you get from your code above? I am trying to get your requirement added. I get a brightness of 0.16 when I block the camera with my finger and the highest that I have seen it is about 0.48 (indoors when pointing the camera to the ceiling)
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice