Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1""" 

2@file 

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

4 

5.. versionadded:: 1.7 

6""" 

7import xml.etree.ElementTree as ET 

8from io import BytesIO 

9from .excs import PYQImageException 

10 

11 

12def guess_svg_size(svg): 

13 """ 

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

15 

16 @param svg :epkg:`SVG` description 

17 @return size (x, y) 

18 """ 

19 mx, my = 0, 0 

20 tree = ET.fromstring(svg) 

21 for elt in tree.iter(): 

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

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

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

25 elif k in ('rx',): 

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

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

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

29 elif k in ('ry',): 

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

31 return (mx, my) 

32 

33 

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

35 """ 

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

37 

38 @param svg svg 

39 @param dpi image resolution 

40 @param scale scale 

41 @param kwargs additional parameters 

42 @return image 

43 

44 The module relies on the following dependencies: 

45 

46 * :epkg:`cairosvg` 

47 * :epkg:`Pillow` 

48 """ 

49 kwargs = {} 

50 if dpi: 

51 kwargs['dpi'] = dpi 

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

53 kwargs['scale'] = scale 

54 from cairosvg import svg2png 

55 img = BytesIO() 

56 try: 

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

58 except OSError as e: 

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

60 size = guess_svg_size(svg) 

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

62 svg = head + svg[5:] 

63 return svg2img(svg, dpi=dpi, scale=scale, **kwargs) 

64 else: 

65 raise PYQImageException( # pragma: no cover 

66 "width and height must be specified. This might be the error.") from e 

67 png = img.getvalue() 

68 st = BytesIO(png) 

69 from PIL import Image 

70 return Image.open(st)