B4A Library [B4X] QRGenerator - Cross platform QR code generator

Status
Not open for further replies.

Erel

Administrator
Staff member
Licensed User
QRGenerator is a class that generates QR codes.
It is written in B4X and it is compatible with B4A, B4i and B4J.

iPhone default camera app recognizing the QR code displayed in a B4A app:



Can create codes made of up to 2953 bytes.

It depends on XUI library and B4XCollections v1.50+.
It uses the very useful B4XBytesBuilder class.

Very good resource about the format: https://www.thonky.com/qr-code-tutorial/introduction
The Reed-Solomon error correction calculation is based on zxing open source project.

A B4J example is attached with QRGenerator class.

Versions

V1.60 - Added support for 1-L (max size is 17 bytes).
V1.50 - Added support for 40-L, 40-H and 23-H formats. Refactored code to make it easier to add more formats. BytesBuilder was replaced with B4XBytesBuilder from B4XCollections library.
V1.20 - Adds support for 9-L codes. Also renamed the local Block variable as it is a reserved word in B4i.
v1.11 - Fixes an issue with messages 35 or 36 bytes long.
 

Attachments

Last edited:

Erel

Administrator
Staff member
Licensed User
would that be possible in the future with B4X?
Why wait for the future?



v1.10 of QRGenerator adds support for 4-H codes. In this format 30% of the data can be restored from the error codes.
This makes it possible to add a logo at the center and keep the data complete.
It will use 4-h format if the data <= 34 bytes. See the logs.

The larger the image the larger the chances that the code will be broken.
 

Erel

Administrator
Staff member
Licensed User
Last example for today:



You can play with the factors to make it more detectable.

B4X:
Sub AddSomeColors(QRBmp As B4XBitmap, logo As B4XBitmap) As B4XBitmap
   Dim bc As BitmapCreator
   bc.Initialize(QRBmp.Width, QRBmp.Height)
   bc.CopyPixelsFromBitmap(QRBmp)
   Dim LogoBC As BitmapCreator
   LogoBC.Initialize(QRBmp.Width, QRBmp.Height)
   LogoBC.CopyPixelsFromBitmap(logo)
   Dim LightFactor As Float = 2
   Dim DarkFactor As Float = 0.8
   Dim argb, largb As ARGBColor
   For x = 0 To bc.mWidth - 1
       For y = 0 To bc.mHeight - 1
           bc.GetARGB(x, y, argb)
           LogoBC.GetARGB(x, y, largb)
           If largb.a > 0 Then
               Dim factor As Float
               If argb.r = 0 Then factor = DarkFactor Else factor = LightFactor
               largb.r = Min(255, largb.r * factor)
               largb.g =  Min(255, largb.g * factor)
               largb.b =  Min(255, largb.b * factor)
               bc.SetARGB(x, y, largb)
           End If
       Next
   Next
   Return bc.Bitmap
End Sub
 

Erel

Administrator
Staff member
Licensed User
Better implementation:



B4X:
Sub AddSomeColors(QRBmp As B4XBitmap, logo As B4XBitmap) As B4XBitmap
   Dim bc As BitmapCreator
   bc.Initialize(QRBmp.Width, QRBmp.Height)
   bc.CopyPixelsFromBitmap(QRBmp)
   Dim LogoBC As BitmapCreator
   LogoBC.Initialize(QRBmp.Width, QRBmp.Height)
   LogoBC.CopyPixelsFromBitmap(logo)
   Dim argb, largb As ARGBColor
   For x = 0 To bc.mWidth - 1
       For y = 0 To bc.mHeight - 1
           bc.GetARGB(x, y, argb)
           LogoBC.GetARGB(x, y, largb)
           If largb.a > 0 Then
               largb.a = 200
               LogoBC.SetARGB(x, y, largb)
               bc.BlendPixel(LogoBC, x, y, x, y)
           End If
       Next
   Next
   Return bc.Bitmap
End Sub
 
Last edited:

Johan Schoeman

Expert
Licensed User
I wasn't familiar with the qr code format before. It was more complicated than I expected.
I have done something similar here before (for B4A) and understand the complexity of generating 2D codes (have done it for QR codes version 1 to 40 with all 4 error levels and any masking pattern. Included is PDF 417 codes and Aztec codes (level 1 to 11). Also some 1D barcodes. Calculating error correction words is a whole excercise on its own. Creating generator polynomials are also complex.

Have also done a posting for B4J with same code converted from B4A to B4J somewhere in the forum.

b4a:

https://www.b4x.com/android/forum/threads/qr-code-library.41408/#post-322509
b4j:

https://www.b4x.com/android/forum/threads/barcodes-qr-codes-pdf417-aztec-codes-code11-code39-code93-ean8-ean13-and-code128.57248/#post-361917

Not simple at all when it comes to packing out the bits into the correct pattern that is required. Aztec codes get more complex and packing out Data Matrix is a nightmare.
But agree with Erel - far more complicated than what it seems to be. Once I "mastered" PDF417 I could make my own airline tickets - and tested them at numerous airports. It was great fun...:)

Qr codes with error correction H is quite tolerable and can recover data from a damaged QR code. As long as all three finding patters are there. Break one and the QR code is failing a scan more often than not
 
Last edited:

Erel

Administrator
Staff member
Licensed User
the [B4X] suggests it is working with B4a, b4i and b4j
That's almost true. It works in B4J UI apps.

It will not work in non-ui apps as it is based on XUI and B4XCanvas. You can make a small helper app that receives the data to encode and creates an image file. Use jShell to call it.
 

Serway

Member
Licensed User
Hello,

How to insert an image into a QRCode ?
The QRCode in the sample attached project is broken.
Thanks community for help.

Thierry
 

Attachments

Erel

Administrator
Staff member
Licensed User
Several mistakes in your code.

1. Why are you using BitmapDrawable?
2. B4XView.SetBitmap sets the gravity to center. In this case the returned bitmap is large due to the device scale. You can either set the gravity to FILL or resize the bitmap yourself:
B4X:
ImvQR.SetBitmap(QR.AddBitmap(BmpQR, logo, 255 * Value / 100).Resize(ImvQR.Width, ImvQR.Height, True))
3. The image itself is not a very good fit for this masking as its contrast is very large.
4. I modified your code and added a seekbar that helps with finding a good alpha value.

It is about 140 when I test it with the default iPhone camera app.

 

Attachments

Serway

Member
Licensed User
Hi Erel,

How fast of response !
Thank you very much Erel for your assistance.
It works perfectly.

Thierry
(ישראלי מצרפת)
 

Gabino A. de la Gala

Active Member
Licensed User
What would be the best way to print the generated code to a network printer?

My idea is to generate the QR using a B4A application and once generated, print it on a network printer.

My idea is to put the same QR13 EAN13, the batch and the expiration date of the products as they are received. Then generate the corresponding label so that, at the time of sale, with reading the QR and automatically we obtain all the "important" data.
 
Status
Not open for further replies.
Top