如何使用 kivy 为移动应用程序制作相机小部件
Posted
技术标签:
【中文标题】如何使用 kivy 为移动应用程序制作相机小部件【英文标题】:how to make camera widget for mobile apps with kivy 【发布时间】:2021-11-01 08:17:33 【问题描述】:我正在尝试在我的应用程序中添加一个摄像头,我希望摄像头处于全屏模式,并且我希望它在移动设备上是垂直的而不是水平的。我希望相机在单击按钮捕获后停止捕获图像。我试图做到这一点,这是我的代码,但它不起作用
camera_widget = '''
MDBoxLayout:
rows:2
Camera:
orientation: 'vertical'
id: camera
size:app.screen.size
resolution:(720, 480)
Rotate:
origin:self.center
angle:-90'''
def menue_arabic_camera(self,*args):
self.screen.clear_widgets()
return_back = MDFlatButton(text=self.ar_text("العودة للخلف"),
pos_hint='center_x': .5, 'center_y': .02,
on_press=self.selection_load_cam_ar,
font_name='DROIDKUFI-REGULAR.TTF')
self.screen.add_widget(return_back)
self.SHEET = Builder.load_string(camera_widget)
self.screen.add_widget(self.SHEET)
CAPTURE = MDFlatButton(text="Capture",
pos_hint='center_x': .5, 'center_y': .05,
on_press=self.capture)
def capture(self,*args):
camera = self.SHEET.ids['camera']
camera.play = not camera.play
self.save_img()
name = "User_sheet"
camera.export_to_png("IMG_.png".format(name))
【问题讨论】:
【参考方案1】:您可以使用着色器指令以及带有摄像头 java 类的 pyjnius 模块,该类具有新的实现功能,包括来自设备的纹理(如果您使用的是 android 设备),如果您使用的是 PC,则此示例可能无法运行,因为它使用带有python、jbsidis的android类:
from jnius import autoclass, PythonJavaClass, java_method
Camera = autoclass('android.hardware.Camera')
SurfaceTexture = autoclass('android.graphics.SurfaceTexture')
GL_TEXTURE_EXTERNAL_OES = 36197
class CameraPreviewjbsidis(Image):
play = BooleanProperty(False)
resolution = ListProperty([640, 480])
_camera = None
_previewCallback = None
_previewTexture = None
secondary_texture = None
def __init__(self, **kwargs):
self.canvas = RenderContext()
super(CameraPreviewjbsidis, self).__init__(**kwargs)
self.bind(size=self.size_changed)
# (2)
self.canvas.shader.fs = '''
#extension GL_OES_EGL_image_external : require
#ifdef GL_ES
precision highp float;
#endif
/* Outputs from the vertex shader */
varying vec4 frag_color;
varying vec2 tex_coord0;
/* uniform texture samplers */
uniform sampler2D texture0;
uniform samplerExternalOES texture1;
void main()
gl_FragColor = texture2D(texture1, tex_coord0);
'''
# This is needed for the default vertex shader.
self.canvas['projection_mat'] = Window.render_context['projection_mat']
with self.canvas.before:
# (4)
Callback(self.draw_callback)
with self.canvas:
# (3)
BindTexture(texture=self.secondary_texture, index=1)
self.canvas['secondary_texture'] = 1
# (1)
tex_id = kivy.graphics.opengl.glGenTextures(1)[0]
kivy.graphics.opengl.glBindTexture(GL_TEXTURE_EXTERNAL_OES, tex_id)
width, height = self.resolution
self.secondary_texture = Texture(width=width, height=height, target=GL_TEXTURE_EXTERNAL_OES, texid=int(tex_id), colorfmt='rgba')
# (6)
self._camera = Camera.open()
self._previewTexture = SurfaceTexture(int(tex_id))
self._camera.setPreviewTexture(self._previewTexture)
def draw_callback(self, instr):
if self._previewTexture:
self._previewTexture.updateTexImage()
def config_camera(self, surface):
self._camera.setPreviewTexture(surface)
def update_canvas(self, dt):
self.canvas.ask_update()
def size_changed(self, *largs):
pass
def on_play(self, instance, value):
if not self._camera:
return
if value:
self._camera.startPreview()
# (5)
Clock.schedule_interval(self.update_canvas, 1.0/30)
else:
Clock.unschedule(self.update_canvas)
self._camera.stopPreview()
【讨论】:
如果代码格式不正确,可以在这里查看完整代码:groups.google.com/g/kivy-users/c/hiyAJqjhFjo以上是关于如何使用 kivy 为移动应用程序制作相机小部件的主要内容,如果未能解决你的问题,请参考以下文章