Coverage for pyquickhelper/imghelper/svg_helper.py: 100%

37 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-06-03 02:21 +0200

1""" 

2@file 

3@brief Helpers around images and :epkg:`SVG`. 

4""" 

5import xml.etree.ElementTree as ET 

6from io import BytesIO 

7from .excs import PYQImageException 

8 

9 

10def guess_svg_size(svg): 

11 """ 

12 Guesses the dimension of a :epkg:`SVG` image. 

13 

14 @param svg :epkg:`SVG` description 

15 @return size (x, y) 

16 """ 

17 mx, my = 0, 0 

18 tree = ET.fromstring(svg) 

19 for elt in tree.iter(): 

20 for k, v in elt.attrib.items(): 

21 if k in ('x', 'cx', 'width'): 

22 mx = max(0, int(v)) 

23 elif k in ('rx',): 

24 mx = max(0, 2 * int(v)) 

25 elif k in ('y', 'cy', 'height'): 

26 my = max(0, int(v)) 

27 elif k in ('ry',): 

28 my = max(0, 2 * int(v)) 

29 return (mx, my) 

30 

31 

32def svg2img(svg, dpi=None, scale=1., **kwargs): 

33 """ 

34 Converts an image in :epkg:`SVG` format. 

35 

36 @param svg svg 

37 @param dpi image resolution 

38 @param scale scale 

39 @param kwargs additional parameters 

40 @return image 

41 

42 The module relies on the following dependencies: 

43 

44 * :epkg:`cairosvg` 

45 * :epkg:`Pillow` 

46 """ 

47 kwargs = {} 

48 if dpi: 

49 kwargs['dpi'] = dpi 

50 if scale not in (None, 1., 1): 

51 kwargs['scale'] = scale 

52 from cairosvg import svg2png 

53 img = BytesIO() 

54 try: 

55 svg2png(svg, write_to=img, **kwargs) 

56 except (ValueError, OSError) as e: 

57 if svg.startswith('<svg>'): 

58 size = guess_svg_size(svg) 

59 head = '<svg width="{}" height="{}">'.format(*size) 

60 svg = head + svg[5:] 

61 return svg2img(svg, **kwargs) 

62 raise PYQImageException( # pragma: no cover 

63 "width and height must be specified. " 

64 "This might be the error.") from e 

65 png = img.getvalue() 

66 st = BytesIO(png) 

67 from PIL import Image 

68 return Image.open(st)