Friday, January 31, 2014

Using inkscape to generate svg objects from a PDF

I have a client who has a collection of storyboard / wireframe PDF documents describing end-user interaction with a company website, and my client wanted me to design and build a website that could closely match the PDFs. There is a particular page which shows a kind of user/vehicle history in a vertical format, where each individual historical event is rendered as a "bubble":



I could see no other way to create such a result without using Canvas or SVG. In the end I went with SVG for this particular application and leveraged a great application called Inkscape to pull the individual "bubble" out of the PDF and export it into SVG format:



This produced a fairly verbose SVG file:

<?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="744.09448819"
height="1052.3622047"
id="svg19746"
version="1.1"
inkscape:version="0.48.4 r9939"
sodipodi:docname="New document 6">
<defs
id="defs19748">
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath8551">
<path
inkscape:connector-curvature="0"
d="m 0,5177.253 3126.964,0 L 3126.964,0 0,0 0,5177.253 z"
id="path8553" />
</clipPath>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.35"
inkscape:cx="375"
inkscape:cy="520"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="463"
inkscape:window-height="453"
inkscape:window-x="225"
inkscape:window-y="225"
inkscape:window-maximized="0" />
<metadata
id="metadata19751">
<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">
<g
transform="matrix(1.25,0,0,-1.25,-1385.6255,4051.4283)"
id="g8547">
<g
id="g8549"
clip-path="url(#clipPath8551)">
<g
id="g8555"
transform="translate(1275.4824,2776.2529)">
<path
inkscape:connector-curvature="0"
d="m 0,0 c -5.79,0 -10.482,5.003 -10.482,11.344 l 0,56 C -10.482,73.428 -6.084,78 0,78 l 188,0 c 5.99,0 13.449,-3.583 16.981,-8.057 L 221.802,48.552 C 225.049,44.438 232.106,41 237.211,41 l 39.307,0 0,-4 -39.307,0 c -5.356,0 -12.27,-3.316 -15.411,-7.296 L 204.983,8.317 C 201.345,3.709 193.728,0 188,0 L 0,0 z"
style="fill:#c1212c;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path8557" />
</g>
<g
id="g8559"
transform="translate(1463.4824,2855.2529)">
<path
inkscape:connector-curvature="0"
d="m 0,0 -188,0 c -6.556,0 -11.482,-5.1 -11.482,-11.656 l 0,-56 c 0,-6.893 5.141,-12.344 11.482,-12.344 l 188,0 c 5.994,0 13.964,3.84 17.766,8.656 l 16.822,21.471 C 37.511,-46.17 44.209,-43 49.211,-43 l 20.789,0 17.5,0 2.018,0 0,1.844 0,2 0,2.156 -2.018,0 -17.5,0 -20.789,0 c -4.842,0 -11.54,3.225 -14.627,7.135 L 17.77,-8.402 C 14.065,-3.711 6.262,0 0,0 m 0,-2 c 5.5,0 12.788,-3.359 16.196,-7.677 L 33.015,-31.065 C 36.423,-35.383 43.711,-39 49.211,-39 l 20.789,0 17.518,0 0,-2 -17.518,0 -20.789,0 c -5.5,0 -12.788,-3.359 -16.196,-7.677 L 16.196,-70.065 C 12.788,-74.383 5.5,-78 0,-78 l -188,0 c -5.5,0 -9.482,4.844 -9.482,10.344 l 0,56 c 0,5.5 3.982,9.656 9.482,9.656 l 187.518,0"
style="fill:#d7d6d4;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path8561" />
</g>
</g>
</g>
</g>
</svg>

After some common sense analysis, I trimmed it down to the following:
<svg
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
>
<g
id="layer1">
<g
transform="matrix(1.25,0,0,-1.25,-1369.1969,3999.9997)"
id="g8547">
<g
id="g8549"
clip-path="url(#clipPath8551)">
<g
id="g8555"
transform="translate(1275.4824,2776.2529)">
<path
d="m 0,0 c -5.79,0 -10.482,5.003 -10.482,11.344 l 0,56 C -10.482,73.428 -6.084,78 0,78 l 188,0 c 5.99,0 13.449,-3.583 16.981,-8.057 L 221.802,48.552 C 225.049,44.438 232.106,41 237.211,41 l 39.307,0 0,-4 -39.307,0 c -5.356,0 -12.27,-3.316 -15.411,-7.296 L 204.983,8.317 C 201.345,3.709 193.728,0 188,0 L 0,0 z"
style="fill:#c1212c;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path8557" />
</g>
<g
id="g8559"
transform="translate(1463.4824,2855.2529)">
<path
d="m 0,0 -188,0 c -6.556,0 -11.482,-5.1 -11.482,-11.656 l 0,-56 c 0,-6.893 5.141,-12.344 11.482,-12.344 l 188,0 c 5.994,0 13.964,3.84 17.766,8.656 l 16.822,21.471 C 37.511,-46.17 44.209,-43 49.211,-43 l 20.789,0 17.5,0 2.018,0 0,1.844 0,2 0,2.156 -2.018,0 -17.5,0 -20.789,0 c -4.842,0 -11.54,3.225 -14.627,7.135 L 17.77,-8.402 C 14.065,-3.711 6.262,0 0,0 m 0,-2 c 5.5,0 12.788,-3.359 16.196,-7.677 L 33.015,-31.065 C 36.423,-35.383 43.711,-39 49.211,-39 l 20.789,0 17.518,0 0,-2 -17.518,0 -20.789,0 c -5.5,0 -12.788,-3.359 -16.196,-7.677 L 16.196,-70.065 C 12.788,-74.383 5.5,-78 0,-78 l -188,0 c -5.5,0 -9.482,4.844 -9.482,10.344 l 0,56 c 0,5.5 3.982,9.656 9.482,9.656 l 187.518,0"
style="fill:#d7d6d4;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path8561" />
</g>
</g>
</g>
</g>
</svg>

Finally, I removed some un-needed "g" container elements, removed the clip path (as it's not needed since we have a single object) and corrected the "translate" (x/y offsetting) by normalising the lowest pair to 0,0 (in this case 1275.4824,2776.2529) and then subtracted those values from the remaining translate transforms (1463.4824,2855.2529). This now gives us a shape that is drawn from a ZERO offset. One final task was to tweak the transform matrix (1.25,0,0,-1.25,-1369.1969,3999.9997) so we take the scale down to 1.0 and again correct the x/y positioning so the whole SVG is now at a zero offset. Most of these tweaks are needed simply because of the way Inkscape exported the original object to SVG:
<svg
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
>
<g
transform="matrix(1.0,0,0,-1.0,12,79)"
>
<g
id="g8555">
<path
d="m 0,0 c -5.79,0 -10.482,5.003 -10.482,11.344 l 0,56 C -10.482,73.428 -6.084,78 0,78 l 188,0 c 5.99,0 13.449,-3.583 16.981,-8.057 L 221.802,48.552 C 225.049,44.438 232.106,41 237.211,41 l 39.307,0 0,-4 -39.307,0 c -5.356,0 -12.27,-3.316 -15.411,-7.296 L 204.983,8.317 C 201.345,3.709 193.728,0 188,0 L 0,0 z"
style="fill:#c1212c;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path8557" />
</g>
<g
id="g8559"
transform="translate(188,79)">
<path
d="m 0,0 -188,0 c -6.556,0 -11.482,-5.1 -11.482,-11.656 l 0,-56 c 0,-6.893 5.141,-12.344 11.482,-12.344 l 188,0 c 5.994,0 13.964,3.84 17.766,8.656 l 16.822,21.471 C 37.511,-46.17 44.209,-43 49.211,-43 l 20.789,0 17.5,0 2.018,0 0,1.844 0,2 0,2.156 -2.018,0 -17.5,0 -20.789,0 c -4.842,0 -11.54,3.225 -14.627,7.135 L 17.77,-8.402 C 14.065,-3.711 6.262,0 0,0 m 0,-2 c 5.5,0 12.788,-3.359 16.196,-7.677 L 33.015,-31.065 C 36.423,-35.383 43.711,-39 49.211,-39 l 20.789,0 17.518,0 0,-2 -17.518,0 -20.789,0 c -5.5,0 -12.788,-3.359 -16.196,-7.677 L 16.196,-70.065 C 12.788,-74.383 5.5,-78 0,-78 l -188,0 c -5.5,0 -9.482,4.844 -9.482,10.344 l 0,56 c 0,5.5 3.982,9.656 9.482,9.656 l 187.518,0"
style="fill:#d7d6d4;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path8561" />
</g>
</g>
</svg>

... and the resultant individual SVG object:

Quite a nice result... all that is left now is to get the rest of the site working and the positioning correct ;-)

3 comments:

Churchill said...

They collaborate smoothly with the in-house team and manage the project smoothly.
best web design firms

Aubrey Dickey said...

They have a very open approach and were completely transparent throughout the project.
UX consulting company

Harry Jack said...

You guys present there are performing an excellent job.
top design agencies in San Francisco