Giter Site home page Giter Site logo

kivy-garden / xcamera Goto Github PK

View Code? Open in Web Editor NEW
43.0 13.0 16.0 1.09 MB

Kivy widget for taking pictures with the camera, optimized for Android. It uses the native Android's APIs to take the pictures, thus ensuring good quality, high resolution, auto-focus, etc.

License: MIT License

Python 81.03% Shell 0.74% Makefile 13.73% kvlang 4.50%

xcamera's Introduction

XCamera: Android-optimized camera widget

Github Actions Tests Github Actions Android Build Status Coverage Status PyPI version

XCamera is a widget which extends the standard Kivy Camera widget with more functionality. In particular:

  1. it displays a "shoot button", which the user can press to take pictures

  2. on Android, it uses the native APIs to take high-quality pictures, including features such as auto-focus, high resolution, etc.

  3. it includes a method to force landscape mode. On Android, it is often desirable to switch to landscape mode when taking pictures: you can easily do it by calling camera.force_landscape(), and later camera.restore_orientation() to restore the orientation to whatever it was before.

Screenshot:

screenshot

Notes:

  • On Android, the resolution property of the XCamera (and also of the plain Camera) widget controls the preview size: in other words, it only affects the quality of the preview, not the size of the pictures taken.

  • As it is now, the camera will shoot using the default setting for the picture size, which seems to be what the camera think it is "the best". In theory, we could add a method to retrieve the list of all possible picture sizes, and add a property to control it. It would also be nice to add a new button to allow the user to manually select the preferred size. Pull requests are welcome :)

Install & Usage

xcamera is available on PyPI. Therefore it can be installed via pip.

pip3 install xcamera

Once installed, the demo should be available in your PATH and can be ran from the command line.

xcamera

And the widget can be imported via:

from kivy_garden.xcamera import XCamera

Demo

A full working demo is available in src/kivy_garden/xcamera/main.py. You can run it via:

make run

Develop & Contribute

To play with the project, install system dependencies and Python requirements using the Makefile.

make

Then verify everything is OK by running tests.

make test

If you're familiar with Docker, the project can also run in a fully isolated container. First build the image.

make docker/build

Then you can run tests within the container.

make docker/run/test

Or the application itself.

make docker/run/app

xcamera's People

Contributors

andremiras avatar antocuni avatar cikoxp avatar el3 avatar keyweeusr avatar misl6 avatar ti-ba-paj avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

xcamera's Issues

Not working on recent android APIs updates and so on

Google updated its Android APIes, Also Gradle and buildozer has been updated. But xcamera is not updated, Therefore xcamera has bugs. If anyone looks for a working android camera project I suggest this:

https://github.com/android/camera-samples/tree/main/Camera2Basic

Camera2Basic is in original Android programing language, Kotlin. I built and tested it successfully with latest Android APIes and Gradle.

Also please be noticed that Kivy Python has some limits to be ported into original Android programing language (Kotlin) and in most cases don't work! But Kotlin and Java codes work properly.

Keyerror while using XCamera

I have made a small script to test out the XCamera but whenever i try loading the script , it shows an error

Exception has occurred: KeyError
'kivy.garden.xcamera'

here is the code

from kivy.lang import Builder
from kivy.app import App

kv = """
#: import XCamera kivy.garden.xcamera.XCamera
FloatLayout:
    orientation: "vertical"
    XCamera:
        id:xcam
        

"""

class Cam(App):
    def build(self):
        return Builder.load_string(kv)

if __name__ == "__main__":
    Cam().run()

Error running

This happens when I run in my desktop, apk and kivy launcher via deploy.sh
And this code line: >> 28: resolution: 640, 480 # 1920, 1080

is related to the last commit, maybe is just happening with me .

`11-21 18:25:29.689  1882  1910 I python  :  Traceback (most recent call last):
11-21 18:25:29.690  1882  1910 I python  :    File "main.py", line 38, in <module>
11-21 18:25:29.691  1882  1910 I python  :      CameraApp().run()
11-21 18:25:29.692  1882  1910 I python  :    File "/home/tito/code/python-for-android-upstream/build/python-install/lib/python2.7/site-packages/kivy/app.py", line 802, in run
11-21 18:25:29.693  1882  1910 I python  :    File "main.py", line 32, in build
11-21 18:25:29.694  1882  1910 I python  :      return Builder.load_string(kv)
11-21 18:25:29.696  1882  1910 I python  :    File "/home/tito/code/python-for-android-upstream/build/python-install/lib/python2.7/site-packages/kivy/lang.py", line 1921, in load_string
11-21 18:25:29.699  1882  1910 I python  :    File "/home/tito/code/python-for-android-upstream/build/python-install/lib/python2.7/site-packages/kivy/lang.py", line 2084, in _apply_rule
11-21 18:25:29.702  1882  1910 I python  :    File "/home/tito/code/python-for-android-upstream/build/python-install/lib/python2.7/site-packages/kivy/lang.py", line 1970, in apply
11-21 18:25:29.706  1882  1910 I python  :    File "/home/tito/code/python-for-android-upstream/build/python-install/lib/python2.7/site-packages/kivy/lang.py", line 2130, in _apply_rule
11-21 18:25:29.711  1882  1910 I python  :  kivy.lang.BuilderException: Parser: File "<inline>", line 28:
11-21 18:25:29.712  1882  1910 I python  :  ...
11-21 18:25:29.714  1882  1910 I python  :       26:
11-21 18:25:29.716  1882  1910 I python  :       27:    id: camera
11-21 18:25:29.718  1882  1910 I python  :  >>   28:    resolution: 640, 480 # 1920, 1080
11-21 18:25:29.720  1882  1910 I python  :       29:    allow_stretch: True
11-21 18:25:29.722  1882  1910 I python  :       30:
11-21 18:25:29.724  1882  1910 I python  :  ...
11-21 18:25:29.726  1882  1910 I python  :  JavaException: JVM exception occurred: Fail to connect to camera service
11-21 18:25:29.728  1882  1910 I python  :    File "/home/tito/code/python-for-android-upstream/build/python-install/lib/python2.7/site-packages/kivy/lang.py", line 2123, in _apply_rule
11-21 18:25:29.730  1882  1910 I python  :    File "kivy/weakproxy.pyx", line 22, in kivy.weakproxy.WeakProxy.__setattr__ (kivy/weakproxy.c:1235)
11-21 18:25:29.732  1882  1910 I python  :    File "kivy/properties.pyx", line 408, in kivy.properties.Property.__set__ (kivy/properties.c:5114)
11-21 18:25:29.734  1882  1910 I python  :    File "kivy/properties.pyx", line 733, in kivy.properties.ListProperty.set (kivy/properties.c:11127)
11-21 18:25:29.736  1882  1910 I python  :    File "kivy/properties.pyx", line 446, in kivy.properties.Property.set (kivy/properties.c:5876)
11-21 18:25:29.738  1882  1910 I python  :    File "kivy/properties.pyx", line 501, in kivy.properties.Property.dispatch (kivy/properties.c:6557)
11-21 18:25:29.739  1882  1910 I python  :    File "kivy/_event.pyx", line 1224, in kivy._event.EventObservers.dispatch (kivy/_event.c:13497)
11-21 18:25:29.740  1882  1910 I python  :    File "kivy/_event.pyx", line 1130, in kivy._event.EventObservers._dispatch (kivy/_event.c:12696)
11-21 18:25:29.741  1882  1910 I python  :    File "/home/tito/code/python-for-android-upstream/build/python-install/lib/python2.7/site-packages/kivy/uix/camera.py", line 103, in _on_index
11-21 18:25:29.742  1882  1910 I python  :    File "/home/tito/code/python-for-android-upstream/build/python-install/lib/python2.7/site-packages/kivy/core/camera/camera_android.py", line 40, in __init__
11-21 18:25:29.743  1882  1910 I python  :    File "/home/tito/code/python-for-android-upstream/build/python-install/lib/python2.7/site-packages/kivy/core/camera/__init__.py", line 70, in __init__
11-21 18:25:29.743  1882  1910 I python  :    File "/home/tito/code/python-for-android-upstream/build/python-install/lib/python2.7/site-packages/kivy/core/camera/camera_android.py", line 47, in init_camera
11-21 18:25:29.744  1882  1910 I python  :    File "jnius/jnius_export_class.pxi", line 906, in jnius.jnius.JavaMultipleMethod.__call__ (jnius/jnius.c:27875)
11-21 18:25:29.745  1882  1910 I python  :    File "jnius/jnius_export_class.pxi", line 637, in jnius.jnius.JavaMethod.__call__ (jnius/jnius.c:24246)
11-21 18:25:29.746  1882  1910 I python  :    File "jnius/jnius_export_class.pxi", line 803, in jnius.jnius.JavaMethod.call_staticmethod (jnius/jnius.c:26271)
11-21 18:25:29.746  1882  1910 I python  :    File "jnius/jnius_utils.pxi", line 93, in jnius.jnius.check_exception (jnius/jnius.c:3870)
11-21 18:25:29.747  1882  1910 I python  :  
11-21 18:25:29.811  1882  1910 I python  : Python for android ended.

Regards

Runtime camera permission check

I've recently implemented dynamic camera permission checking on top of xcamera here:
https://github.com/kivy-garden/zbarcam/blob/543ea49/src/kivy_garden/zbarcam/zbarcam.py#L18

The idea is to prevent the native Camera.open() call from happening until the user gives permission. The way I do it is by overriding _on_index() initially defined in kivy.uix.camera.Camera._on_index(). As we can see it's the one responsible for creating the CoreCamera object later on. And the idea is to skip that call until the camera permission is given.

The beauty of my current fix is it works all asynchronously, meaning the camera texture will start showing up as soon as the user accept the camera permission.

Xcamera release

How can I release xcamera in order for the camera can be used for other apps?

ModuleNotFoundError: No module named 'kivy_garden.xcamera'

After building on android with buildozer and p4a.
it finds zbarcam, but not xcamera

buildozer.spec

...
requirements = python3,kivy,kivymd,Pillow,pyzbar,pyqrcode,pypng,opencv-python,kivy_garden.graph,kivy-garden.filebrowser,xcamera,zbarcam
...

Also publish xcamera binary

This depends on #4 (Publish to PyPI) to be done.
The idea is that people can simply run the xcamera demo after installing it via pip.

When the app stop, Xcamera is still running in background.

When I destroy the Xcamera object, the app is crashing. When I close the app on an android 11, the android's camera icon is still active and keeps running until i force "quit the application" .

Once the Xcamera object is created removing it is not stopping , and when i use del it crashes.

Is there a way to exit the camera safely ?

from kivymd.app import MDApp
from kivy.lang import Builder
from kivy_garden.xcamera import XCamera
from plyer import camera
#from android.permissions import request_permissions, Permission
from kivy.uix.image import Image
from kivy.uix.widget import Widget
from kivymd.app import MDApp
```try:
   
   request_permissions([Permission.INTERNET,
                     Permission.READ_EXTERNAL_STORAGE,
                     Permission.WRITE_EXTERNAL_STORAGE,
                     Permission.CAMERA])
except:
      pass```
KV = """
#:import XCamera kivy_garden.xcamera.XCamera
BoxLayout:
    XCamera:
        id : ycamera
"""
       
class uiApp(MDApp):     
        
        
    def build(self):
        print('IM Building here')
        self.screen = Builder.load_string(KV)
        
        self.screen.ids['ycamera'].on_picture_taken = self.on_picture_taken
        return self.screen
    
uiApp().run()

white Screen in Xcamera

image

i get the white screen for camera

this is my code

from kivy.app import App
from kivy.lang import Builder
from kivy.utils import platform
from kivy_garden.xcamera.xcamera import XCamera
if platform == "android":
from android.permissions import request_permissions, Permission
request_permissions([Permission.CAMERA])

kv = """
FloatLayout:
XCamera:
id: xcamera
on_picture_taken: app.picture_taken(*args)
BoxLayout:
orientation: 'horizontal'
size_hint: 1, None
height: sp(50)
Button:
text: 'Set landscape'
on_release: xcamera.force_landscape()
Button:
text: 'Restore orientation'
on_release: xcamera.restore_orientation()
"""

class CameraApp(App):
def build(self):
return Builder.load_string(kv)

def picture_taken(self, obj, filename):
    print('Picture taken and saved to {}'.format(filename))

def main():
CameraApp().run()

if name == 'main':
main()

Anyone
suggest me i my code

Setup Continuous Integration testing

Let's add Continuous Integration testing like TravisCI to the project.
First that could simply trigger unit tests checks from kivy-garden/garden.xcamera#10 and linting checks from kivy-garden/garden.xcamera#11.
And later more advanced like checking the project build for Android.

Three issues on Android

  1. App crashes if index=1 , I was expecting the selfie camera; index = 0 works as expected.
  2. How to release and attach the camera during on_pause() and on_resume() events ?
  3. on_camera_ready() is not called because on_index() is not called by default.

Despite the issues, the code is a joy to read. :)

Example code (not as pretty as I would like because no on_camera_ready) , and log for the first issue follow:

#!/usr/bin/env python
from kivy.app import App
from kivy.lang import Builder
from kivy.utils import platform
from kivy.clock import Clock
from os.path import isdir
from os import mkdir
try:
    from android.permissions import request_permissions, check_permission, \
        Permission
    from android.storage import primary_external_storage_path
except:
    pass

kv = """
#:import XCamera kivy_garden.xcamera.XCamera
FloatLayout:
    orientation: 'vertical'
    XCamera:
        id: xcamera
        on_picture_taken: app.picture_taken(*args)
        on_camera_ready: app.camera_ready()
    BoxLayout:
        orientation: 'horizontal'
        size_hint: 1, None
        height: sp(50)
        Button:
            text: 'Set landscape'
            on_release: xcamera.force_landscape()
        Button:
            text: 'Restore orientation'
            on_release: xcamera.restore_orientation()
"""

class CameraApp(App):
    def build(self):
        return Builder.load_string(kv)

    def on_start(self):
        if platform == 'android':
            # ISSUE 1 :
            # Crash when index =1 , index = 0 is OK
            self.root.ids.xcamera.index = 0
            request_permissions([Permission.WRITE_EXTERNAL_STORAGE,
                                 Permission.CAMERA],
                                self.setup_storage)
            self.setup_storage([],[])

    # ISSUE 2 : how to open and close camera ?
    def on_pause(self):
        return True

    def on_resume(self):
        pass

    def camera_ready(self):
        # In kv above     on_camera_ready: app.camera_ready()
        # ISSUE 3 :
        # This is never called because on_index is not called by default
        pass
        
    def setup_storage(self,permissions,grants):
        if platform == 'android':
            if check_permission(Permission.WRITE_EXTERNAL_STORAGE):
                path = join(primary_external_storage_path(),'Pictures')
                if not isdir(path):
                    mkdir(path)
                path = join(path,'Xcamera')
                if not isdir(path):
                    mkdir(path)
                self.root.ids.xcamera.directory = path
            if check_permission(Permission.CAMERA):
                # One sec hack because on_camera_ready() isnt called
                Clock.schedule_once(self.force_landscape,1)

    def force_landscape(self,dt):
        # Force long edge of image to be parallel to long edge of screen.
        # This is independent of the orientation of the screen in the world.
        # At least that is what happens on my Pixel 3
        self.root.ids.xcamera.force_landscape()

    def picture_taken(self, obj, filename):
        print('Picture taken and saved to {}'.format(filename))

def main():
    CameraApp().run()


if __name__ == '__main__':
    main()

Crash log

07-27 13:43:50.324 31415 31444 I python  : [INFO   ] [Base        ] Leaving application in progress...
07-27 13:43:50.324 31415 31444 I python  :  Traceback (most recent call last):
07-27 13:43:50.324 31415 31444 I python  :    File "/home/bobf/ex/xcam/.buildozer/android/app/main.py", line 91, in <module>
07-27 13:43:50.325 31415 31444 I python  :    File "/home/bobf/ex/xcam/.buildozer/android/app/main.py", line 87, in main
07-27 13:43:50.325 31415 31444 I python  :    File "/home/bobf/ex/xcam/.buildozer/android/platform/build-arm64-v8a/build/python-installs/xcam/kivy/app.py", line 855, in run
07-27 13:43:50.325 31415 31444 I python  :    File "/home/bobf/ex/xcam/.buildozer/android/platform/build-arm64-v8a/build/python-installs/xcam/kivy/base.py", line 504, in runTouchApp
07-27 13:43:50.325 26747 26747 W ActivityThread: handleWindowVisibility: no activity for token android.os.BinderProxy@79e1678
07-27 13:43:50.325 31415 31444 I python  :    File "/home/bobf/ex/xcam/.buildozer/android/platform/build-arm64-v8a/build/python-installs/xcam/kivy/core/window/window_sdl2.py", line 747, in mainloop
07-27 13:43:50.326 31415 31444 I python  :    File "/home/bobf/ex/xcam/.buildozer/android/platform/build-arm64-v8a/build/python-installs/xcam/kivy/core/window/window_sdl2.py", line 479, in _mainloop
07-27 13:43:50.326 31415 31444 I python  :    File "/home/bobf/ex/xcam/.buildozer/android/platform/build-arm64-v8a/build/python-installs/xcam/kivy/base.py", line 339, in idle
07-27 13:43:50.326 31415 31444 I python  :    File "/home/bobf/ex/xcam/.buildozer/android/platform/build-arm64-v8a/build/python-installs/xcam/kivy/clock.py", line 591, in tick
07-27 13:43:50.326 31415 31444 I python  :    File "kivy/_clock.pyx", line 384, in kivy._clock.CyClockBase._process_events
07-27 13:43:50.326 31415 31444 I python  :    File "kivy/_clock.pyx", line 414, in kivy._clock.CyClockBase._process_events
07-27 13:43:50.326 31415 31444 I python  :    File "kivy/_clock.pyx", line 412, in kivy._clock.CyClockBase._process_events
07-27 13:43:50.327 31415 31444 I python  :    File "kivy/_clock.pyx", line 167, in kivy._clock.ClockEvent.tick
07-27 13:43:50.327 31415 31444 I python  :    File "/home/bobf/ex/xcam/.buildozer/android/platform/build-arm64-v8a/build/python-installs/xcam/kivy/core/camera/camera_android.py", line 155, in _update
07-27 13:43:50.327 31415 31444 I python  :    File "kivy/_event.pyx", line 703, in kivy._event.EventDispatcher.dispatch
07-27 13:43:50.327 31415 31444 I python  :    File "kivy/_event.pyx", line 1214, in kivy._event.EventObservers.dispatch
07-27 13:43:50.328 31415 31444 I python  :    File "kivy/_event.pyx", line 1138, in kivy._event.EventObservers._dispatch
07-27 13:43:50.328 31415 31415 V SDL     : onWindowFocusChanged(): false
07-27 13:43:50.328 31415 31444 I python  :    File "/home/bobf/ex/xcam/.buildozer/android/platform/build-arm64-v8a/build/python-installs/xcam/kivy/uix/camera.py", line 111, in _camera_loaded
07-27 13:43:50.328 31415 31444 I python  :  AttributeError: 'NoneType' object has no attribute 'size'
07-27 13:43:50.328 31415 31444 I python  : Python for android ended.




iOS

Is XCAMERA usable by iOS? If not, will there be any plans on doing so?

Setup linting

The project has no linting setup, we should start with flake8 and isort to begin with.

Android - Xcamera crashes on some devices and APIs

On some (OLD) devices and (OLD) Android APIs, using -1 as index and forcing the resolution (as xcamera does by default ) the app crashes with this error:

Fail to connect to camera service

How to reproduce:

  • Set up via AVD a x86 device with a Android 5.0 x86 system image
  • Launch the example

xCamera windows appears tilted by -90 degrees

Hi, I have managed to integrate xCamera in my Kivy app for Android use the recommended requirements and code examples. The app is launching fine and able to take photographs. I initialized the XCamera object in Kivy instead of Python. One thing I noticed is that we have to let the camera auto-focus for a couple of seconds before clicking the picture, else it crashes.

The problem I have noticed is that my camera seems to initialize in the landscape mode by default. In the buildozer.spec file, the orientation is set to 'portrait' for the app. How can I make the camera view appear straight in portrait mode? Here is a screenshot of my problem. The door appears horizontal even if my phone is held upright. If turn around my phone, the camera view tilts even further by -90 degrees. How can I fix this?

If I use the force_landscape() method, the camera works as intended in the landscape mode, but then my app's orientation is also set to landscape mode permanently. It does not revert back to portrait mode even if I use the restore_orientation() method.

I am using Kivy 2.0.0 on Python 3.8.x. App packaged with buildozer. WRITE_EXTERNAL_STORAGE and CAMERA permissions are provided. Screenshot attached.

aa3d62fc-32b4-40d2-8a88-337134a962b9

Introduce Makefile entrypoint

Makefile is an interesting tool for automating/documenting some tasks.
Here's a list of things it could help with:

  • install project and requirements and system dependencies
  • run unit tests
  • run linting
  • run the demo
  • publish to PyPI
  • clean files

Class not found 'org/renpy/android/PythonActivity'

Builded my kivy apk with buildozer and installed on my Android 10 Pie (API 29), App crashes immediately after start and ADB Logcat give me this error.
After some days of research i founded the way to fix building the 1st apk only to populate the .buildozer folder and manually editing this file:

kivy_garden/xcamera/android_api.py

where at line 7 i changed:

AndroidPythonActivity = autoclass('org.renpy.android.PythonActivity')

with

AndroidPythonActivity = autoclass('org.kivy.android.PythonActivity').

This fix solves the error and Apk works as expected, but ther's a reason if github repo is not updated? Can someone consider to apply this update?
Or someone knows a way to set buildozer to auto edit this line before compile? Maybe a sort of patch?
Thanx for the help.

How to rotate the widget ?

Just as standard Camera widget that comes with Kivy, XCamera loads rotated 90 degrees on my Samsung.

with standard camera widget I can do:


Camera:
        id: camera
        canvas.before:
            PushMatrix:
            Rotate:
                angle: -90
                origin: root.width/2, root.height/2
        canvas.after:
            PopMatrix:

But when I do the same using XCamera the app crashes.
Any feedback much appreciated.

xcamera on Android

Why can I run xcamera on my PC, take photos and save them, but on Android platform, I can't save pictures

Widget shows only camera button and white screen

Widget shows camera button and white screen.
When i press camera button my debug says following:

04-23 10:41:02.293 20776 20951 I python : [WARNING] [Base ] Unknown provider
04-23 10:41:02.294 20776 20951 I python : [INFO ] [Base ] Start application main loop
04-23 10:43:11.955 20776 20951 I python : [INFO ] [xcamera ] starting autofocus...
04-23 10:43:11.960 20776 20951 I python : [INFO ] [Error when calling autofocus] JVM exception occurred: autoFocus failed java.lang.RuntimeException

on_camera_ready method is not fired.
Phone OS MIUI V12.012.0.QCSEUXM

Is this because platform is not supported, any way to investigate?

Just tried plyer camera. Looks like this is just a platform issue:

04-23 11:07:34.286 22391 22563 I python : Traceback (most recent call last):
04-23 11:07:34.287 22391 22563 I python : File "/home/to/KivyMD/demos/bafinfeh/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/myapp/armeabi-v7a/plyer/utils.py", line 93, in _ensure_obj
04-23 11:07:34.287 22391 22563 I python : File "/home/to/KivyMD/demos/bafinfeh/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/myapp/armeabi-v7a/plyer/platforms/android/camera.py", line 9, in
04-23 11:07:34.288 22391 22563 I python : File "/home/to/KivyMD/demos/bafinfeh/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/myapp/armeabi-v7a/jnius/reflect.py", line 229, in autoclass
04-23 11:07:34.288 22391 22563 I python : File "jnius/jnius_export_func.pxi", line 26, in jnius.jnius.find_javaclass
04-23 11:07:34.289 22391 22563 I python : File "jnius/jnius_utils.pxi", line 91, in jnius.jnius.check_exception
04-23 11:07:34.289 22391 22563 I python : jnius.jnius.JavaException: JVM exception occurred: Didn't find class "org.renpy.android.PythonActivity" on path: DexPathList[[zip file "/data/app/com.bafinfeh.logger.myapp-bwsgvvmgMmynmg3i2FETeg==/base.apk"],nativeLibraryDirectories=[/data/app/com.bafinfeh.logger.myapp-bwsgvvmgMmynmg3i2FETeg==/lib/arm, /data/app/com.bafinfeh.logger.myapp-bwsgvvmgMmynmg3i2FETeg==/base.apk!/lib/armeabi-v7a, /system/lib, /product/lib]] java.lang.ClassNotFoundException

xcamera freeze when returning from screen timeout "Android"

Hello Everyone.

I'm not a professional developer so be patient with me.

I have been playing with xcamera to create a little test app that allows me to open and takes photos on android. I modified a little bit the file xcamera.kv to delete the button by default and allows me to create my own shoot photo button.

My app start with an intermediate screen, a button moves from intermediate screen to the camera screen, I have noticed when android device goes to "screen timeout" (yiu can see this option in android settings) that xcamera freeze and app needs to be reloaded, I don't know if this its a bug or there is a way to connect and disconnect the camera when entering/leaving the camera screen.

Really appreciate your help guys.

Attached my code, my buildozer spec and my xcamera.kv modified.

from kivy.lang import Builder
from kivymd.app import MDApp
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import ObjectProperty,StringProperty,BooleanProperty
from kivy.uix.widget import Widget
from kivymd.uix.button import MDFillRoundFlatButton
from kivymd.uix.button import MDRectangleFlatButton
from kivymd.uix.button import MDFlatButton
from kivymd.uix.button import MDRaisedButton
from kivymd.uix.dialog import MDDialog
from kivymd.uix.list import OneLineAvatarIconListItem
from kivymd.uix.menu import MDDropdownMenu
from kivymd.theming import ThemeManager
from kivy.uix.boxlayout import BoxLayout
from kivy.clock import Clock
from kivymd.toast import toast
import time
from kivy.clock import mainthread
from kivy_garden.xcamera import XCamera
import os

KV = '''

WindowManager:
UnassignedLabelScreen:
Camara:

:
name:"uls"
canvas.before:
Rectangle:
pos: self.pos
size: self.size
source:"background.png"
MDToolbar:
pos_hint: {'top':1}
title: "MLCourier"
right_action_items: [["dots-vertical", lambda x: app.open_settings()]]
left_action_items: [["arrow-left", lambda x:root.manager.change_screen("actionscreen")]]

MDTextField:
    id:labels
    hint_text: "Number of Labels"
    #helper_text: "Enter the number of labels to print"
    mode: "rectangle"
    helper_text_mode: "on_focus"
    pos_hint: {"center_x":0.5, "center_y":0.5}
    size_hint_x:None
    width:dp(300)

#MDRectangleFlatButton:
MDRaisedButton:
    pos_hint: {"center_x":0.5, "center_y":0.2}
    text: "Take Photos"
    size_hint:(0.4,0.1)
    #text_color: 0, 0, 1, 1
    on_release:
        app.root.current="camara"
        root.manager.transition.direction = "left"

:
#:import XCamera kivy_garden.xcamera.XCamera
name:"camara"
BoxLayout:
size_hint_y: 1
pos_hint: {'top':1}
orientation: "vertical"
MDToolbar:
title: "TEST"
right_action_items: [["dots-vertical", lambda x: app.open_settings()]]
left_action_items: [["arrow-left", lambda x:root.manager.change_screen("uls")]]

    BoxLayout:
        size_hint_y: 1
        pos_hint: {'top':1}
        orientation: 'horizontal'
        padding:10
        spacing:10 
        Widget:
            id:proxy
            XCamera:
                id:xcamera
                allow_stretch: False
                keep_ratio: True
                #size:self.size
                center:self.size and proxy.center
                size:(proxy.height,proxy.width)          
                canvas.before:
                    PushMatrix
                    Rotate:
                        angle:-90
                        origin:self.center
                canvas.after:
                    PopMatrix
                on_picture_taken: app.picture_taken(*args)
    
    BoxLayout:
        size_hint_y: 0.5
        pos_hint: {'top':1}
        orientation: 'vertical'
        #padding:10
        #spacing:10 

        BoxLayout:
            size_hint_y: 1
            pos_hint: {'top':1}
            orientation: 'horizontal'
            #padding:10
            #spacing:10 

            BoxLayout:
                size_hint_y: 1
                pos_hint: {'top':1}
                orientation: 'horizontal'
                padding:10
                spacing:10 
                MDRaisedButton:
                    pos_hint: {"center_x":0.5, "center_y":0.5}
                    size_hint:1,0.5
                    text: "TAKE PHOTO"
                    #text_color: 0, 0, 1, 1
                    #width:dp(600)
                    on_release:
                        xcamera.shoot()

        BoxLayout:
            orientation: "horizontal"
            BoxLayout:
                #size:100,100
                #pos: root.pos
                size_hint_y: 1
                pos_hint: {'top':1}
                orientation: 'horizontal'
                padding:10
                spacing:10
                BoxLayout:
                    id:ph1
                    canvas.before:
                        PushMatrix
                        Rotate:
                            angle:-90
                            origin: self.center
                    canvas.after:
                        PopMatrix
                    Image:
                        source:app.photo1
            BoxLayout:
                #size:100,100
                #pos: root.pos
                size_hint_y: 1
                pos_hint: {'top':1}
                orientation: 'horizontal'
                padding:10
                spacing:10
                BoxLayout:
                    id:ph2
                    canvas.before:
                        PushMatrix
                        Rotate:
                            angle:-90
                            origin: self.center
                    canvas.after:
                        PopMatrix
                    Image:
                        source:app.photo2
            
            BoxLayout:
                #size:100,100
                #pos: root.pos
                size_hint_y: 1
                pos_hint: {'top':1}
                orientation: 'horizontal'
                padding:10
                spacing:10
                BoxLayout:
                    id:ph3
                    canvas.before:
                        PushMatrix
                        Rotate:
                            angle:-90
                            origin: self.center
                    canvas.after:
                        PopMatrix
                    Image:
                        source:app.photo3
            BoxLayout:
                #size:100,100
                #pos: root.pos
                size_hint_y: 1
                pos_hint: {'top':1}
                orientation: 'horizontal'
                padding:10
                spacing:10
                BoxLayout:
                    id:ph4
                    canvas.before:
                        PushMatrix
                        Rotate:
                            angle:-90
                            origin: self.center
                    canvas.after:
                        PopMatrix
                    Image:
                        source:app.photo4

        BoxLayout:
            size_hint_y: 1
            pos_hint: {'top':1}
            orientation: 'horizontal'
            #padding:10
            #spacing:10 

            BoxLayout:
                size_hint_y: 1
                pos_hint: {'top':1}
                orientation: 'horizontal'
                padding:10
                spacing:10 
            
                MDRaisedButton:
                    size_hint:1,0.5
                    pos_hint: {"center_x":0.5, "center_y":0.5}
                    text: "DELETE PHOTOS"
                    #text_color: 0, 0, 1, 1
                    #width:dp(600)
                    on_release:
                        app.clearimage()

'''
class WindowManager(ScreenManager):

def change_screen(self, screen):
    # the same as in .kv: app.root.current = screen
    self.current = screen

class Camara(Screen):
pass

class UnassignedLabelScreen(Screen):
pass

class Test(MDApp):

photo1=ObjectProperty('photo_background.png', allownone=True)
photo2=ObjectProperty('photo_background.png', allownone=True)
photo3=ObjectProperty('photo_background.png', allownone=True)
photo4=ObjectProperty('photo_background.png', allownone=True)
exc_num_pics=BooleanProperty()


def build(self):
    self.theme_cls.primary_palette="Blue"
    self.theme_cls.primary_hue = "900"
    self.sm = ScreenManager()
    self.num_pics=0
    self.exc_num_pics=True
    
    return Builder.load_string(KV)


@mainthread
def clearimage(self):
    if self.photo1!='photo_background.png':
        os.remove(str(self.photo1))
        self.photo1='photo_background.png'
    if self.photo2!='photo_background.png':
        os.remove(str(self.photo2))
        self.photo2='photo_background.png'
    if self.photo3!='photo_background.png':
        os.remove(str(self.photo3))
        self.photo3='photo_background.png'
    if self.photo4!='photo_background.png':
        os.remove(str(self.photo4))
        self.photo4='photo_background.png'
    
    self.num_pics=0


@mainthread
def picture_taken(self, obj, filename):

    if self.num_pics==0:
        self.photo1=str(filename)
        print('Picture taken and saved to {}'.format(filename))
    if self.num_pics==1:
        self.photo2=str(filename)
        print('Picture taken and saved to {}'.format(filename))
    if self.num_pics==2:
        self.photo3=str(filename)
        print('Picture taken and saved to {}'.format(filename))
    if self.num_pics==3:
        self.photo4=str(filename)
        print('Picture taken and saved to {}'.format(filename))
    
    self.num_pics=self.num_pics+1

    if self.num_pics>3:
        self.exc_num_pics=False
        toast("No more than 4 pics are allowed!")

Test().run()

Buildozer.spec:
[app]

(str) Title of your application

title = PhotoTest

(str) Package name

package.name = PhotoTestApp

(str) Package domain (needed for android/ios packaging)

package.domain = org.test

(str) Source code where the main.py live

source.dir = .

(list) Source files to include (let empty to include all the files)

source.include_exts = py,png,jpg,kv,atlas,ttf,wav

(list) List of inclusions using pattern matching

#source.include_patterns = assets/,images/.png

(list) Source files to exclude (let empty to not exclude anything)

#source.exclude_exts = spec

(list) List of directory to exclude (let empty to not exclude anything)

#source.exclude_dirs = tests, bin

(list) List of exclusions using pattern matching

#source.exclude_patterns = license,images//.jpg

(str) Application versioning (method 1)

version = 0.1

(str) Application versioning (method 2)

version.regex = version = '"['"]

version.filename = %(source.dir)s/main.py

(list) Application requirements

comma separated e.g. requirements = sqlite3,kivy

requirements =
android,
Pillow,
Kivy==1.11.1,
python3,
kivymd,
plyer

(str) Custom source folders for requirements

Sets custom source for any requirements with recipes

#requirements.source.kivy = ../../kivy

(list) Garden requirements

#garden_requirements=mapview

(str) Presplash of the application

#presplash.filename = %(source.dir)s/data/presplash.png

(str) Icon of the application

#icon.filename = %(source.dir)s/data/icon.png

(str) Supported orientation (one of landscape, sensorLandscape, portrait or all)

orientation = portrait

(list) List of service to declare

#services = NAME:ENTRYPOINT_TO_PY,NAME2:ENTRYPOINT2_TO_PY

OSX Specific

author = © Copyright Info

change the major version of python used by the app

osx.python_version = 3

Kivy version to use

osx.kivy_version = 1.9.1

Android specific

(bool) Indicate if the application should be fullscreen or not

fullscreen = 0

(string) Presplash background color (for new android toolchain)

Supported formats are: #RRGGBB #AARRGGBB or one of the following names:

red, blue, green, black, white, gray, cyan, magenta, yellow, lightgray,

darkgray, grey, lightgrey, darkgrey, aqua, fuchsia, lime, maroon, navy,

olive, purple, silver, teal.

#android.presplash_color = #FFFFFF

(list) Permissions

android.permissions = INTERNET,CAMERA

(int) Target Android API, should be as high as possible.

android.api = 27

(int) Minimum API your APK will support.

android.minapi = 21

(int) Android SDK version to use

android.sdk = 20

(str) Android NDK version to use

android.ndk = 19b

(int) Android NDK API to use. This is the minimum API your app will support, it should usually match android.minapi.

android.ndk_api = 21

(bool) Use --private data storage (True) or --dir public storage (False)

#android.private_storage = True

(str) Android NDK directory (if empty, it will be automatically downloaded.)

#android.ndk_path =

(str) Android SDK directory (if empty, it will be automatically downloaded.)

#android.sdk_path =

(str) ANT directory (if empty, it will be automatically downloaded.)

#android.ant_path =

(bool) If True, then skip trying to update the Android sdk

This can be useful to avoid excess Internet downloads or save time

when an update is due and you just want to test/build your package

android.skip_update = False

(bool) If True, then automatically accept SDK license

agreements. This is intended for automation only. If set to False,

the default, you will be shown the license when first running

buildozer.

android.accept_sdk_license = True

(str) Android entry point, default is ok for Kivy-based app

#android.entrypoint = org.renpy.android.PythonActivity

(str) Android app theme, default is ok for Kivy-based app

android.apptheme = "@android:style/Theme.NoTitleBar"

(list) Pattern to whitelist for the whole project

#android.whitelist =

(str) Path to a custom whitelist file

#android.whitelist_src =

(str) Path to a custom blacklist file

#android.blacklist_src =

(list) List of Java .jar files to add to the libs so that pyjnius can access

their classes. Don't add jars that you do not need, since extra jars can slow

down the build process. Allows wildcards matching, for example:

OUYA-ODK/libs/*.jar

#android.add_jars = foo.jar,bar.jar,path/to/more/*.jar

(list) List of Java files to add to the android project (can be java or a

directory containing the files)

#android.add_src =

(list) Android AAR archives to add (currently works only with sdl2_gradle

bootstrap)

#android.add_aars =

(list) Gradle dependencies to add (currently works only with sdl2_gradle

bootstrap)

#android.gradle_dependencies =

(list) add java compile options

this can for example be necessary when importing certain java libraries using the 'android.gradle_dependencies' option

see https://developer.android.com/studio/write/java8-support for further information

android.add_compile_options = "sourceCompatibility = 1.8", "targetCompatibility = 1.8"

(list) Gradle repositories to add {can be necessary for some android.gradle_dependencies}

please enclose in double quotes

e.g. android.gradle_repositories = "maven { url 'https://kotlin.bintray.com/ktor' }"

#android.add_gradle_repositories =

(list) packaging options to add

see https://google.github.io/android-gradle-dsl/current/com.android.build.gradle.internal.dsl.PackagingOptions.html

can be necessary to solve conflicts in gradle_dependencies

please enclose in double quotes

e.g. android.add_packaging_options = "exclude 'META-INF/common.kotlin_module'", "exclude 'META-INF/*.kotlin_module'"

#android.add_gradle_repositories =

(list) Java classes to add as activities to the manifest.

#android.add_activites = com.example.ExampleActivity

(str) OUYA Console category. Should be one of GAME or APP

If you leave this blank, OUYA support will not be enabled

#android.ouya.category = GAME

(str) Filename of OUYA Console icon. It must be a 732x412 png image.

#android.ouya.icon.filename = %(source.dir)s/data/ouya_icon.png

(str) XML file to include as an intent filters in tag

#android.manifest.intent_filters =

(str) launchMode to set for the main activity

#android.manifest.launch_mode = standard

(list) Android additional libraries to copy into libs/armeabi

#android.add_libs_armeabi = libs/android/.so
#android.add_libs_armeabi_v7a = libs/android-v7/
.so
#android.add_libs_arm64_v8a = libs/android-v8/.so
#android.add_libs_x86 = libs/android-x86/
.so
#android.add_libs_mips = libs/android-mips/*.so

(bool) Indicate whether the screen should stay on

Don't forget to add the WAKE_LOCK permission if you set this to True

#android.wakelock = False

(list) Android application meta-data to set (key=value format)

#android.meta_data =

(list) Android library project to add (will be added in the

project.properties automatically.)

#android.library_references =

(list) Android shared libraries which will be added to AndroidManifest.xml using tag

#android.uses_library =

(str) Android logcat filters to use

#android.logcat_filters = *:S python:D

(bool) Copy library instead of making a libpymodules.so

#android.copy_libs = 1

(str) The Android arch to build for, choices: armeabi-v7a, arm64-v8a, x86, x86_64

android.arch = armeabi-v7a

Python for android (p4a) specific

(str) python-for-android fork to use, defaults to upstream (kivy)

#p4a.fork = kivy

(str) python-for-android branch to use, defaults to master

p4a.branch = v2020.04.29

(str) python-for-android git clone directory (if empty, it will be automatically cloned from github)

#p4a.source_dir =

(str) The directory in which python-for-android should look for your own build recipes (if any)

#p4a.local_recipes =

(str) Filename to the hook for p4a

#p4a.hook =

(str) Bootstrap to use for android builds

p4a.bootstrap = sdl2

(int) port number to specify an explicit --port= p4a argument (eg for bootstrap flask)

#p4a.port =

iOS specific

(str) Path to a custom kivy-ios folder

#ios.kivy_ios_dir = ../kivy-ios

Alternately, specify the URL and branch of a git checkout:

ios.kivy_ios_url = https://github.com/kivy/kivy-ios
ios.kivy_ios_branch = master

Another platform dependency: ios-deploy

Uncomment to use a custom checkout

#ios.ios_deploy_dir = ../ios_deploy

Or specify URL and branch

ios.ios_deploy_url = https://github.com/phonegap/ios-deploy
ios.ios_deploy_branch = 1.7.0

(str) Name of the certificate to use for signing the debug version

Get a list of available identities: buildozer ios list_identities

#ios.codesign.debug = "iPhone Developer: ()"

(str) Name of the certificate to use for signing the release version

#ios.codesign.release = %(ios.codesign.debug)s

[buildozer]

(int) Log level (0 = error only, 1 = info, 2 = debug (with command output))

log_level = 2

(int) Display warning if buildozer is run as root (0 = False, 1 = True)

warn_on_root = 1

(str) Path to build artifact storage, absolute or relative to spec file

build_dir = ./.buildozer

(str) Path to build output (i.e. .apk, .ipa) storage

bin_dir = ./bin

-----------------------------------------------------------------------------

List as sections

You can define all the "list" as [section:key].

Each line will be considered as a option to the list.

Let's take [app] / source.exclude_patterns.

Instead of doing:

#[app]
#source.exclude_patterns = license,data/audio/.wav,data/images/original/

This can be translated into:

#[app:source.exclude_patterns]
#license
#data/audio/.wav
#data/images/original/

-----------------------------------------------------------------------------

Profiles

You can extend section / key with a profile

For example, you want to deploy a demo version of your application without

HD content. You could first change the title to add "(demo)" in the name

and extend the excluded directories to remove the HD content.

#[app@demo]
#title = My Application (demo)

#[app:source.exclude_patterns@demo]
#images/hd/*

Then, invoke the command line with the "demo" profile:

#buildozer --profile demo android debug

xcamera.kv

#:import xcamera kivy_garden.xcamera.xcamera

# icon_color: (0, 0, 0, 1) # _down_color: xcamera.darker(self.icon_color) # icon_size: dp(50)
# canvas.before:
#     Color:
#         rgba: self.icon_color if self.state == 'normal' else self._down_color
#     Ellipse:
#         pos: self.pos
#         size: self.size

# size_hint: None, None
# size: self.icon_size, self.icon_size
# font_size: self.icon_size/2

:
# \ue800 corresponds to the camera icon in the font
icon: u"[font=data/icons.ttf]\ue800[/font]"
icon_color: (0.13, 0.58, 0.95, 0.8)
icon_size: dp(70)

id: camera
resolution: 640, 480 # 1920, 1080
allow_stretch: True

# Shoot button
XCameraIconButton:
    # id: shoot_button
    # markup: True
    # text: root.icon
    # icon_color: root.icon_color
    # icon_size: root.icon_size
    # on_release: root.shoot()

    # # position
    # right: root.width - dp(10)
    # center_y: root.center_y

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.