source: spip-zone/_plugins_/filtres_images_vectorise/trunk/lib/geometrize/src/Bitmap.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.8 KB
Line 
1<?php
2
3namespace Cerdic\Geometrize;
4
5class Bitmap {
6        /**
7         * @var int
8         */
9        public $width;
10
11        /**
12         * @var int
13         */
14        public $height;
15
16        /**
17         * @var array
18         */
19        public $data;
20
21        /**
22         * @var array
23         */
24        public $errorCache;
25
26        public function __construct(){
27                $this->data = [];
28                $this->errorCache = [];
29        }
30
31        /**
32         * @param int $x
33         * @param int $y
34         * @return int
35         */
36        public function getPixel($x, $y){
37                return isset($this->data[$y][$x]) ? $this->data[$y][$x] : 255;
38        }
39
40        /**
41         * @param int $x
42         * @param int $y
43         * @param int $color
44         */
45        public function setPixel($x, $y, $color){
46                $this->data[$y][$x] = $color;
47        }
48
49        /**
50         * @return int
51         */
52        public function length() {
53                return $this->width * $this->height;
54        }
55
56        /**
57         * @param int $color
58         */
59        public function fill($color){
60                for ($y=0;$y<$this->height;$y++) {
61                        for ($x=0;$x<$this->width;$x++) {
62                                $this->data[$y][$x] = $color;
63                        }
64                }
65        }
66
67        /**
68         * @param string $file
69         * @param string $extension
70         * @param int|null $quality
71         * @return bool
72         */
73        public function exportToImageFile($file, $extension, $quality = null) {
74                $extension = strtolower($extension);
75                if (!in_array($extension, ['gif', 'png', 'jpg'])) {
76                        return false;
77                }
78
79                $img = imagecreatetruecolor($this->width, $this->height);
80                for($x = 0; $x<$this->width; $x++) {
81                        for($y = 0; $y<$this->height; $y++){
82                                $color = $this->getPixel($x, $y);
83                                $c = Bitmap::colorToRGBAArray($color);
84                                $color = imagecolorallocatealpha($img, $c['red'], $c['green'], $c['blue'], $c['alpha']);
85                                imagesetpixel($img, $x, $y, $color);
86                        }
87                }
88
89                $tmp_file = $file . ".tmp";
90                $res = false;
91                switch ($extension) {
92                        case 'png':
93                                $res = imagepng($img, $tmp_file);
94                                break;
95                        case 'gif':
96                                $res = imagegif($img, $tmp_file);
97                                break;
98                        case 'jpg':
99                                // Enable interlancing
100                                imageinterlace($img, true);
101                                $res = imagejpeg($img, $tmp_file, is_null($quality) ? 85 : $quality);
102                                break;
103                }
104
105                if (!$res || !file_exists($tmp_file)) {
106                        return false;
107                }
108
109                $size = getimagesize($tmp_file);
110                if ($size[0]<1) {
111                        @unlink($tmp_file);
112                        return false;
113                }
114
115                @rename($tmp_file, $file);
116                return true;
117        }
118
119        /**
120         * @param int $w
121         * @param int $h
122         * @param int $color
123         * @return \Cerdic\Geometrize\Bitmap
124         */
125        public static function create($w, $h, $color){
126                $bitmap = new Bitmap();
127                $bitmap->width = $w;
128                $bitmap->height = $h;
129                $bitmap->fill($color);
130                return $bitmap;
131        }
132
133        /**
134         * @param string $file
135         * @return \Cerdic\Geometrize\Bitmap
136         */
137        public static function createFromImageFile($file){
138                list($w, $h) = getimagesize($file);
139                $image = imagecreatefromstring(file_get_contents($file));
140
141                $bitmap = new Bitmap();
142                $bitmap->width = $w;
143                $bitmap->height = $h;
144
145                for ($y = 0; $y<$h; $y++){
146                        for ($x = 0; $x<$w; $x++){
147                                // get a color
148                                $color_index = imagecolorat($image, $x, $y);
149                                // make it human readable
150                                $c = imagecolorsforindex($image, $color_index);
151                                $bitmap->data[$y][$x] = Bitmap::colorFromRGBAArray($c);
152                        }
153                }
154
155                return $bitmap;
156        }
157
158        /**
159         * Convert color from HTML RGBA to Geometrize color system
160         * @param array $c
161         * @return int
162         */
163        public static function colorFromRGBAArray($c){
164                if (isset($c['alpha'])){
165                        // in RGBA 0 = opaque, 127 = transparent
166                        // in geometrize 0 = transparent, 255 = opaque
167                        $c['alpha'] = round((127-$c['alpha'])*255/127);
168                } else {
169                        $c['alpha'] = 255;
170                }
171                $color = ($c['red'] << 24) + ($c['green'] << 16) + ($c['blue'] << 8) + $c['alpha'];
172                return $color;
173        }
174
175        /**
176         * Convert color from Geometrize color system to HTML RGBA to
177         * @param int $color
178         * @return array
179         */
180        public static function colorToRGBAArray($color){
181                $c = [
182                        'red' => ($color >> 24) & 255,
183                        'green' => ($color >> 16) & 255,
184                        'blue' => ($color >> 8) & 255,
185                        'alpha' => $color & 255
186                ];
187
188                $c['alpha'] = round( (255-$c['alpha']) * 127 / 255);
189                return $c;
190        }
191       
192}
Note: See TracBrowser for help on using the repository browser.