Как отрендерить изображение svg из потока байтов svg - PullRequest
0 голосов
/ 03 августа 2020

Этот python / flask скрипт создает поток байтов QR-кода svg, но когда я пытаюсь визуализировать его с помощью шаблона Jinja2 {{ qr[0] }}, он отображается как текст. Как я могу визуализировать это как изображение? Как видно из приведенного ниже кода, я успешно передал данные клиенту - мне не нужна помощь с этим - единственная проблема заключается в том, что данные имеют неправильный формат - поток байтов svg - тогда как я хочу отобразить эти данные в виде изображения.

Для ясности я ДОЛЖЕН экспортировать qr-код в render_template, потому что у меня есть другие переменные, которые вносят вклад в qr-код, которые также необходимо экспортировать. Следовательно, метод <img src="{{ url_for('qr') }}"> не работает.

Точно так же я не хочу, чтобы данные отображались в URL-адресе.

import pyqrcode
from io import BytesIO

@app.route('/qr/<id>/<price>', methods=['GET', 'POST'])
def qr(id,price):
    if id:
        data = id+price
        basestring = pyqrcode.create(data, error='H')
        stream = BytesIO()
        basestring.svg(stream, scale=5, module_color='#802929', background='#FFFFFF')
        qr = stream.getvalue(), 200, {
            'Content-Type': 'image/svg+xml',
            'Cache-Control': 'no-cache, no-store, must-revalidate',
            'Pragma': 'no-cache',
            'Expires': '0'}

    return render_template('qr.html', qr=qr, data=data)

Это часть того, что в настоящее время отображается как текст на странице HTML:

b '\ n

1 Ответ

1 голос
/ 18 августа 2020

Вы должны декодировать поток байтов перед использованием в шаблоне. Далее вы можете использовать Jinja's | безопасный фильтр.

import pyqrcode
from io import BytesIO

@app.route('/qr/<id>/<price>', methods=['GET', 'POST'])
def qr(id, price):
    data = id + price
    qrcode = pyqrcode.create(data, error='H')
    stream = BytesIO()
    # Added: Disable XML declaration and SVG namespace
    # Removed: background='#FFFFFF' since it is the default
    qrcode.svg(stream, scale=5, xmldecl=False, svgns=False, module_color='#802929')
    qr = stream.getvalue().decode('utf-8')
    return render_template('qr.html', qr=qr, data=data)

В вашем шаблоне:

<div>{{ qr | safe }}</div>

Или даже короче, используя другой QR-код lib

import segno

@app.route('/qr/<id>/<price>', methods=['GET', 'POST'])
def qr(id, price):
    data = id + price
    qr = segno.make(data, error='H')
    return render_template('qr.html', qr=qr, data=data)

Jinja шаблон:

<div>{{ qr.svg_inline(dark='#802929', scale=5) | safe }}</div>
...