source: spip-zone/_plugins_/filtres_images_vectorise/trunk/lib/geometrize/src/Model.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.4 KB
Line 
1<?php
2
3namespace Cerdic\Geometrize;
4
5use \Cerdic\Geometrize\Bitmap;
6use \Cerdic\Geometrize\Bitmap\DominantColours;
7use \Cerdic\Geometrize\Core;
8use \Cerdic\Geometrize\Rasterizer\Rasterizer;
9use \Cerdic\Geometrize\Shape\Rectangle;
10
11class Model {
12        /**
13         * @var int
14         */
15        protected $width;
16
17        /**
18         * @var int
19         */
20        protected $height;
21
22        /**
23         * @var int|bool
24         */
25        protected $backgroundColor;
26
27        /**
28         * @var \Cerdic\Geometrize\Bitmap
29         */
30        protected $target;
31
32        /**
33         * @var \Cerdic\Geometrize\Bitmap
34         */
35        protected $current;
36
37        /**
38         * @var \Cerdic\Geometrize\Bitmap
39         */
40        protected $buffer;
41
42        /**
43         * @var float
44         */
45        protected $shapeSizeFactor;
46
47        /**
48         * @var float
49         */
50        protected $score;
51
52        /**
53         * Model constructor.
54         * @param Bitmap $target
55         * @param int|bool $backgroundColor
56         * @throws \Exception
57         */
58        public function __construct($target, $backgroundColor){
59                if (!($target!==null)){
60                        throw new \Exception("FAIL: target != null");
61                }
62                $this->width = $target->width;
63                $this->height = $target->height;
64                $this->target = $target;
65
66                $this->backgroundColor = $backgroundColor;
67
68                // automatic best backgroundColor (lowering the error) ?
69                if ($this->backgroundColor === true) {
70                        $bg = new Rectangle($this->width, $this->height, 1, true);
71                        $dominantColours = DominantColours::dominantColours(3, $this->target, $bg->rasterize());
72                        $this->backgroundColor = reset($dominantColours);
73                }
74
75                $this->current = Bitmap::create($this->width,$this->height,$this->backgroundColor);
76                $this->score = Core::differenceFull($target, $this->current);
77
78                $this->buffer = clone $this->current;
79
80                $this->shapeSizeFactor = 1.0;
81        }
82
83        /**
84         * @param array $shapeTypes
85         * @param int $alpha
86         * @param int $nRandom
87         * @param int $maxMutationAge
88         * @return array
89         * @throws \Exception
90         */
91        public function step($shapeTypes, $alpha, $nRandom, $maxMutationAge){
92                $state = Core::bestHillClimbState($shapeTypes, $this->shapeSizeFactor, $alpha, $nRandom, $maxMutationAge, $this->target, $this->current, $this->buffer, $this->score);
93                return $this->addShape($state->getShape(), $state->getAlpha());
94        }
95
96        /**
97         * @param \Cerdic\Geometrize\Shape\Shape $shape
98         * @param int $alpha
99         * @return array
100         * @throws \Exception
101         */
102        public function addShape($shape, $alpha){
103                if (!($shape!==null)){
104                        throw new \Exception("FAIL: shape != null");
105                }
106                $before = clone $this->current;
107
108                $lines = $shape->rasterize();
109                if (!isset($shape->color)){
110                        $shape->color = Core::computeColor($this->target, $this->current, $lines, $alpha);
111                }
112
113                Rasterizer::drawLines($this->current, $shape->color, $lines);
114                $this->score = Core::differencePartial($this->target, $before, $this->current, $this->score, $lines);
115                $score_normalization = $before->width * $before->height * 4 * 255;
116                $result = ["score" => $this->score/$score_normalization, "color" => $shape->color, "shape" => $shape];
117
118                $this->shapeSizeFactor = 0.75 * $this->shapeSizeFactor + 0.25 * $shape->getSizeFactor();
119                $this->shapeSizeFactor = max(min($this->shapeSizeFactor, 1.0),0.1);
120                return $result;
121        }
122
123        /**
124         * @return \Cerdic\Geometrize\Bitmap
125         */
126        public function getCurrent() {
127                return $this->current;
128        }
129
130        /**
131         * @return int
132         */
133        public function getHeight() {
134                return $this->height;
135        }
136
137        /**
138         * @return int
139         */
140        public function getWidth() {
141                return $this->width;
142        }
143
144        /**
145         * @return bool|int
146         */
147        public function getBackgroundColor() {
148                return $this->backgroundColor;
149        }
150
151}
Note: See TracBrowser for help on using the repository browser.