updating displayed image on kivy

2019-09-07 02:32发布

I am having issues automatically updating my figures on Kivy after I have updated the two JPG files that contain the image data. In my minimal/sample code, I want the images to switch if self.count is '1' or '0'.

Here is my sample code:

#!/usr/bin/env python
"""Client specifically for presentations
This client is meant to run on a computer withouth ROS
"""

import kivy
kivy.require('1.8.0')

#import StringIO
from kivy.uix.floatlayout import FloatLayout
from kivy.app import App
from kivy.graphics import Rectangle
from kivy.clock import Clock
from kivy.logger import Logger
from kivy.core.image import Image
from kivy.uix.widget import Widget
from kivy.uix.label import Label
from kivy.config import Config
from kivy.cache import Cache
Cache.remove('kv.image')
Cache.remove('kv.texture')
#Config.set('graphics', 'fullscreen', 1)
# screen resolution is 1366x768 for the Asus computer
Config.set('graphics', 'width', '1366')
Config.set('graphics', 'height', '768')

#import pprint
import xml.etree.ElementTree as ET
import base64

# FIXME this shouldn't be necessary
from kivy.base import EventLoop
EventLoop.ensure_window()

STORE_SUBPROCESS = []    # stores roscore and rover program

class ControlClass(FloatLayout):
    """Class grabs data form
    """        
    def __init__(self, **kwargs):
        """
        We use __init__ because some variables cannot be initialized
        to an ObjectProperty for some reason, so we gotta initialize
        it this way
        """
        super(ControlClass, self).__init__(**kwargs)
        self._started = False     # true if client connected
        self.proxy = None
        self.res_x = 1366
        self.res_y = 716

        # normal image widget
        self.norm_im_widget = Widget()
#        self.norm_im_widget.pos = self.pos
#        self.norm_im_widget.size = self.size
        self.add_widget(self.norm_im_widget)

        self.count = 1

        # ++++++++++++Real Time Data+++++++++++++++++++++++
        self.alpr_page = Image('ALPR Page.jpg').texture

        self.alrp_info_coming = False

        self.background_size = (2880, 1800)

        # initialize connection to robot
        self.show_alpr_image()
        self.schedule_alpr_display()

    def get_image_size(self, size, height):
        """Outputs correct image size on screen
        Assume all images are 2880 x 1800 for now
        """
        home_size = size #(2880, 1800)
        # calculate new image size
        aspect_ratio = float(home_size[1]) / float(home_size[0])
        h = height    # self.height
        w = float(h) / float(aspect_ratio)  # desired height
        size = (w, h)
        position = (self.center_x - w/2, self.center_y - h/2)
        return (position, size)

    def show_alpr_image(self):
        """Display the normal image comming straight from the alpr
        """
        # convert data to store in .jpg file
        try:
            im_res = (437, 77)    # image original resolution
            plate_size = self.get_image_size(im_res, 65 )
            im_res = (352, 240)
            car_size = self.get_image_size(im_res, 300 )
#            # image's origin starts from buttom left
            x_shift = self.res_x - self.res_x*.4
            y_shift = self.res_y - self.res_y*0.7905
            (plate_x, plate_y) = (self.center_x + x_shift, 
                                  self.center_y/7 + y_shift - 90)
            (car_x1, car_y1) = (self.center_x + x_shift - 40, 
                                self.center_y/2.5 + y_shift)

            Cache.remove('kv.image')
            Cache.remove('kv.texture')
            self.remove_widget(self.norm_im_widget)
            self.add_widget(self.norm_im_widget)
#            self.norm_im_widget.canvas.clear() 
            if self.count == 1:
                self.count = 0
                print('car')
                with self.norm_im_widget.canvas:     #display image
                    Rectangle(source = 'plate.jpg', pos= (plate_x, plate_y),
                                          size=plate_size[1])
                    Rectangle(source = 'car.jpg', pos= (car_x1, car_y1),
                                          size=car_size[1])
            else:
                print('plate')
                self.count = 1
                with self.norm_im_widget.canvas:     #display image
                    Rectangle(source = 'plate.jpg', pos= (plate_x, plate_y),
                                          size=plate_size[1])
                    Rectangle(source = 'plate.jpg', pos= (car_x1, car_y1),
                                          size=car_size[1])
        except BaseException as e:
            Logger.warning('Error getting image frame %s'%e)
            pass
#            self.stop_connection()

    def get_alpr_data(self, dt):
        # get image data from most recent license plate
        self.show_alpr_image()

    def schedule_alpr_display(self, *args):
        """calls the replay_videos function on loop"""
        Clock.schedule_interval(self.get_alpr_data, 1.0 / 2.0)

    ########## Connect to robot ###############################

    ############################################################

class KivyGui(App):
    try:
        def build(self):
            return ControlClass()
    except BaseException:
        from sys import exit
        exit()

if __name__ == '__main__':
    KivyGui().run()

And here is my kv file:

#:kivy 1.0
#:import kivy kivy
#:import win kivy.core.window

#:kivy 1.8.0
#
# To load this file, Kivy looks if there is a Kv file with
# the same name as your App class in lowercase, minus
# "App" if it ends with "App". E.g: KivyRobot -> kivy.kv

<ControlClass, FloatLayout>:
    cols: 4
    row: 4
    canvas.before:
        Rectangle:
            # background image
            source: 'ALPR Page.jpg'
            pos: self.pos
            size: self.size

I am not sure why this does not work and I don't know what else to do.

Feel free to use other sample images, since you don't have the files I have.

0条回答
登录 后发表回答