util.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. <?php
  2. namespace common\components;
  3. use Yii;
  4. use yii\helpers\Json;
  5. class util
  6. {
  7. //判断是否微信浏览器
  8. public static function isWx()
  9. {
  10. if (isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger') == true) {
  11. return true;
  12. }
  13. return false;
  14. }
  15. //根据两点间的经纬度计算距离
  16. public static function getDistance($lat1, $lng1, $lat2, $lng2)
  17. {
  18. $earthRadius = 6367000; //approximate radius of earth in meters
  19. /*
  20. Convert these degrees to radians
  21. to work with the formula
  22. */
  23. $lat1 = ($lat1 * pi()) / 180;
  24. $lng1 = ($lng1 * pi()) / 180;
  25. $lat2 = ($lat2 * pi()) / 180;
  26. $lng2 = ($lng2 * pi()) / 180;
  27. /*
  28. Using the
  29. Haversine formula
  30. http://en.wikipedia.org/wiki/Haversine_formula
  31. calculate the distance
  32. */
  33. $calcLongitude = $lng2 - $lng1;
  34. $calcLatitude = $lat2 - $lat1;
  35. $stepOne = pow(sin($calcLatitude / 2), 2) + cos($lat1) * cos($lat2) * pow(sin($calcLongitude / 2), 2);
  36. $stepTwo = 2 * asin(min(1, sqrt($stepOne)));
  37. $calculatedDistance = $earthRadius * $stepTwo;
  38. return round($calculatedDistance);
  39. }
  40. /**
  41. * 生成缩略图
  42. * @author yangzhiguo0903@163.com
  43. * @param string 源图绝对完整地址{带文件名及后缀名}
  44. * @param string 目标图绝对完整地址{带文件名及后缀名}
  45. * @param int 缩略图宽{0:此时目标高度不能为0,目标宽度为源图宽*(目标高度/源图高)}
  46. * @param int 缩略图高{0:此时目标宽度不能为0,目标高度为源图高*(目标宽度/源图宽)}
  47. * @param int 是否裁切{宽,高必须非0}
  48. * @param int /float 缩放{0:不缩放, 0<this<1:缩放到相应比例(此时宽高限制和裁切均失效)}
  49. * @return boolean
  50. */
  51. public static function img2thumb($src_img, $dst_img, $width = 75, $height = 75, $cut = 0, $proportion = 0)
  52. {
  53. if (!is_file($src_img)) {
  54. return false;
  55. }
  56. $ot = pathinfo($dst_img, PATHINFO_EXTENSION);
  57. $otfunc = 'image' . ($ot == 'jpg' ? 'jpeg' : $ot);
  58. $srcinfo = getimagesize($src_img);
  59. $src_w = $srcinfo[0];
  60. $src_h = $srcinfo[1];
  61. $type = strtolower(substr(image_type_to_extension($srcinfo[2]), 1));
  62. $createfun = 'imagecreatefrom' . ($type == 'jpg' ? 'jpeg' : $type);
  63. $dst_h = $height;
  64. $dst_w = $width;
  65. $x = $y = 0;
  66. /**
  67. * 缩略图不超过源图尺寸(前提是宽或高只有一个)
  68. */
  69. if (($width > $src_w && $height > $src_h) || ($height > $src_h && $width == 0) || ($width > $src_w && $height == 0)) {
  70. $proportion = 1;
  71. }
  72. if ($width > $src_w) {
  73. $dst_w = $width = $src_w;
  74. }
  75. if ($height > $src_h) {
  76. $dst_h = $height = $src_h;
  77. }
  78. if (!$width && !$height && !$proportion) {
  79. return false;
  80. }
  81. if (!$proportion) {
  82. if ($cut == 0) {
  83. if ($dst_w && $dst_h) {
  84. if ($dst_w / $src_w > $dst_h / $src_h) {
  85. $dst_w = $src_w * ($dst_h / $src_h);
  86. $x = 0 - ($dst_w - $width) / 2;
  87. } else {
  88. $dst_h = $src_h * ($dst_w / $src_w);
  89. $y = 0 - ($dst_h - $height) / 2;
  90. }
  91. } else if ($dst_w xor $dst_h) {
  92. if ($dst_w && !$dst_h) //有宽无高
  93. {
  94. $propor = $dst_w / $src_w;
  95. $height = $dst_h = $src_h * $propor;
  96. } else if (!$dst_w && $dst_h) //有高无宽
  97. {
  98. $propor = $dst_h / $src_h;
  99. $width = $dst_w = $src_w * $propor;
  100. }
  101. }
  102. } else {
  103. if (!$dst_h) //裁剪时无高
  104. {
  105. $height = $dst_h = $dst_w;
  106. }
  107. if (!$dst_w) //裁剪时无宽
  108. {
  109. $width = $dst_w = $dst_h;
  110. }
  111. $propor = min(max($dst_w / $src_w, $dst_h / $src_h), 1);
  112. $dst_w = (int)round($src_w * $propor);
  113. $dst_h = (int)round($src_h * $propor);
  114. $x = ($width - $dst_w) / 2;
  115. $y = ($height - $dst_h) / 2;
  116. }
  117. } else {
  118. $proportion = min($proportion, 1);
  119. $height = $dst_h = $src_h * $proportion;
  120. $width = $dst_w = $src_w * $proportion;
  121. }
  122. $src = $createfun($src_img);
  123. $dst = imagecreatetruecolor($width ? $width : $dst_w, $height ? $height : $dst_h);
  124. $white = imagecolorallocate($dst, 255, 255, 255);
  125. imagefill($dst, 0, 0, $white);
  126. if (function_exists('imagecopyresampled')) {
  127. imagecopyresampled($dst, $src, $x, $y, 0, 0, $dst_w, $dst_h, $src_w, $src_h);
  128. } else {
  129. imagecopyresized($dst, $src, $x, $y, 0, 0, $dst_w, $dst_h, $src_w, $src_h);
  130. }
  131. $otfunc($dst, $dst_img);
  132. imagedestroy($dst);
  133. imagedestroy($src);
  134. //return true;
  135. return ['width' => $src_w, 'height' => $src_h];//modify sofashi
  136. }
  137. /**
  138. * 输出字符并结束运行
  139. */
  140. public static function stop($string = '')
  141. {
  142. echo $string;
  143. Yii::$app->end();
  144. }
  145. public static function end()
  146. {
  147. Yii::$app->end();
  148. }
  149. //输出json数据并结束运行
  150. public static function encode($data)
  151. {
  152. echo Json::encode($data);
  153. exit();
  154. }
  155. /**
  156. * 合并图片 ---lqh 2017-05-05
  157. * @param $background_img 背景原图
  158. * @param $inline_img 内嵌原图
  159. * @return mixed 合并图的路径名称
  160. */
  161. public static function mergeImg($background_img, $inline_img, $type = 'wx')
  162. {
  163. $app = Yii::getAlias("@app");
  164. $saveDir = $app . '/../images/qrcode/';
  165. $rand = stringUtil::buildOrderNo();
  166. $random = empty($unique) ? $rand : $unique . '_' . $rand;
  167. //背景框图
  168. $path_1 = $background_img;
  169. //二维码图片
  170. $path_2 = $inline_img;
  171. //将框和二维码图片分别取到两个画布中。 针对png格式
  172. $image_1 = imagecreatefrompng($path_1);
  173. $image_2 = imagecreatefrompng($path_2);
  174. //创建一个和框图片一样大小的真彩色画布(ps:只有这样才能保证后面copy二维码图片的时候不会失真)
  175. $image_3 = imageCreatetruecolor(imagesx($image_1), imagesy($image_1));
  176. //为真彩色画布创建白色背景,再设置为透明
  177. $color = imagecolorallocate($image_3, 255, 255, 255);
  178. imagefill($image_3, 0, 0, $color);
  179. imageColorTransparent($image_3, $color);
  180. //首先将框画布采样copy到真彩色画布中,不会失真
  181. imagecopyresampled($image_3, $image_1, 0, 0, 0, 0, imagesx($image_1), imagesy($image_1), imagesx($image_1), imagesy($image_1));
  182. //再将二维码图片copy到已经具有框图像的真彩色画布中,同样也不会失真
  183. //根据微信或则支付宝合并位置有所不同
  184. if ($type == 'wx') {
  185. imagecopymerge($image_3, $image_2, 220, 320, 0, 0, imagesx($image_2), imagesy($image_2), 100);
  186. } else {
  187. //支付宝
  188. imagecopymerge($image_3, $image_2, 450, 820, 0, 0, imagesx($image_2), imagesy($image_2), 100);
  189. }
  190. //将画布保存到指定的png文件
  191. imagepng($image_3, $saveDir . $random . '_merge.png');
  192. return '/qrcode/' . $random . '_merge.png';//组合图片
  193. }
  194. public static function mergeQrimg($backgroundImg, array $qrImg)
  195. {
  196. $app = Yii::getAlias("@app");
  197. $saveDir = $app . '/../images/qrcode/';
  198. $random = stringUtil::buildOrderNo();
  199. $dest = imagecreatefromjpeg($backgroundImg);
  200. // Get new sizes
  201. list($width, $height) = getimagesize($qrImg['wifi']);
  202. list($newwidth, $newheight) = getimagesize($qrImg['zhifubao']);
  203. $newwidth = $newwidth + 35;//下载的wifi二维码size太小,放大些
  204. $newheight = $newheight + 35;
  205. // Load
  206. $thumb = imagecreatetruecolor($newwidth, $newheight);
  207. $source = imagecreatefromjpeg($qrImg['wifi']);
  208. // Resize
  209. imagecopyresized($thumb, $source, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
  210. imagejpeg($thumb, $saveDir . "temp.jpeg");//Output image to file
  211. //微信(支付宝)二维码、WiFi二维码
  212. $zfbQrImg = imagecreatefrompng($qrImg['zhifubao']);
  213. $WXQrImg = imagecreatefrompng($qrImg['weixin']);
  214. $wifiQrImg = imagecreatefromjpeg($saveDir . "temp.jpeg");
  215. imagealphablending($dest, false);
  216. imagesavealpha($dest, true);
  217. imagecopymerge($dest, $zfbQrImg, 240, 538, 0, 0, imagesx($zfbQrImg), imagesy($zfbQrImg), 100);
  218. imagecopymerge($dest, $WXQrImg, 985, 538, 0, 0, imagesx($WXQrImg), imagesy($WXQrImg), 100);
  219. imagecopymerge($dest, $wifiQrImg, 1708, 520, 0, 0, imagesx($wifiQrImg), imagesy($wifiQrImg), 100);
  220. imagepng($dest, $saveDir . $random . '_fullQrImg.png');
  221. imagedestroy($dest);
  222. imagedestroy($zfbQrImg);
  223. imagedestroy($WXQrImg);
  224. imagedestroy($wifiQrImg);
  225. return '/qrcode/' . $random . '_fullQrImg.png';//组合图片
  226. }
  227. //获取服务器IP
  228. public static function serverIp()
  229. {
  230. if (isset($_SERVER)) {
  231. if ($_SERVER['SERVER_ADDR']) {
  232. $server_ip = $_SERVER['SERVER_ADDR'];
  233. } else {
  234. $server_ip = $_SERVER['LOCAL_ADDR'];
  235. }
  236. } else {
  237. $server_ip = getenv('SERVER_ADDR');
  238. }
  239. return $server_ip;
  240. }
  241. //获取根目录 shish 2020.3.11
  242. public static function getRootDir()
  243. {
  244. $basePath = Yii::$app->basePath;
  245. if (Yii::$app->id == 'app-console') {
  246. $root = $basePath . "/../";
  247. } else {
  248. $root = $basePath . "/../../";
  249. }
  250. return $root;
  251. }
  252. //错误输出
  253. public static function fail($msg = '操作失败')
  254. {
  255. Yii::info($msg);
  256. self::encode(['code' => 0, 'msg' => $msg, 'data' => []]);
  257. }
  258. //成功输出内容
  259. public static function success($data, $msg = '操作成功')
  260. {
  261. self::encode(['code' => 1, 'msg' => $msg, 'data' => $data]);
  262. }
  263. //退出当前登陆 shish 2020.3.8
  264. public static function logout()
  265. {
  266. self::encode(['code' => 2, 'msg' => '当前登陆信息已失效,请重新登陆', 'data' => []]);
  267. }
  268. //只输出执行完成状态 shish 2020.3.11
  269. public static function complete($msg = '')
  270. {
  271. $msg = empty($msg) ? '操作成功' : $msg;
  272. self::encode(['code' => 1, 'msg' => $msg, 'data' => []]);
  273. }
  274. public static function notLogin($msg = '没有登陆')
  275. {
  276. self::encode(['code' => -1, 'msg' => $msg, 'data' => []]);
  277. }
  278. }