Pyzbar on Android doesn't read QRcodes, but reads barcodes

Question:

I have been developing a kivy application with pyzbar to run on an Android that needs to read barcodes and QRcodes.
The application read both barcodes and QRcodes running on my pc, but fails to read QRcodes while using the .apk built with buildozer, while still managing to read barcodes efficiently.

I thought (as it works on pc) that the problem was in dependencies in the .spec file while building to the apk.

Buildozer.spec requirements:

# (list) Application requirements
# comma separated e.g. requirements = sqlite3,kivy
requirements = python3,kivy==2.0.0,sdl2,opencv,android,pyzbar,libzbar,Pillow,libiconv

The code runs everything smoothly, but anyways this is how I call the pyzbar decode function:

import pyzbar
from pyzbar.pyzbar import decode

decoded_objects = decode(VideoCameraBC.image)

I tried to define the ZbarSymbols and only targeting QRcodes, but, not surprinsingly, it didn’t read anything at all.

There are two similar (if not the same problem) questions of this in here and here and as both of them have no answer [28/01/2022] I’ll ask again.

The .apk is built in buildozer in WSL2 but already tried to do build it inside Ubuntu, and same problem occurred.

Help is needed. Thank you

Answers:

After a couple of days I managed to find the problem.
For some reason that I didn’t know, my android was mirroring the image (despite the one in the app being perfectly fine). I was getting the image in kivy source code and sending it to a function.

    def on_tex(self, *l):
        image = np.frombuffer(self.texture.pixels, dtype='uint8')
        image = image.reshape(self.texture.height, self.texture.width, 4)
        numpy_data = image.tobytes()
        image = np.flipud(image) #This was necessary
        pil_image = Image.fromarray(image)

        self.texture.blit_buffer(numpy_data, bufferfmt="ubyte", colorfmt='rgba')
        self.canvas.ask_update()

        VideoCameraBC.new_image = True
        if(VideoCameraBC.BC_flag and VideoCameraBC.flag):
            VideoCameraBC.saving(self.texture.pixels, pil_image) #Here I was sending mirrored image


        VideoCameraID.new_image = True
        if(VideoCameraID.ID_flag and VideoCameraID.flag):
            VideoCameraID.saving(self.texture.pixels, pil_image) #Here I was sending mirrored image

Barcodes still read as normal because they are 1 dimensional and mirroring didn’t affected their data. QR codes on the other hand are 2 dimensional and needed to be treated.

Flipped image worked. Used below code to flip the frame :

self.image_frame = self.camera.texture.pixels

self.image_frame = np.frombuffer(self.image_frame,dtype=np.uint8).reshape(self.camera.texture.height, self.camera.texture.width, 4)

self.image_frameflipped = np.fliplr(self.image_frame)

decoded_objs = pyzbar.decode(self.image_frameflipped)

Answered By: Arpit Agrawal
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.