Vizhash16x16.php 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. <?php
  2. /**
  3. * VizHash_GD
  4. *
  5. * Visual Hash implementation in php4+GD,
  6. * stripped down and modified version for PrivateBin
  7. *
  8. * @link http://sebsauvage.net/wiki/doku.php?id=php:vizhash_gd
  9. * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
  10. * @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
  11. * @version 0.0.4 beta PrivateBin 0.22
  12. */
  13. namespace PrivateBin;
  14. use PrivateBin\Persistence\ServerSalt;
  15. /**
  16. * Vizhash16x16
  17. *
  18. * Example:
  19. * $vz = new Vizhash16x16();
  20. * $data = $vz->generate('hello');
  21. * header('Content-type: image/png');
  22. * echo $data;
  23. * exit;
  24. */
  25. class Vizhash16x16
  26. {
  27. /**
  28. * hash values
  29. *
  30. * @access private
  31. * @var array
  32. */
  33. private $VALUES;
  34. /**
  35. * index of current value
  36. *
  37. * @access private
  38. * @var int
  39. */
  40. private $VALUES_INDEX;
  41. /**
  42. * image width
  43. *
  44. * @access private
  45. * @var int
  46. */
  47. private $width;
  48. /**
  49. * image height
  50. *
  51. * @access private
  52. * @var int
  53. */
  54. private $height;
  55. /**
  56. * salt used when generating the image
  57. *
  58. * @access private
  59. * @var string
  60. */
  61. private $salt;
  62. /**
  63. * constructor
  64. *
  65. * @access public
  66. * @return void
  67. */
  68. public function __construct()
  69. {
  70. $this->width = 16;
  71. $this->height = 16;
  72. $this->salt = ServerSalt::get();
  73. }
  74. /**
  75. * Generate a 16x16 png corresponding to $text.
  76. *
  77. * @access public
  78. * @param string $text
  79. * @return string PNG data. Or empty string if GD is not available.
  80. */
  81. public function generate($text)
  82. {
  83. if (!function_exists('gd_info')) {
  84. return '';
  85. }
  86. // We hash the input string.
  87. $hash=hash('sha1', $text.$this->salt).hash('md5', $text.$this->salt);
  88. $hash=$hash.strrev($hash); # more data to make graphics
  89. $hashlen=strlen($hash);
  90. // We convert the hash into an array of integers.
  91. $this->VALUES=array();
  92. for ($i=0; $i<$hashlen; $i=$i+2) {
  93. array_push($this->VALUES, hexdec(substr($hash, $i, 2)));
  94. }
  95. $this->VALUES_INDEX=0; // to walk the array.
  96. // Then use these integers to drive the creation of an image.
  97. $image = imagecreatetruecolor($this->width, $this->height);
  98. $r0 = $this->getInt();
  99. $r=$r0;
  100. $g0 = $this->getInt();
  101. $g=$g0;
  102. $b0 = $this->getInt();
  103. $b=$b0;
  104. // First, create an image with a specific gradient background.
  105. $op='v';
  106. if (($this->getInt()%2)==0) {
  107. $op='h';
  108. };
  109. $image = $this->degrade($image, $op, array($r0, $g0, $b0), array(0, 0, 0));
  110. for ($i=0; $i<7; $i=$i+1) {
  111. $action=$this->getInt();
  112. $color = imagecolorallocate($image, $r, $g, $b);
  113. $r = ($r0 + $this->getInt()/25)%256;
  114. $g = ($g0 + $this->getInt()/25)%256;
  115. $b = ($b0 + $this->getInt()/25)%256;
  116. $r0=$r;
  117. $g0=$g;
  118. $b0=$b;
  119. $this->drawshape($image, $action, $color);
  120. }
  121. $color = imagecolorallocate($image, $this->getInt(), $this->getInt(), $this->getInt());
  122. $this->drawshape($image, $this->getInt(), $color);
  123. ob_start();
  124. imagepng($image);
  125. $imagedata = ob_get_contents();
  126. ob_end_clean();
  127. imagedestroy($image);
  128. return $imagedata;
  129. }
  130. /**
  131. * Returns a single integer from the $VALUES array (0...255)
  132. *
  133. * @access private
  134. * @return int
  135. */
  136. private function getInt()
  137. {
  138. $v= $this->VALUES[$this->VALUES_INDEX];
  139. $this->VALUES_INDEX++;
  140. $this->VALUES_INDEX %= count($this->VALUES); // Warp around the array
  141. return $v;
  142. }
  143. /**
  144. * Returns a single integer from the array (roughly mapped to image width)
  145. *
  146. * @access private
  147. * @return int
  148. */
  149. private function getX()
  150. {
  151. return $this->width*$this->getInt()/256;
  152. }
  153. /**
  154. * Returns a single integer from the array (roughly mapped to image height)
  155. *
  156. * @access private
  157. * @return int
  158. */
  159. private function getY()
  160. {
  161. return $this->height*$this->getInt()/256;
  162. }
  163. /**
  164. * Gradient function
  165. *
  166. * taken from:
  167. * http://www.supportduweb.com/scripts_tutoriaux-code-source-41-gd-faire-un-degrade-en-php-gd-fonction-degrade-imagerie.html
  168. *
  169. * @access private
  170. * @param resource $img
  171. * @param string $direction
  172. * @param array $color1
  173. * @param array $color2
  174. * @return resource
  175. */
  176. private function degrade($img, $direction, $color1, $color2)
  177. {
  178. if ($direction=='h') {
  179. $size = imagesx($img);
  180. $sizeinv = imagesy($img);
  181. } else {
  182. $size = imagesy($img);
  183. $sizeinv = imagesx($img);
  184. }
  185. $diffs = array(
  186. (($color2[0]-$color1[0])/$size),
  187. (($color2[1]-$color1[1])/$size),
  188. (($color2[2]-$color1[2])/$size)
  189. );
  190. for ($i=0;$i<$size;$i++) {
  191. $r = $color1[0]+($diffs[0]*$i);
  192. $g = $color1[1]+($diffs[1]*$i);
  193. $b = $color1[2]+($diffs[2]*$i);
  194. if ($direction=='h') {
  195. imageline($img, $i, 0, $i, $sizeinv, imagecolorallocate($img, $r, $g, $b));
  196. } else {
  197. imageline($img, 0, $i, $sizeinv, $i, imagecolorallocate($img, $r, $g, $b));
  198. }
  199. }
  200. return $img;
  201. }
  202. /**
  203. * Draw a shape
  204. *
  205. * @access private
  206. * @param resource $image
  207. * @param int $action
  208. * @param int $color
  209. * @return void
  210. */
  211. private function drawshape($image, $action, $color)
  212. {
  213. switch ($action%7) {
  214. case 0:
  215. ImageFilledRectangle($image, $this->getX(), $this->getY(), $this->getX(), $this->getY(), $color);
  216. break;
  217. case 1:
  218. case 2:
  219. ImageFilledEllipse($image, $this->getX(), $this->getY(), $this->getX(), $this->getY(), $color);
  220. break;
  221. case 3:
  222. $points = array($this->getX(), $this->getY(), $this->getX(), $this->getY(), $this->getX(), $this->getY(),$this->getX(), $this->getY());
  223. ImageFilledPolygon($image, $points, 4, $color);
  224. break;
  225. default:
  226. $start=$this->getInt()*360/256; $end=$start+$this->getInt()*180/256;
  227. ImageFilledArc($image, $this->getX(), $this->getY(), $this->getX(), $this->getY(), $start, $end, $color, IMG_ARC_PIE);
  228. }
  229. }
  230. }