Try using scour to clean an svg

2019-06-09 14:32发布

I try to use scour from inside python, to clean up an svg which was coming out of svgutils.

        from scour import scour
        options = "--remove-metadata"
        with open(input_svg, 'rb') as f1:
            with open(output_svg, 'wb') as f2:
                scour.start(options, f1, f2)

If I do, it fails with a decimal error message:

File "C:\Users\Andreas\Anaconda3\lib\site-packages\scour\scour.py", line 2762, in scourUnitlessLength
length = getcontext().create_decimal(str(length))

InvalidOperation: [<class 'decimal.ConversionSyntax'>]

I tried to repeat the same in the CLI to see if it was my python text that was wrong, but the same error appears. The SVG seems to be fine - I even made a very small test svg to make sure it is not a failure coming from the data.

Is there something I could have overlooked? Is scour even the right way to clean svg from inside python or should I do it in a different way?

标签: python svg
1条回答
欢心
2楼-- · 2019-06-09 15:15

Finally...

My solution to my problem.

svgutils delivers an svg that is technically correct, but it always adds a unit to the sizes and coordinates in an svg. 456.0 --> 456.0pt

Technically that is wrong as the original unit free values should stay like that. This was killing scour. Sadly there was little activity in the scour community since some years, otherwise it would be worth it to notify them about their bug.

My solution to work svgutils and scour together:

from scour import scour
import svgutils
import re


sv1 = svgutils.transform.fromfile(svg_file)
# do something with the svg here

reg = re.compile("(\.\d)(pt)") # regex to search numbers with "pt"

svg = sv1.to_str().decode() # svgutils delivers ascii byte strings.
svg = reg.sub(r"\1", svg) # the incorrectly added "pt" unit is removed here

scour_options = scour.sanitizeOptions(options=None) # get a clean scour options object
scour_options.remove_metadata = True # change any option you like
clean_svg = scour.scourString(svg, options = scour_options) # use scour

This works. :-)

查看更多
登录 后发表回答