首页 > 解决方案 > 如何制作图像并在下一页显示

问题描述

下午好,我使用 Python 和 Kivy 编写了一个简单的相机程序,但我就是无法拍摄。您需要拍摄“ScreenThree”的快照(将其保存在手机内存中)并将生成的图像显示在“ScreenFour”上。

我使用 kivy.uix.camera 来显示相机,使用 kivymd 和 kv 来创建界面。android.permissions:INTERNET,CAMERA,WRITE_EXTERNAL_STORAGE,READ_EXTERNAL_STORAGE

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.camera import Camera
from kivymd.theming import ThemeManager

import time

Builder.load_string("""
#:import MDFillRoundFlatButton kivymd.button.MDFillRoundFlatButton
#:import MDIconButton kivymd.button.MDIconButton
<ScreenOne@Screen>:
    canvas:
        Color:
            rgb: [.30,.50,.99]
        Rectangle:
            pos: self.pos
            size: self.size
    FloatLayout:
        MDFillRoundFlatButton:
            color: [1,1,1,1]
            text: "Перейти к созданию фото"
            pos_hint: {'center_x':.50, 'center_y':.50}
            on_press:
                root.manager.transition.direction = 'up'
                root.manager.transition.duration = 1
                root.manager.current = 'screen_two'

<ScreenTwo@Screen>:
    canvas:
        Color:
            rgb: [.30,.50,.99]
        Rectangle:
            pos: self.pos
            size: self.size
    FloatLayout:
        MDFillRoundFlatButton:
            color: [1,1,1,1]
            text: "Выбрать фон"
            pos_hint: {'center_x':.50, 'center_y':.10}
            on_press:
                root.manager.transition.direction = 'up'
                root.manager.transition.duration = 1
                root.manager.current = 'screen_three'
        MDIconButton:
            icon: 'chevron-double-right'
            pos_hint: {'center_x':.95, 'center_y':.10}
            on_press:
                root.manager.transition.direction = 'down'
                root.manager.transition.duration = 1
                root.manager.current = 'screen_one'

<ScreenThree@Screen>:
    id: entry
    canvas:
        Color:
            rgb: [.30,.50,.99]
        Rectangle:
            pos: self.pos
            size: self.size
    FloatLayout:
        Camera:
            id: camera
            index: 0
            resolution: (1280,720)
            play: True  
        MDFillRoundFlatButton:
            text: "take photo"
            pos_hint: {'center_x': 0.50, 'center_y': .10}
            on_press:
                root.capture()   #TAKE PHOTO
                root.manager.transition.direction = 'up'
                root.manager.transition.duration = 1
                root.manager.current = 'screen_four'    
        MDIconButton:
            icon: 'chevron-double-right'
            pos_hint: {'center_x':.95, 'center_y':.10}
            on_press:
                root.manager.transition.direction = 'down'
                root.manager.transition.duration = 1
                root.manager.current = 'screen_two'

<ScreenFour@Screen>:
    canvas:
        Color:
            rgb: [.30,.50,.99]
        Rectangle:
            pos: self.pos
            size: self.size
    FloatLayout:
# HERE I NEED TO DISPLAY THE IMAGE
        MDIconButton:
            icon: 'chevron-double-right'
            pos_hint: {'center_x':.95, 'center_y':.10}
            on_press:
                root.manager.transition.direction = 'down'
                root.manager.transition.duration = 1
                root.manager.current = 'screen_three'
""")


class ScreenOne(Screen):
    pass


class ScreenTwo(Screen):
    theme_cls = ThemeManager()
    theme_cls.primary_palette = 'Blue'
    main_widget = None

class ScreenThree(Screen):
    theme_cls = ThemeManager()
    theme_cls.primary_palette = 'Blue'
    main_widget = None

    def capture(self):
        camera = self.ids['camera']
        timestr = time.strftime("%Y%m%d_%H%M%S")
        photo = camera.export_to_png("IMG_{}.png".format(timestr))
        print("Captured")



class ScreenFour(Screen):
    pass


screen_manager = ScreenManager()


screen_manager.add_widget(ScreenOne(name="screen_one"))
screen_manager.add_widget(ScreenTwo(name="screen_two"))
screen_manager.add_widget(ScreenThree(name="screen_three"))
screen_manager.add_widget(ScreenFour(name="screen_four"))


class Interface(App):

    def build(self):
        return screen_manager

sample_app = Interface()
sample_app.run()

请告诉我,如何修改代码以完成任务。

错误

拍照 白屏

04-08 21:15:19.925   796 13801 E mm-camera: <STATS_AF ><ERROR> 959: af_spd_detect_process: ERROR! SPOT_LIGHT_FLAG =0!!! :AEC_grid = 256, BG_grid = 3072, ave luma = 0
04-08 21:15:19.933   835   902 W SurfaceFlinger: EventThread: dropping event (7673796e) for connection 0x7b332278c0
04-08 21:15:19.949   835   902 W SurfaceFlinger: EventThread: dropping event (7673796e) for connection 0x7b332278c0
04-08 21:15:19.959   796 13801 E mm-camera: <STATS_AF ><ERROR> 959: af_spd_detect_process: ERROR! SPOT_LIGHT_FLAG =0!!! :AEC_grid = 256, BG_grid = 3072, ave luma = 0
04-08 21:15:19.966   835   902 W SurfaceFlinger: EventThread: dropping event (7673796e) for connection 0x7b332278c0
04-08 21:15:19.983   835   902 W SurfaceFlinger: EventThread: dropping event (7673796e) for connection 0x7b332278c0
04-08 21:15:19.992   796 13801 E mm-camera: <STATS_AF ><ERROR> 959: af_spd_detect_process: ERROR! SPOT_LIGHT_FLAG =0!!! :AEC_grid = 256, BG_grid = 3072, ave luma = 0
04-08 21:15:19.999   835   902 W SurfaceFlinger: EventThread: dropping event (7673796e) for connection 0x7b332278c0

错误2

04-09 08:27:25.140   796  6243 E mm-camera: <STATS_AF ><ERROR> 959: af_spd_detect_process: ERROR! SPOT_LIGHT_FLAG =0!!! :AEC_grid = 256, BG_grid = 3072, ave luma = 0
04-09 08:27:25.146   835   902 W SurfaceFlinger: EventThread: dropping event (7673796e) for connection 0x7b32a54420
04-09 08:27:25.146  6164  6198 I python  : Captured
04-09 08:27:25.147  6164  6198 I python  : [ERROR  ] [Image       ] Error reading file IMG_20190409_082724.png
04-09 08:27:25.162   835   902 W SurfaceFlinger: EventThread: dropping event (7673796e) for connection 0x7b32a54420
04-09 08:27:25.175   796  6243 E mm-camera: <STATS_AF ><ERROR> 959: af_spd_detect_process: ERROR! SPOT_LIGHT_FLAG =0!!! :AEC_grid = 256, BG_grid = 3072, ave luma = 0
04-09 08:27:25.179   835   902 W SurfaceFlinger: EventThread: dropping event (7673796e) for connection 0x7b32a54420

标签: androidpython-3.xkivyandroid-camerakivy-language

解决方案


from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.camera import Camera
from kivymd.theming import ThemeManager

import time

filename = ''
screenfour = ''

Builder.load_string("""
#:import MDFillRoundFlatButton kivymd.button.MDFillRoundFlatButton
#:import MDIconButton kivymd.button.MDIconButton
<ScreenOne@Screen>:
    canvas:
        Color:
            rgb: [.30,.50,.99]
        Rectangle:
            pos: self.pos
            size: self.size
    FloatLayout:
        MDFillRoundFlatButton:
            color: [1,1,1,1]
            text: "Перейти к созданию фото"
            pos_hint: {'center_x':.50, 'center_y':.50}
            on_press:
                root.manager.transition.direction = 'up'
                root.manager.transition.duration = 1
                root.manager.current = 'screen_two'

<ScreenTwo@Screen>:
    canvas:
        Color:
            rgb: [.30,.50,.99]
        Rectangle:
            pos: self.pos
            size: self.size
    FloatLayout:
        MDFillRoundFlatButton:
            color: [1,1,1,1]
            text: "Выбрать фон"
            pos_hint: {'center_x':.50, 'center_y':.10}
            on_press:
                root.manager.transition.direction = 'up'
                root.manager.transition.duration = 1
                root.manager.current = 'screen_three'
        MDIconButton:
            icon: 'chevron-double-right'
            pos_hint: {'center_x':.95, 'center_y':.10}
            on_press:
                root.manager.transition.direction = 'down'
                root.manager.transition.duration = 1
                root.manager.current = 'screen_one'

<ScreenThree@Screen>:
    id: entry
    canvas:
        Color:
            rgb: [.30,.50,.99]
        Rectangle:
            pos: self.pos
            size: self.size
    FloatLayout:
        Camera:
            id: camera
            index: 0
            resolution: (1280,720)
            play: True
        MDFillRoundFlatButton:
            text: "take photo"
            pos_hint: {'center_x': 0.50, 'center_y': .10}
            on_press:
                root.capture()   #TAKE PHOTO
                root.manager.transition.direction = 'up'
                root.manager.transition.duration = 1
                root.manager.current = 'screen_four'
        MDIconButton:
            icon: 'chevron-double-right'
            pos_hint: {'center_x':.95, 'center_y':.10}
            on_press:
                root.manager.transition.direction = 'down'
                root.manager.transition.duration = 1
                root.manager.current = 'screen_two'

<ScreenFour@Screen>:
    canvas:
        Color:
            rgb: [.30,.50,.99]
        Rectangle:
            pos: self.pos
            size: self.size
    FloatLayout:
        Image:
            size: root.width, root.height
            source: ''
            id: imageWid
        MDIconButton:
            icon: 'chevron-double-right'
            pos_hint: {'center_x':.95, 'center_y':.10}
            on_press:
                root.manager.transition.direction = 'down'
                root.manager.transition.duration = 1
                root.manager.current = 'screen_three'
""")


class ScreenOne(Screen):
    pass


class ScreenTwo(Screen):
    theme_cls = ThemeManager()
    theme_cls.primary_palette = 'Blue'
    main_widget = None

class ScreenThree(Screen):
    theme_cls = ThemeManager()
    theme_cls.primary_palette = 'Blue'
    main_widget = None

    def capture(self):
        camera = self.ids['camera']
        timestr = time.strftime("%Y%m%d_%H%M%S")
        photo = camera.export_to_png("IMG_{}.png".format(timestr))
        global filename, screenfour
        filename = "IMG_{}.png".format(timestr)
        print("Captured")
        screenfour.update()

class ScreenFour(Screen):
    def __init__(self, **kwargs):
        super(ScreenFour, self).__init__(**kwargs)
        global screenfour
        screenfour = self

    def update(self, *args):
        global filename
        imageWidget = self.ids['imageWid']
        imageWidget.source = filename

screen_manager = ScreenManager()

screen_manager.add_widget(ScreenOne(name="screen_one"))
screen_manager.add_widget(ScreenTwo(name="screen_two"))
screen_manager.add_widget(ScreenThree(name="screen_three"))
screen_manager.add_widget(ScreenFour(name="screen_four"))

class Interface(App):

    def build(self):
        return screen_manager

sample_app = Interface()
sample_app.run()

您将创建一个global变量来保存图片的文件名,然后Image在 screenfour 中创建一个小部件,您Screen将在其中将 Image 小部件的源更新为您拍摄的图片的文件名。如果出现任何问题,请随时与我联系


推荐阅读