kivy-garden / zbarcam

Real time Barcode and QR Code scanner
MIT License
129 stars 33 forks source link

close camera #59

Open kompish opened 3 years ago

kompish commented 3 years ago

Is there any option to close camera after i finish scan of qr code?

AndreMiras commented 3 years ago

See there https://github.com/kivy-garden/xcamera/issues/14 I never had time to investigate further, but it could be a relatively simple Kivy bug to fix. Till it's fixed you can to workaround app side

gittb commented 3 years ago

Is there any option to close camera after i finish scan of qr code?

+1

ajinkya-open commented 2 years ago

after studing documentation i was able to close the camera by following zbarcam implements xbarcam xbarcam implements kivy.uix.camera so we can close the cmera by for reference https://kivy.org/doc/stable/api-kivy.uix.camera.html `

` MDFlatButton: text:'release' on_press: root.ids.zbarcam.ids.xcamera.play=False

`

dovivi commented 2 years ago

Hi guys, either zbarcam.stop() or root.ids.zbarcam.ids.xcamera.play=False do not actually release the camera. I have finally found a way to do so, based on this. Therefore, I simply use self.zbarcam.ids['xcamera']._camera._device.release() in my .py file (I initiate ZBarCam in the .py not in the .kv) I guess in .kv it should be something like root.ids.zbarcam.ids.xcamera._camera._device.release()

MrBillium commented 2 years ago

I too have gone deep down the rabbit hole on this one! Dovivi's solution is the only one that turns off my Camera's active light but once off I have been unable to turn it back on again without restarting the app.

Everything I do to restart after releasing the camera results in these warnings followed by pages of errors [WARNING] [Lang ] The file C:\Development\venvs\Inspector\Lib\site-packages\kivy_garden\zbarcam\zbarcam.kv is loaded multiples times, you might have unwanted behaviors. [WARNING] [Lang ] The file C:\Development\venvs\Inspector\lib\site-packages\kivy_garden\xcamera\xcamera.kv is loaded multiples times, you might have unwanted behaviors.

Here is some sample code where I have a main screen with a scanner button to take me to scanner screen with a back button. The scanner works fine and my two lines of teardown do turn off the camera when called but clicking the scanner button again does not work no matter what I try to destroy - see later lines in teardown.

Any ideas? Is there any working code that can turn off the camera AND allow other code to restart it?

     from kivy.app import App
    from kivy.properties import ObjectProperty
    from kivy.uix.screenmanager import Screen, ScreenManager, FadeTransition
    from kivy.uix.widget import Widget
    from kivy.lang import Builder
    from kivy_garden.zbarcam import ZBarCam
    from kivy.clock import Clock

    def windowManager():
        pass

    class InspectorApp(App):
        # # use any specified kv file
        # def build(self):
        #     sm = Builder.load_file(kvfile)
        #     return sm
        pass

    class LoginWindow(Screen):
        user = ObjectProperty(None)
        pwd = ObjectProperty(None)

        def validate(self):
            # check credential and move to main screen or display error message
            if self.pwd.text == 'bill':
                # use screen manager to change current screen
                self.manager.current = 'main'
                pass

    class MainWindow(Screen):
        pass

    class ScanWindow(Screen):
        pass

    class ScannerWindow(Screen):
        scanlabel = ObjectProperty(None)
        cam = None

        def startcamera(self):
            print (' camera starting')
            self.cam = ZBarCam()
            self.ids.cambox.add_widget(self.cam)
            Clock.schedule_interval(self.readcamera, 1)
            self.cam.start()

        def readcamera(self, instance):
            # Check if zbarcam.symbols is filled and stop scanning - THIS WORKS FINE
            print('reading')
            if (len(self.cam.symbols) > 0):  # something is detected
                txt = str(self.cam.symbols[0].data)  # text from QR
                print( f'QR = {txt}')
                # write to scanlabel and stop camera
                self.scanlabel.text = txt
                self.stopcamera()

        def stopcamera(self):
            print (' camera stopping')
            Clock.unschedule(self.readcamera, 1)
            self.cam.stop()  # stop zbarcam

        def teardown(self):
            # destroys camera called by screen exit event
            self.stopcamera()
            self.cam.ids['xcamera']._camera._device.release()  # release camera - THIS WORKS TOO

            # none of the below have worked to allow me to re-enter scannerscreen with a working camera
            self.cam.xcamera._camera = None
            self.clear_widgets()
            self.cam = None
            a = Builder.unload_file('zbarcam.kv') # I still get the 'multiple loading warnings with these
            b = Builder.unload_file('xcamera.kv')

    class WindowManager(ScreenManager):
        pass

    if __name__ == "__main__":
        InspectorApp().run()
qlrd commented 1 year ago

Everything I do to restart after releasing the camera results in these warnings followed by pages of errors [WARNING] [Lang ] The file C:\Development\venvs\Inspector\Lib\site-packages\kivy_garden\zbarcam\zbarcam.kv is loaded multiples times, you might have unwanted behaviors. [WARNING] [Lang ] The file C:\Development\venvs\Inspector\lib\site-packages\kivy_garden\xcamera\xcamera.kv is loaded multiples times, you might have unwanted behaviors.

I had same issue in all aspects when developing a desktop application.

I resolved this doing in 4 steps (i do not know if all 2nd is necessary), assuming that your app has a instantiated self._zbarcam = ZBarCam(...):

1. Release device

print("Releasing device")
self._zbarcam.ids.xcamera._camera._device.release()

2. Stop ZBarCam

print("Stopping <ZBarCam>")
self._zbarcam.stop()

3. Unload zbarcam.kv file

mod_path = os.path.dirname(sys.modules['kivy_garden.zbarcam'].__file__)
zbar_kv_path = os.path.join(mod_path, 'zbarcam.kv')
print("Unloading '%s'" % zbar_kv_path)            
Builder.unload_file(zbar_kv_path)

4. Unload xcamera.kv file

mod_path = os.path.dirname(sys.modules['kivy_garden.xcamera'].__file__)
xcam_kv_path = os.path.join(mod_path, 'xcamera.kv')
print("Unloading '%s'" % xcam_kv_path)            
Builder.unload_file(xcam_kv_path)

The complete example can be found here