1 | <?php |
---|
2 | /** |
---|
3 | * Generation d'une preview svg |
---|
4 | * |
---|
5 | * @plugin Adaptive Images |
---|
6 | * @copyright 2013-2019 |
---|
7 | * @author Cedric |
---|
8 | * @licence GNU/GPL |
---|
9 | * @package SPIP\Adaptive_Images\Preview |
---|
10 | */ |
---|
11 | |
---|
12 | use Potracio\Potracio; |
---|
13 | |
---|
14 | /** |
---|
15 | * Generation d'une Image SVG a partir d'un bitmap |
---|
16 | * en utilisant Potracio PHP qui est un portage PHP de PotRace |
---|
17 | * https://seenthis.net/messages/645575 |
---|
18 | * |
---|
19 | * @param string $img |
---|
20 | * @param array $options |
---|
21 | * @return string |
---|
22 | */ |
---|
23 | function image_potrace($img, $options=[]) { |
---|
24 | |
---|
25 | include_spip("inc/filtres_images_lib_mini"); |
---|
26 | include_spip('lib/potracio/Potracio'); |
---|
27 | include_spip('filtres/couleurs'); |
---|
28 | |
---|
29 | // dimension de la miniature a vectoriser |
---|
30 | $width_thumb = 512; |
---|
31 | if (isset($options['width_thumb'])) { |
---|
32 | $width_thumb = $options['width_thumb']; |
---|
33 | unset($options['width_thumb']); |
---|
34 | } |
---|
35 | $potconfig = [ |
---|
36 | 'turnpolicy' => "minority", // "black" / "white" / "left" / "right" / "minority" / "majority" |
---|
37 | 'turdsize' => 2, |
---|
38 | 'optcurve' => true, |
---|
39 | 'alphamax' => 0.75, |
---|
40 | 'opttolerance' => 0.2, |
---|
41 | 'rounding' => 1, |
---|
42 | 'bgcolor' => 'auto', |
---|
43 | 'color' => 'auto' |
---|
44 | ]; |
---|
45 | $potconfig = array_merge($potconfig, $options); |
---|
46 | |
---|
47 | $cache = _image_valeurs_trans($img, "image_potrace-$width_thumb-".json_encode($potconfig), "svg"); |
---|
48 | if (!$cache) { |
---|
49 | return false; |
---|
50 | } |
---|
51 | // facile ! |
---|
52 | if ($cache['format_source'] === 'svg'){ |
---|
53 | return $img; |
---|
54 | } |
---|
55 | |
---|
56 | if ($cache["creer"]) { |
---|
57 | $fichier = $cache["fichier"]; |
---|
58 | $dest = $cache["fichier_dest"]; |
---|
59 | |
---|
60 | if (!@file_exists($fichier)) { |
---|
61 | return false; |
---|
62 | } |
---|
63 | |
---|
64 | $thumb = image_reduire($img,$width_thumb); |
---|
65 | $source = extraire_attribut($thumb, 'src'); |
---|
66 | |
---|
67 | if ($potconfig['bgcolor'] === 'auto' or $potconfig['color'] === 'auto') { |
---|
68 | $palette = extraire_palette_couleurs($img, 5, 32); |
---|
69 | |
---|
70 | $couleur_bg = array_shift($palette); |
---|
71 | $couleur_1 = reset($palette); |
---|
72 | if (couleur_luminance_relative($couleur_bg) < couleur_luminance_relative($couleur_1)) { |
---|
73 | $couleur_1 = $couleur_bg; |
---|
74 | $couleur_bg = reset($palette); |
---|
75 | } |
---|
76 | $couleur_bg = '#'.ltrim(couleur_eclaircir_si_foncee($couleur_bg),'#'); |
---|
77 | $couleur_1 = '#'.ltrim(couleur_foncer_si_claire($couleur_1),'#'); |
---|
78 | } |
---|
79 | if ($potconfig['bgcolor'] !== 'auto') { |
---|
80 | $couleur_bg = $potconfig['bgcolor']; |
---|
81 | } |
---|
82 | if ($potconfig['color'] !== 'auto') { |
---|
83 | $couleur_1 = $potconfig['color']; |
---|
84 | } |
---|
85 | |
---|
86 | $rounding = $potconfig['rounding']; |
---|
87 | unset($potconfig['rounding']); |
---|
88 | |
---|
89 | $pot = new Potracio(); |
---|
90 | $pot->loadImageFromFile($source); |
---|
91 | $pot->setParameter($potconfig); |
---|
92 | |
---|
93 | $pot->process(); |
---|
94 | $coeffSize = 1; |
---|
95 | if ($rounding !== false and $rounding !== 'off') { |
---|
96 | if (strpos($rounding, 'width=') === 0) { |
---|
97 | $coeffSize = intval(substr($rounding,6)) / $width_thumb; |
---|
98 | $rounding = false; |
---|
99 | } |
---|
100 | else { |
---|
101 | $rounding = intval($rounding); |
---|
102 | while ($rounding-->0) { |
---|
103 | $coeffSize *= 10; |
---|
104 | } |
---|
105 | } |
---|
106 | } |
---|
107 | $svg_image = $pot->getSVG($coeffSize); |
---|
108 | |
---|
109 | $svg_image = explode('>', $svg_image, 2); |
---|
110 | |
---|
111 | $t = $svg_image[0] . '>'; |
---|
112 | $w = extraire_attribut($t, "width"); |
---|
113 | $h = extraire_attribut($t, "height"); |
---|
114 | |
---|
115 | $svg_image[0] = "<svg viewBox=\"0 0 $w $h\" xmlns=\"http://www.w3.org/2000/svg\">"; |
---|
116 | if ($couleur_bg !== 'transparent') { |
---|
117 | $svg_image[0] .= "<rect width=\"100%\" height=\"100%\" fill=\"$couleur_bg\"/>"; |
---|
118 | } |
---|
119 | |
---|
120 | // optimize the size : round all points to integer |
---|
121 | if ($rounding !== false and $rounding !== 'off'){ |
---|
122 | $svg_image[1] = preg_replace_callback(",\b(\d+\.\d+)\b,ims", "_svg_round_point", $svg_image[1]); |
---|
123 | } |
---|
124 | $svg_image[1] = preg_replace(",(\s)\s+,", "\\1", $svg_image[1]); |
---|
125 | $svg_image[1] = str_replace("black", $couleur_1, $svg_image[1]); |
---|
126 | $svg_image = $svg_image[0] . $svg_image[1]; |
---|
127 | |
---|
128 | ecrire_fichier($dest, $svg_image); |
---|
129 | } |
---|
130 | |
---|
131 | if (!@file_exists($dest)) { |
---|
132 | return false; |
---|
133 | } |
---|
134 | |
---|
135 | return _image_ecrire_tag($cache, array('src' => $cache["fichier_dest"])); |
---|
136 | } |
---|
137 | |
---|
138 | if (!function_exists('_svg_round_point')) { |
---|
139 | function _svg_round_point($m) { |
---|
140 | return round($m[0]); |
---|
141 | } |
---|
142 | } |
---|