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

如何将HTML页面加载的图片传递到Flask应用进行处理

实现方案

核心逻辑是前端把页面已加载的图片转成可传输格式,通过HTTP请求发给Flask接口,后端解码后直接传给PIL/OpenCV处理即可,不需要让用户重复选择文件。

前端实现逻辑

页面中已经加载展示的<img>标签内容,可以通过Canvas导出为可传输格式,有两种常用传输方式:

  • 方式1:转Base64字符串通过JSON格式POST发送
    假设你页面上预览图片的标签id为previewImg,绑定处理按钮的点击事件即可触发传输:
    document.getElementById('processBtn').addEventListener('click', async () => {
      const img = document.getElementById('previewImg');
      // 创建和原图尺寸一致的画布
      const canvas = document.createElement('canvas');
      canvas.width = img.naturalWidth;
      canvas.height = img.naturalHeight;
      const ctx = canvas.getContext('2d');
      ctx.drawImage(img, 0, 0);
      // 导出为base64格式,可按需切换image/jpeg、image/webp等格式
      const base64Data = canvas.toDataURL('image/png');
    
      // 发送请求到Flask接口
      const resp = await fetch('/process-image', {
        method: 'POST',
        headers: {'Content-Type': 'application/json'},
        body: JSON.stringify({image: base64Data})
      });
      // 接收处理结果,比如返回的处理后图片base64可直接赋值给img标签展示
      const result = await resp.json();
      document.getElementById('resultImg').src = result.processed_image;
    })
    
  • 方式2:转Blob文件流通过FormData发送
    这种方式后端接收逻辑和普通文件上传完全一致,不需要额外解析Base64,传输大图片时体积更小:
    canvas.toBlob(async (blob) => {
      const formData = new FormData();
      // 字段名和普通文件上传保持一致即可
      formData.append('uploaded_img', blob, 'process.png');
      const resp = await fetch('/process-image', {
        method: 'POST',
        body: formData
      });
      // 响应处理逻辑和上述方式一致
    }, 'image/png');
    

注意:如果页面展示的图片是跨域资源,Canvas导出时会触发跨域污染报错,这种情况要么给图片源配置CORS规则,要么在用户首次上传图片时就把原始File对象存在全局变量里,直接传原始File对象,不需要从img标签转。

Flask后端实现

先安装依赖:pip install flask pillow opencv-python numpy

  • 对应接收Base64参数的接口写法,包含PIL、OpenCV格式转换逻辑:
    from flask import Flask, request, jsonify
    import base64
    import numpy as np
    from PIL import Image
    import cv2
    import io
    
    app = Flask(__name__)
    
    @app.route('/process-image', methods=['POST'])
    def process_image():
        data = request.get_json()
        # 去掉base64开头的格式前缀
        img_base64 = data['image'].split(',')[1]
        # 解码为字节流
        img_bytes = base64.b64decode(img_base64)
        
        # 转PIL可直接处理的格式
        pil_img = Image.open(io.BytesIO(img_bytes))
        
        # 转OpenCV可直接处理的格式(注意通道转换:PIL是RGB,OpenCV默认用BGR)
        cv_img = cv2.cvtColor(np.array(pil_img), cv2.COLOR_RGB2BGR)
    
        # 在此处编写你的图像处理逻辑即可,以下为灰度化示例
        processed_cv = cv2.cvtColor(cv_img, cv2.COLOR_BGR2GRAY)
    
        # 处理完成后转回base64返回给前端
        _, buffer = cv2.imencode('.png', processed_cv)
        processed_base64 = 'data:image/png;base64,' + base64.b64encode(buffer).decode('utf-8')
        return jsonify({'processed_image': processed_base64})
    
    if __name__ == '__main__':
        app.run(debug=True)
    
  • 对应接收FormData文件流的接口写法,和普通文件上传逻辑完全一致:
    @app.route('/process-image', methods=['POST'])
    def process_image_file():
        file = request.files['uploaded_img']
        img_bytes = file.read()
        # 后续转PIL、OpenCV格式以及处理逻辑和上述代码完全一致
        pil_img = Image.open(io.BytesIO(img_bytes))
        cv_img = cv2.cvtColor(np.array(pil_img), cv2.COLOR_RGB2BGR)
        # 自定义处理逻辑...
        # 返回结果逻辑同上
    

常见注意点

  • 传输高清大图优先选择Blob+FormData的方式,Base64编码会比原文件体积大30%左右
  • Canvas导出图片默认会有压缩,如果需要无损画质,直接存用户首次上传时的原始File对象传输即可,不需要走Canvas转换
  • 转OpenCV格式时必须做RGB到BGR的通道转换,否则处理后的图片会出现蓝红色调错位

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 01:24:32