File indexing completed on 2024-12-22 05:36:24
0001 <?php 0002 /** 0003 * ocs-webserver 0004 * 0005 * Copyright 2016 by pling GmbH. 0006 * 0007 * This file is part of ocs-webserver. 0008 * 0009 * This program is free software: you can redistribute it and/or modify 0010 * it under the terms of the GNU Affero General Public License as 0011 * published by the Free Software Foundation, either version 3 of the 0012 * License, or (at your option) any later version. 0013 * 0014 * This program is distributed in the hope that it will be useful, 0015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0017 * GNU Affero General Public License for more details. 0018 * 0019 * You should have received a copy of the GNU Affero General Public License 0020 * along with this program. If not, see <http://www.gnu.org/licenses/>. 0021 **/ 0022 0023 /** 0024 * Class Local_Tools_Identicon 0025 * 0026 * This is based on the source from the PHP Identicons Project 0027 * from sourceforge.net. 0028 */ 0029 class Local_Tools_Identicon 0030 { 0031 0032 protected $_spriteZ; 0033 0034 function __construct() 0035 { 0036 $this->_spriteZ = 128; 0037 } 0038 0039 0040 /* generate sprite for corners and sides */ 0041 0042 public function renderIdentIcon($hash = '', $size = 100) 0043 { 0044 /* parse hash string */ 0045 $csh = hexdec(substr($hash, 0, 1)); // corner sprite shape 0046 $ssh = hexdec(substr($hash, 1, 1)); // side sprite shape 0047 $xsh = hexdec(substr($hash, 2, 1)) & 7; // center sprite shape 0048 0049 $cro = hexdec(substr($hash, 3, 1)) & 3; // corner sprite rotation 0050 $sro = hexdec(substr($hash, 4, 1)) & 3; // side sprite rotation 0051 $xbg = hexdec(substr($hash, 5, 1)) % 2; // center sprite background 0052 0053 /* corner sprite foreground color */ 0054 $cfr = hexdec(substr($hash, 6, 2)); 0055 $cfg = hexdec(substr($hash, 8, 2)); 0056 $cfb = hexdec(substr($hash, 10, 2)); 0057 0058 /* side sprite foreground color */ 0059 $sfr = hexdec(substr($hash, 12, 2)); 0060 $sfg = hexdec(substr($hash, 14, 2)); 0061 $sfb = hexdec(substr($hash, 16, 2)); 0062 0063 /* final angle of rotation */ 0064 $angle = hexdec(substr($hash, 18, 2)); 0065 0066 /* size of each sprite */ 0067 $spriteZ = $this->_spriteZ; 0068 0069 /* start with blank 3x3 identicon */ 0070 $identicon = imagecreatetruecolor($spriteZ * 3, $spriteZ * 3); 0071 if (function_exists('imageantialias')) { 0072 imageantialias($identicon, true); 0073 } 0074 0075 /* assign white as background */ 0076 $bg = imagecolorallocate($identicon, 255, 255, 255); 0077 imagefilledrectangle($identicon, 0, 0, $spriteZ, $spriteZ, $bg); 0078 0079 /* generate corner sprites */ 0080 $corner = $this->getsprite($csh, $cfr, $cfg, $cfb, $cro); 0081 imagecopy($identicon, $corner, 0, 0, 0, 0, $spriteZ, $spriteZ); 0082 $corner = imagerotate($corner, 90, $bg); 0083 imagecopy($identicon, $corner, 0, $spriteZ * 2, 0, 0, $spriteZ, $spriteZ); 0084 $corner = imagerotate($corner, 90, $bg); 0085 imagecopy($identicon, $corner, $spriteZ * 2, $spriteZ * 2, 0, 0, $spriteZ, $spriteZ); 0086 $corner = imagerotate($corner, 90, $bg); 0087 imagecopy($identicon, $corner, $spriteZ * 2, 0, 0, 0, $spriteZ, $spriteZ); 0088 0089 /* generate side sprites */ 0090 $side = $this->getsprite($ssh, $sfr, $sfg, $sfb, $sro); 0091 imagecopy($identicon, $side, $spriteZ, 0, 0, 0, $spriteZ, $spriteZ); 0092 $side = imagerotate($side, 90, $bg); 0093 imagecopy($identicon, $side, 0, $spriteZ, 0, 0, $spriteZ, $spriteZ); 0094 $side = imagerotate($side, 90, $bg); 0095 imagecopy($identicon, $side, $spriteZ, $spriteZ * 2, 0, 0, $spriteZ, $spriteZ); 0096 $side = imagerotate($side, 90, $bg); 0097 imagecopy($identicon, $side, $spriteZ * 2, $spriteZ, 0, 0, $spriteZ, $spriteZ); 0098 0099 /* generate center sprite */ 0100 $center = $this->getcenter($xsh, $cfr, $cfg, $cfb, $sfr, $sfg, $sfb, $xbg); 0101 imagecopy($identicon, $center, $spriteZ, $spriteZ, 0, 0, $spriteZ, $spriteZ); 0102 0103 // $identicon=imagerotate($identicon,$angle,$bg); 0104 0105 /* make white transparent */ 0106 imagecolortransparent($identicon, $bg); 0107 0108 /* create blank image according to specified dimensions */ 0109 $resized = imagecreatetruecolor($size, $size); 0110 if (function_exists('imageantialias')) { 0111 imageantialias($resized, true); 0112 } 0113 0114 /* assign white as background */ 0115 $bg = imagecolorallocate($resized, 255, 255, 255); 0116 imagefilledrectangle($resized, 0, 0, $size, $size, $bg); 0117 0118 /* resize identicon according to specification */ 0119 imagecopyresampled($resized, $identicon, 0, 0, (imagesx($identicon) - $spriteZ * 3) / 2, (imagesx($identicon) - $spriteZ * 3) / 2, $size, 0120 $size, $spriteZ * 3, $spriteZ * 3); 0121 0122 /* make white transparent */ 0123 imagecolortransparent($resized, $bg); 0124 0125 return $resized; 0126 0127 /* and finally, send to standard output */ 0128 //header("Content-Type: image/png"); 0129 //imagepng($resized); 0130 } 0131 0132 /* generate sprite for center block */ 0133 0134 protected function getsprite($shape, $R, $G, $B, $rotation) 0135 { 0136 $spriteZ = $this->_spriteZ; 0137 $sprite = imagecreatetruecolor($spriteZ, $spriteZ); 0138 if (function_exists('imageantialias')) { 0139 imageantialias($sprite, true); 0140 } 0141 $fg = imagecolorallocate($sprite, $R, $G, $B); 0142 $bg = imagecolorallocate($sprite, 255, 255, 255); 0143 imagefilledrectangle($sprite, 0, 0, $spriteZ, $spriteZ, $bg); 0144 switch ($shape) { 0145 case 0: // triangle 0146 $shape = array( 0147 0.5, 0148 1, 0149 1, 0150 0, 0151 1, 0152 1 0153 ); 0154 break; 0155 case 1: // parallelogram 0156 $shape = array( 0157 0.5, 0158 0, 0159 1, 0160 0, 0161 0.5, 0162 1, 0163 0, 0164 1 0165 ); 0166 break; 0167 case 2: // mouse ears 0168 $shape = array( 0169 0.5, 0170 0, 0171 1, 0172 0, 0173 1, 0174 1, 0175 0.5, 0176 1, 0177 1, 0178 0.5 0179 ); 0180 break; 0181 case 3: // ribbon 0182 $shape = array( 0183 0, 0184 0.5, 0185 0.5, 0186 0, 0187 1, 0188 0.5, 0189 0.5, 0190 1, 0191 0.5, 0192 0.5 0193 ); 0194 break; 0195 case 4: // sails 0196 $shape = array( 0197 0, 0198 0.5, 0199 1, 0200 0, 0201 1, 0202 1, 0203 0, 0204 1, 0205 1, 0206 0.5 0207 ); 0208 break; 0209 case 5: // fins 0210 $shape = array( 0211 1, 0212 0, 0213 1, 0214 1, 0215 0.5, 0216 1, 0217 1, 0218 0.5, 0219 0.5, 0220 0.5 0221 ); 0222 break; 0223 case 6: // beak 0224 $shape = array( 0225 0, 0226 0, 0227 1, 0228 0, 0229 1, 0230 0.5, 0231 0, 0232 0, 0233 0.5, 0234 1, 0235 0, 0236 1 0237 ); 0238 break; 0239 case 7: // chevron 0240 $shape = array( 0241 0, 0242 0, 0243 0.5, 0244 0, 0245 1, 0246 0.5, 0247 0.5, 0248 1, 0249 0, 0250 1, 0251 0.5, 0252 0.5 0253 ); 0254 break; 0255 case 8: // fish 0256 $shape = array( 0257 0.5, 0258 0, 0259 0.5, 0260 0.5, 0261 1, 0262 0.5, 0263 1, 0264 1, 0265 0.5, 0266 1, 0267 0.5, 0268 0.5, 0269 0, 0270 0.5 0271 ); 0272 break; 0273 case 9: // kite 0274 $shape = array( 0275 0, 0276 0, 0277 1, 0278 0, 0279 0.5, 0280 0.5, 0281 1, 0282 0.5, 0283 0.5, 0284 1, 0285 0.5, 0286 0.5, 0287 0, 0288 1 0289 ); 0290 break; 0291 case 10: // trough 0292 $shape = array( 0293 0, 0294 0.5, 0295 0.5, 0296 1, 0297 1, 0298 0.5, 0299 0.5, 0300 0, 0301 1, 0302 0, 0303 1, 0304 1, 0305 0, 0306 1 0307 ); 0308 break; 0309 case 11: // rays 0310 $shape = array( 0311 0.5, 0312 0, 0313 1, 0314 0, 0315 1, 0316 1, 0317 0.5, 0318 1, 0319 1, 0320 0.75, 0321 0.5, 0322 0.5, 0323 1, 0324 0.25 0325 ); 0326 break; 0327 case 12: // double rhombus 0328 $shape = array( 0329 0, 0330 0.5, 0331 0.5, 0332 0, 0333 0.5, 0334 0.5, 0335 1, 0336 0, 0337 1, 0338 0.5, 0339 0.5, 0340 1, 0341 0.5, 0342 0.5, 0343 0, 0344 1 0345 ); 0346 break; 0347 case 13: // crown 0348 $shape = array( 0349 0, 0350 0, 0351 1, 0352 0, 0353 1, 0354 1, 0355 0, 0356 1, 0357 1, 0358 0.5, 0359 0.5, 0360 0.25, 0361 0.5, 0362 0.75, 0363 0, 0364 0.5, 0365 0.5, 0366 0.25 0367 ); 0368 break; 0369 case 14: // radioactive 0370 $shape = array( 0371 0, 0372 0.5, 0373 0.5, 0374 0.5, 0375 0.5, 0376 0, 0377 1, 0378 0, 0379 0.5, 0380 0.5, 0381 1, 0382 0.5, 0383 0.5, 0384 1, 0385 0.5, 0386 0.5, 0387 0, 0388 1 0389 ); 0390 break; 0391 default: // tiles 0392 $shape = array( 0393 0, 0394 0, 0395 1, 0396 0, 0397 0.5, 0398 0.5, 0399 0.5, 0400 0, 0401 0, 0402 0.5, 0403 1, 0404 0.5, 0405 0.5, 0406 1, 0407 0.5, 0408 0.5, 0409 0, 0410 1 0411 ); 0412 break; 0413 } 0414 /* apply ratios */ 0415 for ($i = 0; $i < count($shape); $i++) { 0416 $shape[$i] = $shape[$i] * $spriteZ; 0417 } 0418 imagefilledpolygon($sprite, $shape, count($shape) / 2, $fg); 0419 /* rotate the sprite */ 0420 for ($i = 0; $i < $rotation; $i++) { 0421 $sprite = imagerotate($sprite, 90, $bg); 0422 } 0423 return $sprite; 0424 } 0425 0426 protected function getcenter($shape, $fR, $fG, $fB, $bR, $bG, $bB, $usebg) 0427 { 0428 $spriteZ = $this->_spriteZ; 0429 $sprite = imagecreatetruecolor($spriteZ, $spriteZ); 0430 if (function_exists('imageantialias')) { 0431 imageantialias($sprite, true); 0432 } 0433 0434 $fg = imagecolorallocate($sprite, $fR, $fG, $fB); 0435 /* make sure there's enough contrast before we use background color of side sprite */ 0436 if ($usebg > 0 && (abs($fR - $bR) > 127 || abs($fG - $bG) > 127 || abs($fB - $bB) > 127)) { 0437 $bg = imagecolorallocate($sprite, $bR, $bG, $bB); 0438 } else { 0439 $bg = imagecolorallocate($sprite, 255, 255, 255); 0440 } 0441 imagefilledrectangle($sprite, 0, 0, $spriteZ, $spriteZ, $bg); 0442 switch ($shape) { 0443 case 0: // empty 0444 $shape = array(); 0445 break; 0446 case 1: // fill 0447 $shape = array( 0448 0, 0449 0, 0450 1, 0451 0, 0452 1, 0453 1, 0454 0, 0455 1 0456 ); 0457 break; 0458 case 2: // diamond 0459 $shape = array( 0460 0.5, 0461 0, 0462 1, 0463 0.5, 0464 0.5, 0465 1, 0466 0, 0467 0.5 0468 ); 0469 break; 0470 case 3: // reverse diamond 0471 $shape = array( 0472 0, 0473 0, 0474 1, 0475 0, 0476 1, 0477 1, 0478 0, 0479 1, 0480 0, 0481 0.5, 0482 0.5, 0483 1, 0484 1, 0485 0.5, 0486 0.5, 0487 0, 0488 0, 0489 0.5 0490 ); 0491 break; 0492 case 4: // cross 0493 $shape = array( 0494 0.25, 0495 0, 0496 0.75, 0497 0, 0498 0.5, 0499 0.5, 0500 1, 0501 0.25, 0502 1, 0503 0.75, 0504 0.5, 0505 0.5, 0506 0.75, 0507 1, 0508 0.25, 0509 1, 0510 0.5, 0511 0.5, 0512 0, 0513 0.75, 0514 0, 0515 0.25, 0516 0.5, 0517 0.5 0518 ); 0519 break; 0520 case 5: // morning star 0521 $shape = array( 0522 0, 0523 0, 0524 0.5, 0525 0.25, 0526 1, 0527 0, 0528 0.75, 0529 0.5, 0530 1, 0531 1, 0532 0.5, 0533 0.75, 0534 0, 0535 1, 0536 0.25, 0537 0.5 0538 ); 0539 break; 0540 case 6: // small square 0541 $shape = array( 0542 0.33, 0543 0.33, 0544 0.67, 0545 0.33, 0546 0.67, 0547 0.67, 0548 0.33, 0549 0.67 0550 ); 0551 break; 0552 case 7: // checkerboard 0553 $shape = array( 0554 0, 0555 0, 0556 0.33, 0557 0, 0558 0.33, 0559 0.33, 0560 0.66, 0561 0.33, 0562 0.67, 0563 0, 0564 1, 0565 0, 0566 1, 0567 0.33, 0568 0.67, 0569 0.33, 0570 0.67, 0571 0.67, 0572 1, 0573 0.67, 0574 1, 0575 1, 0576 0.67, 0577 1, 0578 0.67, 0579 0.67, 0580 0.33, 0581 0.67, 0582 0.33, 0583 1, 0584 0, 0585 1, 0586 0, 0587 0.67, 0588 0.33, 0589 0.67, 0590 0.33, 0591 0.33, 0592 0, 0593 0.33 0594 ); 0595 break; 0596 } 0597 /* apply ratios */ 0598 for ($i = 0; $i < count($shape); $i++) { 0599 $shape[$i] = $shape[$i] * $spriteZ; 0600 } 0601 if (count($shape) > 0) { 0602 imagefilledpolygon($sprite, $shape, count($shape) / 2, $fg); 0603 } 0604 return $sprite; 0605 } 0606 0607 }