source: spip-zone/_plugins_/filtres_images_vectorise/trunk/filtres/image_potrace.php @ 116199

Last change on this file since 116199 was 116199, checked in by cedric@…, 21 months ago

Un plugin pour vectoriser en SVG des images bitmap, qui propose 4 nouveaux filtres

  • extraire_palette_couleurs permet d'extraire une palette de couleur d'une image (par defaut les 3 couleurs les plus representees) en utilisant un calcul des couleurs dominantes par partitionnement en k-moyennes

`
<BOUCLE_palette(POUR){tableau #FICHIER|extraire_palette_couleurs{3}}>
<div style="display: inline-block;width: 30px;height: 15px;background-color: #VALEUR;"></div>
</BOUCLE_palette>
`

  • image_geometrize permet de creer une image SVG approchante de l'image d'origine en utilisant le lib GeometrizePHP https://github.com/Cerdic/geometrize-php/ (attention methode gourmande en temps de calcul)
  • image_potrace permet de generer un trace SVG depuis l'image d'origine, a l'aide de Potracio PHP qui est un portage PHP de PotRace? https://seenthis.net/messages/645575
  • image_geopotrize combine les 2 techniques : un background geometrize qui n'a pas besoin d'un grand nombre de shapes et un trace potrace superpose/mixe

Les 3 filtres ont tout un tas d'option pour qui veut jouer avec, mais les reglages par defaut permettent d'avoir immediatement un joli resultat exploitable
A noter que pour image_geometrize, le temps de calcul peut depasser les 30s pour generer le nombre de shapes demandees, selon les reglages utilises.
Dans ce cas le calcul est arrete au bout de 20s, on stocke et on renvoie l'image provisoire incomplete, et on stocke l'etat du calcul qui reprendra au prochain calcul de la page.

(J'evite les screenshots dans le message de commit mais le coeur y est)

File size: 3.7 KB
Line 
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
12use 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 */
23function 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
138if (!function_exists('_svg_round_point')) {
139        function _svg_round_point($m) {
140                return round($m[0]);
141        }
142}
Note: See TracBrowser for help on using the repository browser.