【问题标题】:Auto reload HTML image on each loop iteration in Python code using BottlePy使用 BottlePy 在 Python 代码中的每次循环迭代中自动重新加载 HTML 图像
【发布时间】:2021-10-19 15:44:05
【问题描述】:

我正在使用 Raspberry Pi、超声波传感器和伺服电机构建一个 DIY 声纳,到目前为止,我已经设法让它在每次 180 度扫描时生成一张图片/地图,但问题是我也想在本地网页上显示这张图片,我想让它在每次扫描时自动更新,而无需用户手动刷新页面(每次扫描的持续时间与前一次不同 - 这是一个问题)。我曾想过使用 BottlePy 微型 Web 框架以及一些 JSON。代码如下:

Python:

import pigpio
import time
import RPi.GPIO as GPIO
import numpy as np
import cv2
import math
from PIL import Image as im

import bottle
from bottle import route, run, template, BaseTemplate, static_file

app = bottle.default_app()
BaseTemplate.defaults['get_url'] = app.get_url

@route('/')
def index():
    return template('index.html')


@route('/<filename:path>', name='static')
def serve_static(filename):
    return static_file(filename, root='static')

@route('/refresh')

def refresh():

...
    #matrix generation for map - newmapp
...

    data=im.fromarray(newmapp)
    data.save('/home/pi/Desktop/servo_web/static/map.png')
    
run(host='localhost', port=8080)

HTML/JS:

<!DOCTYPE html>
<html>
<head>
    <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
        <title>HARTA</title>
</head>
<body>
    <img src="{{ get_url('static', filename='map.png') }}" />
    <script>
      $(document).ready(function(){
        setInterval(refreshFunction,300);
      });

      function refreshFunction(){
        $.getJSON('/refresh', function(){
        });
      }
    </script>
</body>
</html>

提前致谢!

【问题讨论】:

  • 如果您使用 JavaScript 将 url 更改为图像,那么浏览器将重新加载图像。您可以将随机参数添加到 url,如map.png?random_value。某些系统使用当前时间重新加载 imagecss 文件 - 比如 map.png?2021.08.17.20.49.43 (year.month.day.hour.minut.second)

标签: javascript python html bottle


【解决方案1】:

从这个问题:Refresh image with a new one at the same url,您可以尝试添加一个catchbreaker,实质上是强制浏览器重新加载图像,而不是从缓存中获取它。

document.querySelector("img").src = `{{ get_url('static', filename='map.png?${new Date().getTime()}') }}`;

【讨论】:

    【解决方案2】:

    如果您向 url 添加随机参数 - map.png?random_value(即带有时间和秒的当前日期) - 那么浏览器会自动重新加载图像。

    所以在 JavaScript 中你可以这样做

    <img id="map" src="{{ get_url('static', filename='map.png') }}" />
    
    $.get('/refresh', function(){            
         d = new Date();
         $("#map").attr("src", "{{ get_url('static', filename='map.png') }}?"+d.getTime());            
    });  
    

    最少的工作代码

    import os
    import time
    
    import bottle
    from bottle import route, run, template, BaseTemplate, static_file
    
    import numpy as np
    from PIL import Image
    
    app = bottle.default_app()
    BaseTemplate.defaults['get_url'] = app.get_url
    
    @route('/')
    def index():
        return template('''<!DOCTYPE html>
    <html>
    <head>
        <title>HARTA</title>
        <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
    </head>
    <body>
        <img id="map" src="{{ get_url('static', filename='map.png') }}" />
        <script>
          $(document).ready(function(){
            setInterval(refreshFunction, 1000);
          });
    
          function refreshFunction(){
            $.get('/refresh', function(){            
                d = new Date();
                $("#map").attr("src", "{{ get_url('static', filename='map.png') }}?"+d.getTime());            
                console.log($("#map").attr("src"));
            });
          }
        </script>
    </body>
    </html>''')
    
    @route('/<filename:path>', name='static')
    def serve_static(filename):
        return static_file(filename, root='static')
    
    @route('/refresh')
    def refresh():
        os.makedirs('static', exist_ok=True)
        newmapp = np.random.rand(100,100,3) * 255    
        data = Image.fromarray(newmapp.astype('uint8')).convert('RGBA')
        data.save('static/map.png')
        return "OK" 
        
    run(host='localhost', port=8080)
    

    【讨论】:

      【解决方案3】:

      “我想让它在每次扫描时自动更新,而无需用户手动刷新页面”

      不是每次都刷新页面,更复杂但更有效的选择是使用 AJAX GET 请求在浏览器中动态呈现图像。使用 setInterval() 从客户端重复发送请求。您选择的时间间隔将决定您将获得多少个请求到服务器,较小的间隔 = 更多的请求。这种模式称为轮询。

      因为浏览器会尝试缓存图像而不是更新它,所以在客户端添加缓存破坏 url 片段并将缓存控制标头添加到服务器响应: https://stackoverflow.com/a/9943419/14082992

      Bottle 可以使用图像的通配符路径忽略添加的 URL 片段:https://bottlepy.org/docs/dev/routing.html#wildcard-filters

      使用 Bottle 的 response.set_header 设置缓存控制头: https://bottlepy.org/docs/dev/tutorial.html#the-response-object

      【讨论】:

        猜你喜欢
        • 2017-09-05
        • 1970-01-01
        • 2015-03-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-19
        • 2018-05-23
        • 2014-10-31
        相关资源
        最近更新 更多