I need a control for rendering SVG graphics. The data is coming in the in the form of a StreamReader
object. What's the easiest way to render such an image?
At present, I'm using PNGs:
But I'd like something higher resolution. SVGs would be perfect for this.
Sample SVG:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 2.28.0 (20110507.0327)
-->
<!-- Title: G Pages: 1 -->
<svg width="262pt" height="216pt"
viewBox="0.00 0.00 262.00 216.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph1" class="graph" transform="scale(1 1) rotate(0) translate(4 212)">
<title>G</title>
<polygon fill="white" stroke="white" points="-4,5 -4,-212 259,-212 259,5 -4,5"/>
<!-- a -->
<g id="node1" class="node"><title>a</title>
<polygon fill="purple" stroke="purple" points="159.618,-186.523 133,-198.872 106.382,-186.523 116.549,-166.541 149.451,-166.541 159.618,-186.523"/>
<polygon fill="none" stroke="purple" points="165.003,-188.397 133,-203.245 100.997,-188.397 114.139,-162.57 151.861,-162.57 165.003,-188.397"/>
<polygon fill="none" stroke="purple" points="170.387,-190.272 133,-207.617 95.6126,-190.272 111.729,-158.598 154.271,-158.598 170.387,-190.272"/>
<text text-anchor="middle" x="133" y="-177.3" font-family="Times New Roman,serif" font-size="14.00">a</text>
</g>
<!-- b -->
<g id="node3" class="node"><title>b</title>
<ellipse fill="none" stroke="black" cx="133" cy="-100" rx="27" ry="18"/>
<text text-anchor="middle" x="133" y="-96.3" font-family="Times New Roman,serif" font-size="14.00">b</text>
</g>
<!-- a->b -->
<g id="edge2" class="edge"><title>a->b</title>
<path fill="none" stroke="black" d="M133,-158.413C133,-149.086 133,-138.069 133,-128.192"/>
<polygon fill="black" stroke="black" points="136.5,-128.057 133,-118.057 129.5,-128.057 136.5,-128.057"/>
</g>
<!-- c -->
<g id="node4" class="node"><title>c</title>
<polygon fill="none" stroke="black" points="144.42,-41 22.2639,-41 -0.419833,-5 121.736,-5 144.42,-41"/>
<text text-anchor="middle" x="72" y="-19.3" font-family="Times New Roman,serif" font-size="14.00">hello world</text>
</g>
<!-- b->c -->
<g id="edge3" class="edge"><title>b->c</title>
<path fill="none" stroke="black" d="M120.656,-83.8226C112.588,-73.903 101.855,-60.7069 92.5226,-49.2327"/>
<polygon fill="black" stroke="black" points="95.0581,-46.8031 86.0329,-41.2536 89.6275,-51.22 95.0581,-46.8031"/>
</g>
<!-- d -->
<g id="node6" class="node"><title>d</title>
<polygon fill="none" stroke="black" points="194,-3.55271e-015 225.296,-34.5 162.704,-34.5 194,-3.55271e-015"/>
<text text-anchor="middle" x="194" y="-19.3" font-family="Times New Roman,serif" font-size="14.00">d</text>
</g>
<!-- b->d -->
<g id="edge5" class="edge"><title>b->d</title>
<path fill="none" stroke="black" d="M145.344,-83.8226C154.961,-71.9983 168.365,-55.5183 178.67,-42.8489"/>
<polygon fill="black" stroke="black" points="181.629,-44.757 185.224,-34.7906 176.199,-40.3401 181.629,-44.757"/>
</g>
<!-- e -->
<g id="node7" class="node"><title>e</title>
<polygon fill="none" stroke="black" points="254.137,-199 189.863,-199 208.407,-163 235.593,-163 254.137,-199"/>
<text text-anchor="middle" x="222" y="-177.3" font-family="Times New Roman,serif" font-size="14.00">e</text>
</g>
</g>
</svg>
The easiest way to render SVG files is to construct a QSvgWidget and load an SVG file using one of the QSvgWidget::load() functions. QSvgRenderer is the class responsible for rendering SVG files for QSvgWidget, and it can be used directly to provide SVG support for custom widgets.
SVG uses a "painters model" of rendering. Paint is applied in successive operations to the output device such that each operation paints onto some area of the output device, possibly obscuring paint that has previously been layed down.
The issue of blurriness arises when you upload an image that has the exact pixel dimensions of the space you are targeting. The exact reason has to do with the resolution of modern screens.
Scalable Vector Graphics (SVG) is an XML-based vector image format for defining two-dimensional graphics, having support for interactivity and animation.
When I had looked into using SVGs in my WPF applications, I found there were a couple packages that could be added in to provide this functionality, but in the end went with using SVGs that I converted to XAML, which will be able to scale in WPF applications the same way an SVG image is able to scale on browsers and such. If you have access to the SVG code (which it looks like you do), then this may be a good solution for you.
These are the steps I use to achieve this:
Converting SVG to XAML I prefer to use Inkscape for the following steps.
Using a XAML image in a WPF project
The image can now be used by setting the source of an item to display the image (e.g. a Frame) to the resource path (e.g. “/resources/images/.xaml”). This can be set either directly or through binding.
Example WPF/XAML code for displaying a XAML image The following code shows an example of how to display a XAML image added using the above steps. This code will scale the image to fill the container it is added to. The source for the image is supplied through the binding used for the Frame element's source. This can be replaced with a string of the image's path (which is what is be provided through the binding value).
<Viewbox Stretch="Uniform"
Margin="4,4"
VerticalAlignment="Center">
<Frame Source="{Binding ImageSource}"
NavigationUIVisibility="Hidden"/>
</Viewbox>
An example of the path string is:
/resources/images/<file-name>.xaml
If the image is located in a DLL and is used in the same DLL, the path string will need to include more information using the following format:
/<AssemblyName>;component/resources/images/<file-name>.xaml
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With