You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Flask Socket.IO传输图片?现有代码无法显示图片求帮助

Flask Socket.IO 图片传输问题解决

我是Flask Socket.IO的新手,正在尝试实现通过Flask Socket.IO传输图片的方案。使用application.py从项目目录发送已保存的图片,application1.js接收二进制图片数据,index.html用于展示图片,但页面上完全看不到图片。相关代码如下:

application.py

from flask_socketio import SocketIO, emit
from flask import Flask, render_template, url_for, copy_current_request_context
from random import random
from time import sleep
from threading import Thread, Event


__author__ = 'slynn'

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
app.config['DEBUG'] = True


socketio = SocketIO(app, async_mode=None, logger=True, engineio_logger=True)

#random number Generator Thread
thread = Thread()
thread_stop_event = Event()

def randomNumberGenerator():
    print("Making random numbers")

    while not thread_stop_event.isSet():

        with open('savedImage.jpg', 'rb') as f:
            image_data = f.read()

        socketio.emit('my_response', {'image': image_data}, namespace='/test')
        socketio.sleep(2)


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

@socketio.on('connect', namespace='/test')
def test_connect():
    global thread
    print('Client connected')

    if not thread.is_alive():
        print("Starting Thread")
        thread = socketio.start_background_task(randomNumberGenerator)

@socketio.on('disconnect', namespace='/test')
def test_disconnect():
    print('Client disconnected')


if __name__ == '__main__':
    socketio.run(app)

application1.js

$(document).ready(function(){

    var socket = io.connect('http://' + document.domain + ':' + location.port + '/test');
    var numbers_received = [];
    socket.on('my_response', function(msg) {

            let arrayBufferView = new Uint8Array(msg['image']);
            console.log(arrayBufferView);

            var blob = new Blob( [ arrayBufferView ], { type: "image/jpeg" } );
            //maintain a list of ten numbers
            var img_url = URL.createObjectURL(blob);
            console.log(img_url);
            document.getElementById("img_show").src = img_url;
        });

});

index.html

<!DOCTYPE html>
<html>
<head>
    <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/4.4.1/socket.io.min.js"></script>
    <script src="static/jscript/application1.js"></script>

    <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<body>
<div class="container">
  <div class="jumbotron">
    <h1>Asynchronous Flask Communication</h1>
    <p>Random numbers generated by the Flask server will appear below, asynchronously.</p>
    <p>Details <a href='https://www.shanelynn.ie/asynchronous-updates-to-a-webpage-with-flask-and-socket-io/' target='_blank'>here.</a></p>
  </div>
</div>
    
</div>

<div class="container" id="content">
    <div class="row">
        <h3>Image:</h3>
        <div id="img_show">
        </div> <!-- /#log -->
    </div>
</div>


</body>
</html>

问题原因及修复方案

1. HTML标签错误

页面中用来展示图片的是<div id="img_show"></div>,但src是<img>标签专属属性,div标签无法通过设置src显示图片。需将div替换为img标签:

<div class="container" id="content">
    <div class="row">
        <h3>Image:</h3>
        <img id="img_show" alt="传输的图片" />
    </div>
</div>

2. 二进制数据传输格式问题

Flask Socket.IO直接将bytes类型图片数据放入字典发送时,会因JSON不支持二进制数据被错误序列化,前端无法解析出正确内容。提供两种修复方式:

方式一:Base64编码传输(兼容性更好)

修改application.py,导入base64并将图片数据编码为Base64字符串:

# 新增导入
import base64

def randomNumberGenerator():
    print("Making random numbers")

    while not thread_stop_event.isSet():

        with open('savedImage.jpg', 'rb') as f:
            # 将二进制数据编码为Base64字符串
            image_data = base64.b64encode(f.read()).decode('utf-8')

        socketio.emit('my_response', {'image': image_data}, namespace='/test')
        socketio.sleep(2)

修改application1.js,直接用Base64字符串生成Data URL设置图片src:

socket.on('my_response', function(msg) {
    // 构造Data URL赋值给img标签
    document.getElementById("img_show").src = 'data:image/jpeg;base64,' + msg.image;
});
方式二:直接发送二进制数据

修改application.py,将二进制数据作为单独参数发送,并指定binary=True:

def randomNumberGenerator():
    print("Making random numbers")

    while not thread_stop_event.isSet():

        with open('savedImage.jpg', 'rb') as f:
            image_data = f.read()

        # 直接发送二进制数据,指定binary=True
        socketio.emit('my_response', image_data, namespace='/test', binary=True)
        socketio.sleep(2)

修改application1.js,接收二进制数据并处理:

socket.on('my_response', function(msg) {
    let arrayBufferView = new Uint8Array(msg);
    var blob = new Blob( [ arrayBufferView ], { type: "image/jpeg" } );
    var img_url = URL.createObjectURL(blob);
    document.getElementById("img_show").src = img_url;
});

验证

修改完成后,确保项目目录下存在savedImage.jpg,启动Flask应用,访问页面即可看到图片每隔2秒更新一次。

内容的提问来源于stack exchange,提问作者Sourav Chakraborty

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 22:46:02