Basic PHP document management system, including automatic detection of corporate logos in letters
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

logodetect.php 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. <?PHP
  2. set_time_limit(120);
  3. if (!defined('logodetect')) {
  4. function isClear(&$im, $x, $y) {
  5. $rgb = imagecolorat($im, $x, $y);
  6. $r = ($rgb >> 16) & 0xFF;
  7. $g = ($rgb >> 8) & 0xFF;
  8. $b = $rgb & 0xFF;
  9. return $r + $g + $b > 600;
  10. }
  11. function getLineScore(&$im, $y, $xmin, $xmax) {
  12. $count = 0;
  13. for ($x = $xmin; $x < $xmax; $x++) {
  14. if (isClear($im, $x, $y)) {
  15. $count++;
  16. }
  17. }
  18. return $count / ($xmax - $xmin);
  19. }
  20. function getColScore(&$im, $ymin, $ymax, $x) {
  21. $count = 0;
  22. for ($y = $ymin; $y < $ymax; $y++) {
  23. if (isClear($im, $x, $y)) {
  24. $count++;
  25. }
  26. }
  27. return $count / ($ymax - $ymin);
  28. }
  29. }
  30. if (file_exists('.logos/' . md5($_SERVER['QUERY_STRING']))) {
  31. header('Content-type: image/jpeg');
  32. readfile('.logos/' . md5($_SERVER['QUERY_STRING']));
  33. exit;
  34. }
  35. $im = imagecreatefromjpeg($_SERVER['QUERY_STRING']);
  36. if (!defined('logodetect')) {
  37. // Number of blank lines required in a row
  38. define('BLANK_THRESHOLD', 15);
  39. function doBlankCols(&$im, $ymin, $ymax, $xmin, $xmax, $colour = false) {
  40. // Check for blank columns
  41. if ($xmin == $xmax || $ymin == $ymax) { return array(); }
  42. $lastx = $laststreak = -100; $count = 0; $res = array();
  43. for ($x = $xmin; $x <= $xmax; $x++) {
  44. $score = getColScore($im, $ymin, $ymax, $x);
  45. if ($score > 0.99) {
  46. if (++$lastx == $x) {
  47. $count++;
  48. if ($count == BLANK_THRESHOLD) {
  49. if ($colour) { imagefilledrectangle($im, $x - $count, $ymin, $x, $ymax, imagecolorallocatealpha($im, 0, 0, 0, 50)); }
  50. $res = array_merge($res, doBlankLines($im, $ymin, $ymax, max($xmin, $laststreak + 1), $x - $count - 1, $colour));
  51. $laststreak = $x;
  52. } else if ($count > BLANK_THRESHOLD) {
  53. if ($colour) { imageline($im, $x, $ymin, $x, $ymax, imagecolorallocatealpha($im, 0, 0, 0, 50)); }
  54. $laststreak = $x;
  55. }
  56. } else {
  57. $lastx = $x;
  58. $count = 1;
  59. }
  60. }
  61. }
  62. if (count($res) > 0 && $laststreak + 1 < $xmax) {
  63. $res = array_merge($res, doBlankLines($im, $ymin, $ymax, max($xmin, $laststreak + 1), $xmax));
  64. }
  65. if (count($res) == 0) {
  66. $res[] = array($ymin, $ymax, $xmin, $xmax);
  67. }
  68. return $res;
  69. }
  70. function doBlankLines(&$im, $ymin, $ymax, $xmin, $xmax, $colour = false) {
  71. // Check for blank lines
  72. if ($xmin == $xmax || $ymin == $ymax) { return array(); }
  73. $lasty = $laststreak = -100; $count = 0; $res = array();
  74. for ($y = $ymin; $y <= $ymax; $y++) {
  75. $score = getLineScore($im, $y, $xmin, $xmax);
  76. if ($xmin > 0) {
  77. //imageline($im, $xmin, $y, $xmax, $y, imagecolorallocatealpha($im, 0, 0xFF * $score, 0, 50));
  78. }
  79. if ($score > 0.99) {
  80. if (++$lasty == $y) {
  81. $count++;
  82. if ($count == BLANK_THRESHOLD) {
  83. if ($colour) {
  84. imagefilledrectangle($im, $xmin, $y - $count, $xmax, $y, imagecolorallocatealpha($im, 0, 0xFF, 0, 50));
  85. }
  86. $res = array_merge($res, doBlankCols($im, max($ymin, 1 + $laststreak), $y - $count, $xmin, $xmax, $colour));
  87. $laststreak = $y;
  88. } else if ($count > BLANK_THRESHOLD) {
  89. if ($colour) { imageline($im, $xmin, $y, $xmax, $y, imagecolorallocatealpha($im, 0, 0xFF, 0, 50)); }
  90. $laststreak = $y;
  91. }
  92. } else {
  93. $count = 1;
  94. $lasty = $y;
  95. }
  96. }
  97. }
  98. if (count($res) > 0 && $laststreak + 1 < $ymax) {
  99. $res = array_merge($res, doBlankCols($im, max($ymin, 1 + $laststreak), $ymax, $xmin, $xmax));
  100. }
  101. if (count($res) == 0) {
  102. $res[] = array($ymin, $ymax, $xmin, $xmax);
  103. }
  104. return $res;
  105. }
  106. function logoFilter1($logo) {
  107. global $im;
  108. $height = $logo[1] - $logo[0];
  109. $width = $logo[3] - $logo[2];
  110. if ($width < 3 * BLANK_THRESHOLD || $height < 3 * BLANK_THRESHOLD) { return false; }
  111. if ($width > 0.4 * imagesx($im)) { return false; }
  112. return true;
  113. }
  114. function logoFilter2($logo) {
  115. global $im, $logos;
  116. $left = $logo[2] < 0.5 * imagesx($im);
  117. foreach ($logos as $other) {
  118. if (($left && $other[2] < $logo[2] - 20) || (!$left && $other[3] > $logo[3] + 20)) {
  119. return false;
  120. }
  121. }
  122. return true;
  123. }
  124. function logoFilter3($logo) {
  125. global $logos;
  126. foreach ($logos as $other) {
  127. if ($other[0] < $logo[0]) { return false; }
  128. }
  129. return true;
  130. }
  131. }
  132. $logos = doBlankLines($im, 0, imagesy($im) / 3, 0, imagesx($im), false);
  133. $logos = array_filter($logos, 'logoFilter1');
  134. $logos = array_filter($logos, 'logoFilter2');
  135. $logos = array_filter($logos, 'logoFilter3');
  136. $logo = array_pop($logos);
  137. $im2 = imagecreatetruecolor($logo[3] - $logo[2], $logo[1] - $logo[0]);
  138. imagecopy($im2, $im, 0, 0, $logo[2], $logo[0], $logo[3] - $logo[2], $logo[1] - $logo[0]);
  139. imagejpeg($im2, '.logos/' . md5($_SERVER['QUERY_STRING']));
  140. if (!defined('nooutput')) {
  141. header('Content-type: image/jpeg');
  142. imagejpeg($im2);
  143. }
  144. define('logodetect', true);
  145. ?>