суббота, 3 августа 2013 г.

PHP: Auto-crop the image with GD

PHP: Auto-crop the image with GD




  1. <?php
  2. /*!*****************************************************************************************************
  3. *
  4. * @file autocrop.php
  5. * @author Jos Pape
  6. * @version 1.0
  7. * @brief Contains a class that auto crops images
  8. * @example new AutoCrop('scan.jpg'); outputs the image directly
  9. * @example new AutoCrop('scan.jpg', 'croped.jpg'); outputs the image to the file
  10. ******************************************************************************************************/
  11.  
  12. /*!**************************************************************************
  13. * @class AutoCrop
  14. * @author Jos Pape
  15. * @version 1.0
  16. * @brief Facilitates automaticly cropping a image
  17. **************************************************/
  18.  
  19. class AutoCrop
  20. {
  21. /*!******************************
  22. * @brief holds the original image
  23. */
  24. var $originalImage = false;
  25. /*!******************************
  26. * @brief holds the original image location
  27. */
  28. var $originalSource = false;
  29. /*!******************************
  30. * @brief holds the destination location
  31. */
  32. var $destinationSource = false;
  33. /*!******************************
  34. * @brief holds the destination image
  35. */
  36. var $destinationImage = false;
  37. /*!******************************
  38. * @brief holds the edges
  39. */
  40. var $edge = array();
  41. /*!******************************
  42. * @brief holds the default margin
  43. */
  44. var $margin = 30;
  45. /*!***********
  46. * @brief holds the default correction value
  47. */
  48. var $correction = 5;
  49. /**
  50. * @param $source (location to the image)
  51. * @param $destination (default false means inline display)
  52. * @return boolean
  53. */
  54. public function __construct($source, $destination=false)
  55. {
  56. if(is_file($source))
  57. {
  58. $this->originalSource = $source;
  59. if($destination)
  60. {
  61. $this->destinationSource = $destination;
  62. }
  63. return $this->cropImage();
  64. }
  65. else return false;
  66. }
  67. /**
  68. * @return boolean
  69. */
  70. private function cropImage()
  71. {
  72. // first we get the filetype
  73. $fileType = mime_content_type($this->originalSource);
  74. if(substr($fileType, 0, 5) == "image")
  75. {
  76. switch($fileType)
  77. {
  78. case "image/jpeg":
  79. $this->originalImage = imagecreatefromjpeg($this->originalSource);
  80. $this->destinationImage = imagecreatefromjpeg($this->originalSource);
  81. break;
  82. case "image/gif":
  83. $this->originalImage = imagecreatefromgif($this->originalSource);
  84. $this->destinationImage = imagecreatefromgif($this->originalSource);
  85. break;
  86. case "image/png":
  87. $this->originalImage = imagecreatefrompng($this->originalSource);
  88. $this->destinationImage = imagecreatefrompng($this->originalSource);
  89. break;
  90. default:
  91. return false;
  92. break;
  93. }
  94. if($this->originalImage)
  95. {
  96. $this->imagecolorswap($this->destinationImage);
  97. $this->edge = $this->imageGetEdges($this->destinationImage, 250, 250, 250);
  98. imagedestroy($this->destinationImage);
  99. $newWidth = $this->edge[0]-$this->edge[2];
  100. $newHeight = $this->edge[1]-$this->edge[3];
  101. $this->destinationImage = imagecreatetruecolor($newWidth, $newHeight);
  102. imagecopyresized(
  103. $this->destinationImage,
  104. $this->originalImage,
  105. 0,
  106. 0,
  107. $this->edge[2],
  108. $this->edge[3],
  109. $newWidth,
  110. $newHeight,
  111. $newWidth,
  112. $newHeight
  113. );
  114. return $this->outputImage();
  115. }
  116. else return false;
  117. }
  118. else return false;
  119. }
  120. /**
  121. * @return boolean
  122. */
  123. private function outputImage()
  124. {
  125. if(count($this->edge) == 4)
  126. {
  127. // output the image....as what?
  128. if($this->destinationSource)
  129. { // save to file
  130. // get the destination extention so we know how to save this image
  131. $fileType = strtolower(substr($this->destinationSource,strripos($this->destinationSource, ".")));
  132. switch($fileType)
  133. {
  134. case ".jpg":
  135. case ".jpeg":
  136. imagejpeg($this->destinationImage, $this->destinationSource);
  137. break;
  138. case ".png":
  139. imagepng($this->destinationImage, $this->destinationSource);
  140. break;
  141. case ".gif":
  142. imagegif($this->destinationImage, $this->destinationSource);
  143. break;
  144. }
  145. }
  146. else
  147. { // inline display
  148. $fileType = mime_content_type($this->originalSource);
  149. header('Content-type: '.$fileType);
  150. switch($fileType)
  151. {
  152. case "image/jpeg":
  153. imagejpeg($this->destinationImage);
  154. break;
  155. case "image/png":
  156. imagepng($this->destinationImage);
  157. break;
  158. case "image/gif":
  159. imagegif($this->destinationImage);
  160. break;
  161. }
  162. }
  163. return true;
  164. }
  165. else return false;
  166. }
  167. /**
  168. * @param $img (image resource)
  169. * @param $red (color red)
  170. * @param $green (color green)
  171. * @param $blue (color blue)
  172. * @return array(X1, Y1, X2, Y2) (right, bottom, left, top)
  173. * @brief X1,Y1 are the bottom right positions and X2,Y2 are the top left position
  174. */
  175. private function imageGetEdges(&$img, $red, $green, $blue)
  176. {
  177. // where the color starts thats te edge
  178. $margin = 30;
  179. $width = imagesx($img);
  180. $height = imagesy($img);
  181. $returnX = $this->margin;
  182. $returnY = $this->margin;
  183. $returnXmin = $width-($this->margin);
  184. $returnYmin = $height-($this->margin);
  185. $Xvalues = array();
  186. $Yvalues = array();
  187. $searchColor = imagecolorclosest($img, $red, $green, $blue);
  188. for($x = $margin; $x<($width-$this->margin); $x=$x+1)
  189. {
  190. for($y = $margin; $y<($height-$this->margin); $y=$y+1)
  191. {
  192. $color = imagecolorat($img, $x, $y);
  193. if($color != $searchColor)
  194. {
  195. $aprocX = floor($x/$this->correction)*$this->correction;
  196. $aprocY = floor($y/$this->correction)*$this->correction;
  197. if(isset($Xvalues[$aprocX]))
  198. $Xvalues[$aprocX] += 1;
  199. else
  200. $Xvalues[$aprocX] = 0;
  201. if(isset($Yvalues[$aprocY]))
  202. $Yvalues[$aprocY] += 1;
  203. else
  204. $Yvalues[$aprocY] = 0;
  205. }
  206. }
  207. }
  208. // average X and Y
  209. $returnX = $this->margin;
  210. $returnY = $this->margin;
  211. $returnXmin = $width-($this->margin);
  212. $returnYmin = $height-($this->margin);
  213. foreach($Xvalues AS $X => $aantal)
  214. {
  215. if($X > $returnX && $aantal > 8)
  216. {
  217. $returnX = $X;
  218. }
  219. if($X < $returnXmin && $aantal > 8)
  220. {
  221. $returnXmin = $X;
  222. }
  223. }
  224. foreach($Yvalues AS $Y => $aantal)
  225. {
  226. if($Y > $returnY && $aantal > 8)
  227. {
  228. $returnY = $Y;
  229. $maxAantalY = $aantal;
  230. }
  231. if($Y < $returnYmin && $aantal > 8)
  232. {
  233. $returnYmin = $Y;
  234. }
  235. }
  236. $testmargin = $this->margin + $this->correction;
  237. if($returnX >= $width-($testmargin))
  238. $returnX = $width;
  239. else
  240. $returnX += $this->correction;
  241. if($returnY >= $height-($testmargin))
  242. $returnY = $height;
  243. else
  244. $returnY += $this->correction;
  245. if($returnXmin <= $testmargin)
  246. $returnXmin = 0;
  247. else
  248. $returnXmin -= $this->correction;
  249. if($returnYmin <= $testmargin)
  250. $returnYmin = 0;
  251. else
  252. $returnYmin -= $this->correction;
  253. return array($returnX, $returnY, $returnXmin, $returnYmin);
  254. }
  255. private function imagecolorswap(&$img)
  256. {
  257. // First we remove the background
  258. imagefilter($img, IMG_FILTER_SMOOTH, 10);
  259. imagefilter($img, IMG_FILTER_EDGEDETECT);
  260. imagefilter($img, IMG_FILTER_CONTRAST, -90);
  261. imagefilter($img, IMG_FILTER_BRIGHTNESS, -20);
  262. //imagefilter($img, IMG_FILTER_BRIGHTNESS, -40);
  263. imagefilter($img, IMG_FILTER_CONTRAST, 20);
  264. // remove color: 120 120 120 TO 180 180 180
  265. if (!($t = imagecolorstotal($img)))
  266. {
  267. $t = 250;
  268. imagetruecolortopalette($img, 1, $t);
  269. }
  270. for ($c = 0; $c < $t; $c++)
  271. {
  272. $cc = imagecolorclosest($img, 150, 150, 150);
  273. imagecolorset($img, $cc, 250, 250, 250);
  274. }
  275. imagefilter($img, IMG_FILTER_COLORIZE, 0, 0, 0);
  276. }
  277. }
  278. ?>

Комментариев нет:

Отправить комментарий

Постоянные читатели

Популярные сообщения