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

Flask生成图片二维码报ValueError版本无效错误的解决方法咨询

解决Flask生成图片二维码时的Invalid version错误

问题详情

开发Flask应用实现图片转二维码功能时,出现如下报错:

Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
  File AppData\Local\Programs\Python\Python311\Lib\site-packages\qrcode\main.py", line 160, in make
    self.best_fit(start=self.version)
  File AppData\Local\Programs\Python\Python311\Lib\site-packages\qrcode\main.py", line 232, in best_fit
    self.version = bisect_left(
  File AppData\Local\Programs\Python\Python311\Lib\site-packages\qrcode\main.py", line 115, in version
    util.check_version(value)
  File AppData\Local\Programs\Python\Python311\Lib\site-packages\qrcode\util.py", line 185, in check_version
 raise ValueError(f"Invalid version (was {version}, expected 1 to 40)")
ValueError: Invalid version (was 41, expected 1 to 40)

相关代码

Python后端代码

def generate_qr_image(data):
    memory = BytesIO()

     qr = qrcode.QRCode(version=1,
                   error_correction=qrcode.constants.ERROR_CORRECT_L,
                   box_size=10, border=4)
     qr.add_data(data)
     qr.make(fit=True)

     img = qr.make_image(fill_color='white', back_color='#282d39')
     img = img.convert("RGBA")

     background = Image.new("RGBA", img.size)
     qr_code = Image.alpha_composite(background, img)
     qr_code.save(memory, format="PNG")
     memory.seek(0)

     base64_img = "data:image/png;base64," + \
        b64encode(memory.getvalue()).decode('ascii')

     return base64_img


@app.route('/qr_image_select', methods=['POST'])
def image_select():
 if 'image-input' in request.files:
    image_file = request.files['image-input']  
    if image_file:
        image_data = image_file.read()
        encoded_string = base64.b64encode(image_data).decode('ascii')
        qr_image_data = generate_qr_image(encoded_string)
        return render_template('qr_image.html', data=qr_image_data)

return "No image file selected."

HTML前端代码

<form action="/qr_image_select" method="POST" enctype="multipart/form-data">
    <input type="file" name="image-input">
    <button type="submit" class="button">Select File</button>
</form>
<br><br>

{% if data %}
<div class="qrcode">
   <img src="{{ data }}" alt="QR_CODE">
   <p>qr_code has been generated!</p>
</div>
{% endif %}

解决办法

1. 限制上传图片的大小

二维码容量有限,Version 40是QR码的最大版本,对应纠错等级L时最多只能存储2953个字符。图片转base64后体积会增加约33%,稍大的图片就会超出字符上限,导致库尝试使用不存在的Version 41。

在后端添加文件大小限制:

import os

@app.route('/qr_image_select', methods=['POST'])
def image_select():
 if 'image-input' in request.files:
    image_file = request.files['image-input']  
    if image_file:
        # 限制图片大小为100KB(可按需调整)
        image_file.seek(0, os.SEEK_END)
        file_size = image_file.tell()
        image_file.seek(0)
        if file_size > 100 * 1024:
            return "图片大小不能超过100KB"
        
        image_data = image_file.read()
        encoded_string = base64.b64encode(image_data).decode('ascii')
        qr_image_data = generate_qr_image(encoded_string)
        return render_template('qr_image.html', data=qr_image_data)

return "未选择图片."

2. 改用URL托管图片(推荐方案)

直接存储图片base64编码到二维码低效且受限,更合理的方式是将上传图片保存到服务器或云存储,生成可访问的URL,再将URL存入二维码,字符数极少,完全不会触发版本超限问题。

修改后端代码实现:

import os
from werkzeug.utils import secure_filename
from flask import url_for

# 配置上传文件夹
app.config['UPLOAD_FOLDER'] = os.path.join(app.root_path, 'static', 'uploads')
os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)
# 允许的图片格式
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg'}

def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

@app.route('/qr_image_select', methods=['POST'])
def image_select():
 if 'image-input' in request.files:
    image_file = request.files['image-input']  
    if image_file and allowed_file(image_file.filename):
        filename = secure_filename(image_file.filename)
        file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
        image_file.save(file_path)
        # 生成可公开访问的URL
        image_url = url_for('static', filename=f'uploads/{filename}', _external=True)
        qr_image_data = generate_qr_image(image_url)
        return render_template('qr_image.html', data=qr_image_data)

return "未选择有效图片."

3. 调整QRCode初始化参数

如果坚持直接存储base64编码,可以不指定初始version,让库自动选择合适版本(但本质仍受内容大小限制):

qr = qrcode.QRCode(
    error_correction=qrcode.constants.ERROR_CORRECT_L,
    box_size=10, 
    border=4
)

此方法仅能解决小图片的问题,大图片仍会触发版本超限错误。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 06:34:56