Simple Camera With Kivy
FleetingThe simple pwa offline camera works well, but has one issue: it reloads when scrolling down.
Let’s try building a simple camera with kivy, using the camera example as basis.
from kivy.app import App
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.uix.floatlayout import FloatLayout
from jnius import autoclass
import time
from android.runnable import run_on_ui_thread
from kivy.animation import Animation
from kivy import platform
import plyer
Builder.load_string('''
<CameraClick>:
Camera:
id: camera
resolution: (640, 480)
# resolution: (-1, -1) # best
play: True
allow_stretch: True
Button:
id: button
pos: ((self.parent.width - self.width), (self.parent.height - self.height) / 2)
size_hint: (None, None)
size: (200, 200)
on_press: root.capture()
background_color: (1, 1, 1, 0) # transparent
AsyncImage:
source: "https://cdn.icon-icons.com/icons2/865/PNG/96/Citycons_camera_icon-icons.com_67912.png"
allow_stretch: True
keep_ratio: True
# center in the parent button
y: self.parent.y + self.parent.height / 2 - self.height / 2
x: self.parent.x + self.parent.width / 2 - self.width / 2
# fit to the parent button (keep_ratio will prevent it from being distorded)
size: (self.parent.width, self.parent.height)
''')
class CameraClick(FloatLayout):
def __init__(self, *args, **kwargs):
super(CameraClick, self).__init__(*args, **kwargs)
self.doing = False
print("camera click")
def done(self, *args):
self.doing = False
def shoot(self, *args):
timestr = time.strftime("%Y%m%d_%H%M%S")
camera = self.ids['camera']
camera.export_to_png("/sdcard/Download/IMG_{}.png".format(timestr))
button = self.ids['button']
self.anim2 = Animation(background_color=(0, 0, 0, 1), duration=0.5)
self.anim2 &= Animation(size=(200, 200), duration=0.3)
self.anim2 &= Animation(pos=((self.width - 200), (self.height - 200) / 2), duration=0.5)
self.anim2.bind(on_complete=self.done)
self.anim2.start(button)
def capture(self):
if self.doing:
return
self.doing = True
button = self.ids['button']
self.anim = Animation(background_color=(1, 1, 1, 1), duration=0.2)
self.anim &= Animation(size=(self.height, self.height), duration=0.2)
self.anim &= Animation(pos=((self.width - self.height) / 2, 0), duration=0.2)
self.anim.bind(on_complete=self.shoot)
self.anim.start(button)
class TestCamera(App):
def build(self):
Window.bind(on_keyboard=self.hook_keyboard)
# the following only works on android recent enough
plyer.orientation.set_landscape()
# self.do_window_stuff()
return CameraClick()
@run_on_ui_thread
def do_window_stuff(self):
from android import mActivity
View = autoclass('android.view.View')
Context = autoclass('android.content.Context')
PowerManager = autoclass('android.os.PowerManager')
option = View.SYSTEM_UI_FLAG_FULLSCREEN
pm = mActivity.getSystemService(Context.POWER_SERVICE)
wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, 'TAG')
wl.acquire()
mActivity.getWindow().getDecorView().setSystemUiVisibility(option)
def hook_keyboard(self, window, key, *args):
if key == 27:
# exit(0)
return False
def run():
TestCamera().run()