gdimage.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. <?php
  2. /**
  3. * 水印类
  4. *
  5. * 可以生成文字水印和图片水印(图片文件类型:gif,jpg,png)
  6. *
  7. *
  8. *
  9. * @package
  10. */
  11. defined('InShopNC') or exit('Access Invalid!');
  12. class GdImage{
  13. /**
  14. * 输入图片的文件名(必须包含路径名)
  15. */
  16. private $src_image_name = "";
  17. /**
  18. * jpeg图片质量
  19. */
  20. private $jpeg_quality = 90;
  21. /**
  22. * 输出文件名
  23. */
  24. private $save_file = '';
  25. /**
  26. * 水印图片的文件名(必须包含路径名)
  27. */
  28. private $wm_image_name = "";
  29. /**
  30. * 水印图片放置的位置
  31. * 0 = middle
  32. * 1 = top left
  33. * 2 = top right
  34. * 3 = bottom right
  35. * 4 = bottom left
  36. * 5 = top middle
  37. * 6 = middle right
  38. * 7 = bottom middle
  39. * 8 = middle left
  40. */
  41. private $wm_image_pos = 1;
  42. /**
  43. * 水印图片与原图片的融合度 (1=100)
  44. */
  45. private $wm_image_transition = 20;
  46. /**
  47. * 水印文字(支持中英文以及带有\r\n的跨行文字)
  48. */
  49. private $wm_text = "";
  50. /**
  51. * 水印文字大小(单位:像素px)
  52. */
  53. private $wm_text_size = 20;
  54. /**
  55. * 水印文字角度,这个值尽量不要更改
  56. */
  57. private $wm_text_angle = 4;
  58. /**
  59. * 水印文字放置位置
  60. */
  61. private $wm_text_pos = 3;
  62. /**
  63. * 水印文字的字体
  64. */
  65. private $wm_text_font = "";
  66. /**
  67. * 水印字体的颜色值
  68. */
  69. private $wm_text_color = "#cccccc";
  70. /**
  71. * 取指定下标的数组内容
  72. *
  73. * @param string $key 数组下标
  74. * @return string 字符串形式的返回结果
  75. */
  76. public function get($key){
  77. $result = $this->$key ? $this->$key : '';
  78. return $result;
  79. }
  80. /**
  81. * 设置指定下标的数组内容
  82. *
  83. * @param string $key 数组下标
  84. * @param string $value 值
  85. * @return bool 字符串形式的返回结果
  86. */
  87. public function set($key,$value){
  88. $this->$key = $value;
  89. return true;
  90. }
  91. /**
  92. * 设置水印内容
  93. *
  94. */
  95. public function setWatermark($watermark){
  96. $this->set('jpeg_quality',$watermark['jpeg_quality']);
  97. if($watermark['wm_image_name'] != ''){
  98. $this->set('wm_image_name',BASE_UPLOAD_PATH.DS.ATTACH_WATERMARK.DS.$watermark['wm_image_name']);
  99. }
  100. $this->set('wm_image_pos',$watermark['wm_image_pos']);
  101. $this->set('wm_image_transition',$watermark['wm_image_transition']);
  102. $this->set('wm_text',$watermark['wm_text']);
  103. $this->set('wm_text_size',$watermark['wm_text_size']);
  104. $this->set('wm_text_angle',$watermark['wm_text_angle']);
  105. $this->set('wm_text_pos',$watermark['wm_text_pos']);
  106. $this->set('wm_text_font',BASE_DATA_PATH.DS.'resource'.DS.'font'.DS.$watermark['wm_text_font'].'.ttf');
  107. $this->set('jpeg_quality',$watermark['jpeg_quality']);
  108. $this->set('wm_text_color', $watermark['wm_text_color']);
  109. return true;
  110. }
  111. /**
  112. * 生成增加水印的图片
  113. *
  114. * <code>
  115. * //使用示例
  116. * <?php
  117. * $img = new GDImage();
  118. * //文字水印
  119. * $img->wm_text = "www.abc.com";
  120. * $img->wm_text_font = "./STXINWEI.TTF";
  121. * //图片水印
  122. * $img->wm_image_name="水印图片名";
  123. * $img->create("生成图片文件名(包括路径)");
  124. * ?>
  125. * </code>
  126. *
  127. * @param string $filename 需要增加水印的图片文件名
  128. * @return bool 布尔类型的返回结果
  129. */
  130. public function create($filename="")
  131. {
  132. @ini_set('memory_limit', '-1');
  133. if ($filename){
  134. $this->src_image_name = strtolower(trim($filename));
  135. $this->save_file = $this->src_image_name;
  136. }
  137. $src_image_type = $this->get_type($this->src_image_name);
  138. $src_image = $this->createImage($src_image_type,$this->src_image_name);
  139. if (!$src_image) {
  140. return false;
  141. }
  142. $src_image_w=ImageSX($src_image);
  143. $src_image_h=ImageSY($src_image);
  144. if ($this->wm_image_name){
  145. $this->wm_image_name = strtolower(trim($this->wm_image_name));
  146. $wm_image_type = $this->get_type($this->wm_image_name);
  147. $wm_image = $this->createImage($wm_image_type,$this->wm_image_name);
  148. $wm_image_w=ImageSX($wm_image);
  149. $wm_image_h=ImageSY($wm_image);
  150. $temp_wm_image = $this->getPos($src_image_w,$src_image_h,$this->wm_image_pos,$wm_image);
  151. $wm_image_x = $temp_wm_image["dest_x"];
  152. $wm_image_y = $temp_wm_image["dest_y"];
  153. imageCopyMerge($src_image, $wm_image,$wm_image_x,$wm_image_y,0,0,$wm_image_w,$wm_image_h,$this->wm_image_transition);
  154. }
  155. if ($this->wm_text){
  156. $temp_wm_text = $this->getPos($src_image_w,$src_image_h,$this->wm_text_pos);
  157. $wm_text_x = $temp_wm_text["dest_x"];
  158. $wm_text_y = $temp_wm_text["dest_y"];
  159. if(preg_match("/([a-f0-9][a-f0-9])([a-f0-9][a-f0-9])([a-f0-9][a-f0-9])/i", $this->wm_text_color, $color)) {
  160. $red = hexdec($color[1]);
  161. $green = hexdec($color[2]);
  162. $blue = hexdec($color[3]);
  163. $wm_text_color = imagecolorallocate($src_image, $red,$green,$blue);
  164. }else{
  165. $wm_text_color = imagecolorallocate($src_image, 255,255,255);
  166. }
  167. imagettftext($src_image, $this->wm_text_size, $this->wm_angle, $wm_text_x, $wm_text_y, $wm_text_color,$this->wm_text_font, $this->wm_text);
  168. }
  169. if ($this->save_file)
  170. {
  171. switch ($this->get_type($this->save_file)){
  172. case 'gif':$src_img=imagegif($src_image, $this->save_file); break;
  173. case 'jpeg':$src_img=ImageJPEG($src_image, $this->save_file, $this->jpeg_quality); break;
  174. case 'jpg':$src_img=ImageJPEG($src_image, $this->save_file, $this->jpeg_quality); break;
  175. case 'png':$src_img=ImagePNG($src_image, $this->save_file); break;
  176. default:$src_img=ImageJPEG($src_image, $this->save_file, $this->jpeg_quality); break;
  177. }
  178. }
  179. else
  180. {
  181. if ($src_image_type == "jpg") $src_image_type="jpeg";
  182. @header("Content-type: image/{$src_image_type}");
  183. switch ($src_image_type){
  184. case 'gif':$src_img=imagegif($src_image); break;
  185. case 'jpg':$src_img=ImageJPEG($src_image, "", $this->jpeg_quality);break;
  186. case 'jpeg':$src_img=ImageJPEG($src_image, "", $this->jpeg_quality);break;
  187. case 'png':$src_img=ImagePNG($src_image);break;
  188. default:$src_img=ImageJPEG($src_image, "", $this->jpeg_quality);break;
  189. }
  190. }
  191. imagedestroy($src_image);
  192. return true;
  193. }
  194. /**
  195. * 根据文件名和类型创建图片
  196. *
  197. * @param string $type 图片的类型,包括gif,jpg,png
  198. * @param string $img_name 图片文件名,包括路径名,例如 " ./mouse.jpg"
  199. * @return string 字符串类型的返回结果
  200. */
  201. private function createImage($type, $img_name){
  202. if (!$type){
  203. $type = $this->get_type($img_name);
  204. }
  205. switch ($type){
  206. case 'gif':
  207. if (function_exists('imagecreatefromgif'))
  208. $tmp_img=@ImageCreateFromGIF($img_name);
  209. break;
  210. case 'jpg':
  211. $tmp_img=ImageCreateFromJPEG($img_name);
  212. break;
  213. case 'jpeg':
  214. $tmp_img=ImageCreateFromJPEG($img_name);
  215. break;
  216. case 'png':
  217. $tmp_img=ImageCreateFromPNG($img_name);
  218. break;
  219. default:
  220. $tmp_img=ImageCreateFromString($img_name);
  221. break;
  222. }
  223. return $tmp_img;
  224. }
  225. /**
  226. * 根据源图像的长、宽,位置代码,水印图片id来生成把水印放置到源图像中的位置
  227. *
  228. * @param int $sourcefile_width 源图像的宽
  229. * @param int $sourcefile_height 源图像的高
  230. * @param int $pos 位置代码
  231. * @param string $wm_image 水印图片 如果为空 则默认为文字水印
  232. * @return array 数组形式的返回结果
  233. */
  234. private function getPos($sourcefile_width, $sourcefile_height, $pos, $wm_image=''){
  235. if ($wm_image){
  236. $insertfile_width = ImageSx($wm_image);
  237. $insertfile_height = ImageSy($wm_image);
  238. }else {
  239. $lineCount = explode("\r\n",$this->wm_text);
  240. $fontSize = imagettfbbox($this->wm_text_size,$this->wm_text_angle,$this->wm_text_font,$this->wm_text);
  241. $insertfile_width = $fontSize[2] - $fontSize[0];
  242. $insertfile_height = count($lineCount)*($fontSize[1] - $fontSize[3]);
  243. }
  244. switch ($pos){
  245. case 0:
  246. $dest_x = ( $sourcefile_width / 2 ) - ( $insertfile_width / 2 );
  247. $dest_y = ( $sourcefile_height / 2 ) - ( $insertfile_height / 2 );
  248. break;
  249. case 1:
  250. $dest_x = 0;
  251. if ($this->wm_text){
  252. $dest_y = $insertfile_height;
  253. }else{
  254. $dest_y = 0;
  255. }
  256. break;
  257. case 2:
  258. $dest_x = $sourcefile_width - $insertfile_width;
  259. if ($this->wm_text){
  260. $dest_y = $insertfile_height;
  261. }else{
  262. $dest_y = 0;
  263. }
  264. break;
  265. case 3:
  266. $dest_x = $sourcefile_width - $insertfile_width;
  267. if ($this->wm_text){
  268. $dest_y = $insertfile_height;
  269. }else{
  270. $dest_y = 0;
  271. }
  272. break;
  273. case 4:
  274. $dest_x = 0;
  275. $dest_y = ( $sourcefile_height / 2 ) - ( $insertfile_height / 2 );
  276. break;
  277. case 5:
  278. $dest_x = ( ( $sourcefile_width - $insertfile_width ) / 2 );
  279. $dest_y = ( $sourcefile_height / 2 ) - ( $insertfile_height / 2 );
  280. break;
  281. case 6:
  282. $dest_x = $sourcefile_width - $insertfile_width;
  283. $dest_y = ( $sourcefile_height / 2 ) - ( $insertfile_height / 2 );
  284. break;
  285. case 7:
  286. $dest_x = 0;
  287. $dest_y = $sourcefile_height - $insertfile_height;
  288. break;
  289. case 8:
  290. $dest_x = ( ( $sourcefile_width - $insertfile_width ) / 2 );
  291. $dest_y = $sourcefile_height - $insertfile_height;
  292. break;
  293. default:
  294. $dest_x = $sourcefile_width - $insertfile_width;
  295. $dest_y = $sourcefile_height - $insertfile_height;
  296. break;
  297. }
  298. return array("dest_x"=>$dest_x,"dest_y"=>$dest_y);
  299. }
  300. /**
  301. * 指定的文字转换为UTF-8格式,包括中英文混合
  302. *
  303. * @param string $gb gbk字符串
  304. * @return string 字符串形式的返回结果
  305. */
  306. private function gb2utf8($gb)
  307. {
  308. if(!trim($gb))
  309. return $gb;
  310. $filename="./gb2312.txt";
  311. $tmp=file($filename);
  312. $codetable=array();
  313. while(list($key,$value)=each($tmp))
  314. $codetable[hexdec(substr($value,0,6))]=substr($value,7,6);
  315. $utf8="";
  316. while($gb)
  317. {
  318. if (ord(substr($gb,0,1))>127)
  319. {
  320. $tthis=substr($gb,0,2);
  321. $gb=substr($gb,2,strlen($gb)-2);
  322. $utf8.=$this->u2utf8(hexdec($codetable[hexdec(bin2hex($tthis))-0x8080]));
  323. }
  324. else
  325. {
  326. $tthis=substr($gb,0,1);
  327. $gb=substr($gb,1,strlen($gb)-1);
  328. $utf8.=$this->u2utf8($tthis);
  329. }
  330. }
  331. return $utf8;
  332. }
  333. function u2utf8($c)
  334. {
  335. $str="";
  336. if ($c < 0x80)
  337. {
  338. $str.=$c;
  339. }
  340. else if ($c < 0x800)
  341. {
  342. $str.=chr(0xC0 | $c>>6);
  343. $str.=chr(0x80 | $c & 0x3F);
  344. }
  345. else if ($c < 0x10000)
  346. {
  347. $str.=chr(0xE0 | $c>>12);
  348. $str.=chr(0x80 | $c>>6 & 0x3F);
  349. $str.=chr(0x80 | $c & 0x3F);
  350. }
  351. else if ($c < 0x200000)
  352. {
  353. $str.=chr(0xF0 | $c>>18);
  354. $str.=chr(0x80 | $c>>12 & 0x3F);
  355. $str.=chr(0x80 | $c>>6 & 0x3F);
  356. $str.=chr(0x80 | $c & 0x3F);
  357. }
  358. return $str;
  359. }
  360. /**
  361. * 获得图片的格式,包括jpg,png,gif
  362. *
  363. * @param string $img_name 图片文件名,包括路径名
  364. * @return string 字符串形式的返回结果
  365. */
  366. private function get_type($img_name)
  367. {
  368. $name_array = explode(".",$img_name);
  369. if (preg_match("/\.(jpg|jpeg|gif|png)$/", $img_name, $matches))
  370. {
  371. $type = strtolower($matches[1]);
  372. }
  373. else
  374. {
  375. $type = "string";
  376. }
  377. return $type;
  378. }
  379. }