the code from this site is not working for me: https://kivy.org/doc/stable/examples/gen__camera__main__py.html
It works perfectly on my pc. However, when I push it to my android phone with
buildozer -v android debug deploy run
The camera opens up normally and when I press 'Capture', it acts as if it takes a picture. However, when I look into the phone's gallery, I can't find any new picture. Is the picture saved somewhere that's not in the gallery? My app has a few more steps to upload that pic to google firebase. And it can never find the recently taken pic in the root directory. Again, it's working perfectly on PC. My buildozer spec is:
Permissionsandroid.permissions = INTERNET,CAMERA,WRITE_EXTERNAL_STORAGE,READ_EXTERNAL_STORAGE
I tried WRITE_INTERNAL_STORAGE and it didn't like it. So I guess writing to internal storage permission is given by default.
Another minor issue: the screen on the app is flipped sideways. It's showing the correct live pic but it's a bit weird. I tried switching between 'vertical' and 'horizontal' in the Builder.load_string but nothing changes.
Please assist. I appreciate any input.
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
import time
Builder.load_string('''
<CameraClick>:
orientation: 'vertical'
Camera:
id: camera
resolution: (640, 480)
play: False
ToggleButton:
text: 'Play'
on_press: camera.play = not camera.play
size_hint_y: None
height: '48dp'
Button:
text: 'Capture'
size_hint_y: None
height: '48dp'
on_press: root.capture()
''')
class CameraClick(BoxLayout):
def capture(self):
'''
Function to capture the images and give them the names
according to their captured time and date.
'''
camera = self.ids['camera']
timestr = time.strftime("%Y%m%d_%H%M%S")
camera.export_to_png("IMG_{}.png".format(timestr))
print("Captured")
class TestCamera(App):
def build(self):
return CameraClick()
TestCamera().run()````
I have figured it out. Somehow the root directory doesn't work. To make it work, simply change
camera.export_to_png("IMG_{}.png".format(timestr))
to
camera.export_to_png("/sdcard/IMG_{}.png".format(timestr))
Related
I am trying to create a ListView widget in Kivy, but cannot; am using Python 3.10 and Kivy 2.0. Later I changed it to RecycleView. Window is opening but items in the item_strings property of RecycleView are not getting displayed.
AddLocationForm:
<AddLocationForm#BoxLayout>:
orientation: 'vertical'
BoxLayout:
TextInput:
Button:
text: 'Search'
Button:
text: 'Current Location'
RecycleView:
item_strings: ["Kolkata", 'New Delhi']
My main.py is as follows:
from kivy.app import App
class WeatherApp(App):
pass
if __name__ == '__main__':
app = WeatherApp()
app.run()
Can you help me out.
i'm working on a qr code scanner using kivy zbarcam, I managed to make it work but the problem is the camera initializes right away and does not release the camera after leaving the screen. I tried zbarcam.stop() and root.ids.zbarcam_id.ids.xcamera.play=False but what it does is just unscheduling and doesn't really release the use of camera. I tried to build this in buildozer but it's so slow since the camera is using a lot of memory even when not in use.
Can somebody know what is the workaround on this?
This is my code:
from kivy.lang.builder import Builder
from kivy.uix.screenmanager import Screen
from kivy.clock import Clock
from kivymd.app import MDApp
class QRScreen(Screen):
pass
class LoginScreen(Screen):
pass
class ScannerScreen(Screen):
def __init__(self, **kwargs):
super().__init__(**kwargs)
Clock.schedule_once(self._after_init)
# self.ids.zbarcam_id.ids.xcamera.play=True
def _after_init(self, dt):
"""
Binds `ZBarCam.on_symbols()` event.
"""
zbarcam = self.ids.zbarcam_id
zbarcam.bind(symbols=self.on_symbols)
def on_symbols(self, zbarcam, symbols):
"""
Loads the first symbol data to the `QRFoundScreen.data_property`.
"""
# going from symbols found to no symbols found state would also
# trigger `on_symbols`
if not symbols:
return
symbol = symbols[0]
data = symbol.data.decode('utf8')
print(data)
self.manager.get_screen('qr').ids.data.text= data
self.manager.transition.direction = 'left'
self.manager.current = 'qr'
def on_leave(self):
zbarcam = self.ids.zbarcam_id
zbarcam.stop()
class DemoApp(MDApp):
def build(self):
# screen =Screen()
self.title='Demeter'
self.theme_cls.theme_style = "Dark"
self.theme_cls.primary_palette = "DeepPurple"
self.help = Builder.load_file('main.kv')
return self.help
DemoApp().run()
kv file:
#:import ZBarCam kivy_garden.zbarcam.ZBarCam
ScreenManager:
LoginScreen:
ScannerScreen:
QRScreen:
<LoginScreen>:
name: "login"
MDFlatButton:
text:'release'
on_press:
root.manager.current = 'scanner'
root.manager.transition.direction = "right"
<ScannerScreen>:
name: 'scanner'
ZBarCam:
id: zbarcam_id
play: False
MDFlatButton:
id: iyu
text:'release'
on_press:
root.ids.zbarcam_id.ids.xcamera.play=False
MDFlatButton:
id: ads
text:'replay'
pos_hint: {"center_x": 0.5, "center_y": 0.95}
on_press:
root.ids.zbarcam_id.ids.xcamera.play=True
<QRScreen>:
name: 'qr'
MDIconButton:
icon:'arrow-left'
pos_hint: {'center_x':0.1,'center_y':0.95}
on_press:
root.manager.current = 'scanner'
root.manager.transition.direction = "right"
MDLabel:
id:data
text: "asdgasda"
pos_hint: {'center_y':0.5}
theme_text_color: "Custom"
text_color: 0, 1, 0, 1
I was having the same problem and finally found the solution (based on this)
In my case I initate ZBarCam in the .py file instead of .kv (see example).
To actually close the camera, you can call the following:zbarcam.ids['xcamera']._camera._device.release() in your on_leave() function.
If you initiate/manage ZBarCam in the .kv, I think that the equivalent would be something like: root.ids.zbarcam.ids.xcamera._camera._device.release()
If compiled with buildzoner for Android, I have to use self.zbarcam.ids['xcamera']._camera = None instead
I have the same error, I already install garden, kivy-garden, kivy, kivymd, pyzbar, and all the requriments in the buildozer.spec file, but when I run it, the log said ModuleNotFoundError: No module named 'kivy_garden.zbarcam', I have being trying a lot of solutions in other requriments, but any of that works.
Simply put, I would like to use a small USB keypad/numpad to type into a text input field on a kivy app running on android via the kivy launcher.
I am using an OTG USB connector to connect a small keypad to my tablet. The connector works in general on the tablet (I can type in numbers in the browser and other apps). In a kivy app however, when I use the touchscreen to select a text input field, it focuses awaiting input, then if I try to type in with the numpad, nothing happens. After doing some testing with a normal sized USB keyboard, it works (but the numpad on it doesn't).
Here is the basic kivy app I used to test this out with:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
KV = """
<MyScreenManager>:
KeyboardInput:
name: 'KeyInput'
<KeyboardInput>:
GridLayout:
rows: 3
TextInput:
id: input1
text:''
multiline: False
Widget:
TextInput:
id: input2
text:''
multiline: False
"""
class KeyboardInput(Screen):
pass
class MyScreenManager(ScreenManager):
def changescreen(self, value):
try:
if value!='Go To...':
self.current = value
except:
print('No screen named ' + value)
#Main application
class packagingDiscardmentApp(App):
def build(self):
Builder.load_string(KV)
self.sm = MyScreenManager()
return self.sm
if __name__ == '__main__':
packagingDiscardmentApp().run()
My guess is that there is some issue with the ascii characters on the numpad and Kivy. Any help would be greatly appreciated.
I'm building an Android App, using Kivy and Python 2.7, which is going to unlock the phone based on Face Recognition. After downloading the App and initializing it, I would like the App to be opened directly when Slide To Unlock the phone, open a specific screen "The Recognizer Screen, recognize my face and then Unlock the phone.
What should I add to the .KV code or even to the .py code to root the Slide To Unlock to my app?
For example, if this is my .KV code
<ScreenFour>:
name: "screen4"
id: screen_four
FloatLayout:
canvas:
Rectangle:
source: "image1.jpg"
pos:self.pos
size:self.size
Button:
text: 'Next'
font_size: 32 # font size
size_hint: .2,.1
pos_hint:{'right':1, 'y':0}
on_release: app.root.current="screen5"
Button:
text: "Unlock the phone"
font_size: 20
pos_hint:{'right':0.5, 'y':0.5}
size_hint: 0.4,0.2
on_release: app.fr()
where one_release: app.fr() is the root to start the FaceRecognizer code
What do I have to add to this code? Or do I have to add any thing to the Python code on the specific
class ScreenFour(Screen):
pass
Or do I have to add it here:
class FaceRecognitionApp(App):
def fg(self):
FaceGenerator()
def fr(self):
FaceRecognizer()
def build(self):
return sm
if __name__=="__main__":
FaceRecognitionApp().run()
I would really appreciate having an answer, I'm working on a project and I'm running out of time.
Please i am looking for a work around to get access Android camera through kivy, or a library that i can integrate with kivy in order to access the Camera.
I am developing an application for android but using python-kivy for the UI,
anything will be really appreciated,
thanks alot.
Here's my sample code, that works on Android. Just import that file https://github.com/kivy/plyer/blob/master/plyer/platforms/android/camera.py
Also, don't forget to add CAMERA permissions to manifest.
main.py:
__version__ = '1.0'
import kivy
# importing file from https://github.com/kivy/plyer/blob/master/plyer/platforms/android/camera.py
# I downloaded it and saved it in the same directory:
from camera import AndroidCamera
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty, StringProperty
import base64
class MyCamera(AndroidCamera):
pass
class BoxLayoutW(BoxLayout):
my_camera = ObjectProperty(None)
# /sdcard means internal mobile storage for that case:
image_path = StringProperty('/sdcard/my_test_photo.png')
def __init__(self, **kwargs):
super(BoxLayoutW, self).__init__()
self.my_camera = MyCamera()
def take_shot(self):
self.my_camera._take_picture(self.on_success_shot, self.image_path)
def on_success_shot(self, loaded_image_path):
# converting saved image to a base64 string:
image_str = self.image_convert_base64
return True
#converting image to a base64, if you want to send it, for example, via POST:
def image_convert_base64(self):
with open(self.image_path, "rb") as image_file:
encoded_string = base64.b64encode(image_file.read())
if not encoded_string:
encoded_string = ''
return encoded_string
if __name__ == '__main__':
class CameraApp(App):
def build(self):
main_window = BoxLayoutW()
return main_window
CameraApp().run()
camera.kv:
<BoxLayoutW>:
Button:
text: 'shot'
on_release: root.take_shot()
Kivy has some native support for calling the camera. Check out this page from the new programming guide for a core provider or this page from the new programming guide for a uix widget. In theory, the core should be able to adapt between platforms and the widget should then be able to use the camera.
This links to a discution where a custom implementation can be found. It is based on PyJNIus's automatic wrapping of the android API's Camera class.
Didn't try myself but you can give it a try...
thanks to this post i was able to solve a critical problem in my app thanks a lot guys here is my code that i used i hope that you guys can use it somewhere.
I made a screen and used the plyer camera function
from os import getcwd
from os.path import exists
from os.path import splitext
import kivy
kivy.require('1.8.0')
from kivy.app import App
from kivy.properties import ObjectProperty
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.popup import Popup
from kivy.logger import Logger
from plyer import camera
i also used some other imports for the screens and the labels and popups etc which you can definatly look into depending upon your requirment
class ScreenFive(Screen): #camera screen
def gg1back(self):
self.parent.current = 'First'
def do_capture(self):
filepath = 'IMG_1.jpg'
ext = splitext(filepath)[-1].lower()
try:
camera.take_picture(self.camera_callback,filepath)
except NotImplementedError:
popup = MsgPopup(
"The Face_rec_image feature has not yet \n been implemented for this platform :(")
popup.open()
def camera_callback(self, filepath):
if(exists(filepath)):
popup = MsgPopup("Picture saved!")
popup.open()
else:
popup = MsgPopup("Could not save your picture!")
popup.open()
As it was hard for me to find the answer how to use camera on android I thought I'll share my journey to the answer to save next person's time.
I couldn't find the way to make work Camera class straight from Kivy:
https://kivy.org/docs/examples/gen__camera__main__py.html
finally I found the solution posted above, and after wasting some time implementing it in my app it turned out it was impossible for me to return to the app after photo being taken - the app was terminated, so I couldn't go back to the app to make use of the picture (I was using Kivy Launcher).
Just recently I found out this way of accessing Camera was abandoned (https://github.com/kivy/plyer/issues/16#issuecomment-54094174 )
But then I found the solution below and by just running the example code it looks like I will be able to get results I want (it just needs a little tweaking not to crash when android camera is canceled/no photo has been taken)
https://github.com/kivy/kivy/tree/master/examples/android/takepicture
EDIT:
appears my app was terminated because I didn't implement on_pause: return True in topmost widget. Nevertheless the text above still might be helpful
Some years later, the Android API has changed as to how it deals with permissions and storage providers.
I have a full working example for the Android camera through Kivy here. It basically requires some tweaking of the compiled manifest file in python-for-android, as well as working directly with the FileProvider.