在Python中显示SVG文件 [英] Display SVG file in Python
问题描述
我正在创建一个 Python3 程序,该程序可以生成个人项目所需的带有随机圆圈的 SVG 图像.现在该程序可以完美运行,但是我想微调一些参数以产生最佳结果.我的想法是要有一个显示窗口,以显示中间结果,并有一个交互式外壳,可以更改生成圆的位置的某些值,而不必创建数千个不同的图像并进行比较.完成后,我可以简单地保存结果.
I'm creating a Python3 program that generates SVG images with random circles that I need for a personal project. Right now the program works perfectly, but I'd like to fine-tune some parameters to produce the best results possible. My idea is to have a display window that shows the intermediate result and an interactive shell to change some of the values that generate the position of the circles, without having to create thousands of different images and compare them. When I finish I can simply save the result.
问题来了:我真的不知道如何实现这个结果.我首先想到了使用Matplotlib,它通常对这类任务非常理想,但似乎无法读取SVG文件.我也想过直接在绘图中画圆,但其中一些必须模糊(SVG文件中的高斯模糊过滤器),而Matplotlib似乎无法模糊形状.最终,我寻找了能够显示SVG文件或直接显示程序生成的文本以生成SVG文件的其他东西,但是没有运气.
And here comes the problem: I don't really know how to achieve this result. I first thought of using Matplotlib, which is usually perfect for these kind of tasks, but it doesn't seem to be able to read SVG files. I also thought of drawing circles directly into a plot, but some of them have to be blurred (Gaussian blur filter in the SVG file), and Matplotlib doesn't seem to be able to blur shapes. Finally I looked for something else able to display either an SVG file or directly the text the program produces to generate the SVG file, but with no luck.
我刚刚尝试过CairoSVG将SVG文件转换为PNG.它有效,但不支持高斯模糊,因此它是次优解决方案.我可以接受将SVG文件转换为PNG或其他格式的解决方案,但是我希望它至少支持高斯模糊,否则我可以使用Matplotlib绘制每个圆.
I just tried CairoSVG to convert the SVG file to PNG. It works, but it doesn't support Gaussian blur, so it's a suboptimal solution. I can accept a solution that involves converting the SVG file to PNG or some other format, but I'd like it to support at least Gaussian blur, otherwise I can simply draw every circle with Matplotlib.
提前感谢您的帮助!
推荐答案
这是 PyQt5(或 PySide2 在我的情况下)和 QWebEngineView(有提到 有解释了为什么QSvgWidget不处理模糊等滤镜.
Here's a solution with PyQt5 (or PySide2 in my case) and QWebEngineView (there are mentions here or there that explain why QSvgWidget didn't handle filters like blur).
这只是显示svg(及其模糊),您可能需要添加小部件以使其随心所欲地互动:
This is just displaying the svg (with its blur), you will probably want to add widgets to make it interactive as you like:
import sys
from PySide2 import QtCore, QtGui, QtWidgets
from PySide2.QtNetwork import QNetworkProxy, QNetworkProxyFactory
from PySide2.QtWebEngineWidgets import QWebEngineView
class DisplaySVG(QtWidgets.QWidget):
"A simple SVG display."
def __init__(self, url=None, parent=None):
super().__init__(parent)
self.resize(800,600)
self.verticalLayout = QtWidgets.QVBoxLayout(self)
self.webview = QWebEngineView(self)
self.verticalLayout.addWidget(self.webview)
self.setWindowTitle("Display SVG")
act = QtWidgets.QAction("Close", self)
act.setShortcuts([QtGui.QKeySequence(QtCore.Qt.Key_Escape)])
act.triggered.connect(self.close)
self.addAction(act)
svg = '''
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="210mm"
height="297mm"
viewBox="0 0 210 297"
version="1.1"
id="svg8"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
sodipodi:docname="drawing.svg">
<defs
id="defs2">
<filter
style="color-interpolation-filters:sRGB;"
inkscape:label="Blur"
id="filter4530">
<feGaussianBlur
stdDeviation="3.48559 2"
result="fbSourceGraphic"
id="feGaussianBlur4528" />
<feColorMatrix
result="fbSourceGraphicAlpha"
in="fbSourceGraphic"
values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"
id="feColorMatrix4532" />
<feGaussianBlur
id="feGaussianBlur4534"
stdDeviation="3.49 2"
result="blur"
in="fbSourceGraphic" />
</filter>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.7"
inkscape:cx="214.06823"
inkscape:cy="366.85869"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1487"
inkscape:window-height="958"
inkscape:window-x="58"
inkscape:window-y="85"
inkscape:window-maximized="0" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<circle
style="opacity:1;fill:#ff5555;fill-opacity:0.57480317;stroke:#2c2cff;stroke-width:1.882;stroke-miterlimit:4;stroke-dasharray:3.764, 1.88199999999999990;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter4530)"
id="path4518"
cx="66.523811"
cy="123.13095"
r="36.285713" />
</g>
</svg>
'''
self.webview.setHtml(svg)
qt_app = QtWidgets.QApplication(sys.argv)
disp = DisplaySVG()
disp.show()
qt_app.exec_()
这篇关于在Python中显示SVG文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!