如何从 svg 字节流渲染 svg 图像
How to render an svg image from an svg byte stream
这个 python / flask 脚本创建了一个 svg QR 代码字节流,但是当我尝试使用 Jinja2 模板 {{ qr[0] }}
呈现它时,它呈现为文本。如何将其渲染为图像?正如您从下面的代码中看到的,我已经成功地将数据传输到客户端——我不需要帮助——唯一的问题是数据格式错误——一个 svg 字节流——而我想显示该数据作为图像。
为了澄清起见,我必须导出 render_template 中的二维码,因为我还有其他变量对二维码有贡献,也需要导出。因此,<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<path
transform="scale(5)" stroke="#802929" class="pyqrline" d="M4 4.5h7m1
0h1m1 0h2m2 0h2m1 0h3m1 0h1m1 0h2m1 0h2m2 0h5m2 0h4m1 0h1m1 0h4m2
0h7m-57 1h1m5 0h1m2 0h1m1 0h1m2 0h5m1 0h2m3 0h1m4 0h1m1 0h1m1 0h5m4
0h1m3 0h1m2 0h1m5 0h1m-57 1h1m1 0h3m1 0h1m1 0h1m1 0h4m3 0h1m3 0h1m2
0h2m3 0h2m3 0h1m2 0h1m1 0h4m1 0h4m2 0h1m1 0h3m1 0h1m-57 1h1m1 0h3m1
0h1m3 0h3m2 0h1m2 0h3m1 0h1m8 0h2m1 0h2m3 0h2m1 0h3m2 0h1m2 0h1m1
0h3m1 0h1m-57 1h1m1 0h3m1 0h1m1 0h1m1 0h1m1 0h1m2 0h1m5 0h1m3 0h6m1
0h1m1 0h3m3 0h3m1 0h1m2 0h1m2 0h1m1 0h3m1 0h1m-57 1h1m5 0h1m2 0h1m5
0h1m2 0h1m6 0h2m3 0h1m1 0h2m1 0h7m1 0h4m3 0h1m5 0h1m-57 1h7m1 0h1m1
0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1
0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h7m-49 1h1m3
0h3m1 0h5m1 0h1m3 0h1m3 0h1m1 0h1m2 0h1m3 0h3m1 0h1m1 0h2m1 0h1m-44
1h2m4 0h1m2 0h2m1 0h4m4 0h6m2 0h5m1 0h1m5 0h3m2 0h1m1 0h1m1 0h1m1
0h1m-57
在模板中使用之前,您必须对字节流进行解码。此外,您还必须使用 Jinja 的 |安全过滤器。
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 code 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>
这个 python / flask 脚本创建了一个 svg QR 代码字节流,但是当我尝试使用 Jinja2 模板 {{ qr[0] }}
呈现它时,它呈现为文本。如何将其渲染为图像?正如您从下面的代码中看到的,我已经成功地将数据传输到客户端——我不需要帮助——唯一的问题是数据格式错误——一个 svg 字节流——而我想显示该数据作为图像。
为了澄清起见,我必须导出 render_template 中的二维码,因为我还有其他变量对二维码有贡献,也需要导出。因此,<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<path transform="scale(5)" stroke="#802929" class="pyqrline" d="M4 4.5h7m1 0h1m1 0h2m2 0h2m1 0h3m1 0h1m1 0h2m1 0h2m2 0h5m2 0h4m1 0h1m1 0h4m2 0h7m-57 1h1m5 0h1m2 0h1m1 0h1m2 0h5m1 0h2m3 0h1m4 0h1m1 0h1m1 0h5m4 0h1m3 0h1m2 0h1m5 0h1m-57 1h1m1 0h3m1 0h1m1 0h1m1 0h4m3 0h1m3 0h1m2 0h2m3 0h2m3 0h1m2 0h1m1 0h4m1 0h4m2 0h1m1 0h3m1 0h1m-57 1h1m1 0h3m1 0h1m3 0h3m2 0h1m2 0h3m1 0h1m8 0h2m1 0h2m3 0h2m1 0h3m2 0h1m2 0h1m1 0h3m1 0h1m-57 1h1m1 0h3m1 0h1m1 0h1m1 0h1m1 0h1m2 0h1m5 0h1m3 0h6m1 0h1m1 0h3m3 0h3m1 0h1m2 0h1m2 0h1m1 0h3m1 0h1m-57 1h1m5 0h1m2 0h1m5 0h1m2 0h1m6 0h2m3 0h1m1 0h2m1 0h7m1 0h4m3 0h1m5 0h1m-57 1h7m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h7m-49 1h1m3 0h3m1 0h5m1 0h1m3 0h1m3 0h1m1 0h1m2 0h1m3 0h3m1 0h1m1 0h2m1 0h1m-44 1h2m4 0h1m2 0h2m1 0h4m4 0h6m2 0h5m1 0h1m5 0h3m2 0h1m1 0h1m1 0h1m1 0h1m-57
在模板中使用之前,您必须对字节流进行解码。此外,您还必须使用 Jinja 的 |安全过滤器。
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 code 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>