先说一下本人在工作中遇到的瓶颈

之前做过一个【霍兰德职业兴趣测试】测试的项目,大体结构就是用户答题,系统根据用户回答的问题进行职业性格测试,最后显示结果,在结果页存在一个类似于六芒星的能力分析图(这个是我自己起的名字,具体是叫什么我也不太清楚,下面将以“六芒星图”代替),起初我们用的是Echarts插件,本来相安无事。突然有一天,客户提了一个需求,需要把结果页实现一个长按保存的功能,我们计划用html2canvas实现,这时发现页面中使用Echarts生成的六芒星图在利用html2canvas时不能成功保存为图片,前端的同事们束手无策,好吧,工作丢给了我们PHP,欲哭无泪。我在各种网站中找资料,发现没有任何现成的代码(可能是我没有找到),好吧,自己写。之前由于时间比较紧,没有时间考虑其他的东西,用的是GD库的函数,别提多苦逼了。现在把整理好的代码放上来供大家参考,希望能帮到同样问题的小伙伴。

使用条件

由于之前使用GD库的代码实现的,后来发现GD库过于麻烦,而且性能简直不敢恭维,所以,后来完善代码的使用的是Imagick,所以需要安装这个控件,这篇文章也会将Imagick的安装方法简单介绍,如果不懂的小伙伴可以在自行百度其他答案。

Windows安装

  • ImageMagick下载地址(对照好VC库的版本)https://windows.php.net/downloads/pecl/deps/
  • php扩展下载地址http://pecl.php.net/package/imagick
  • 将ImageMagick的软件包下载好之后解压,然后将软件目录下的bin目录加入到环境变量中,不会设置环境变量的小伙伴请看这里
  • 测试ImageMagick是否安装成功,打开CMD命令,输入下面的命令(stream.ext -version),如果出现了版本信息证明已经安装成功了。

  • 将php的扩展包解压,然后将解压包中的php_imagick.dll文件及其他的.dll文件都复制到php目录的扩展控件目录下,修改配置文件,重启使之生效

Linux安装(以CentOS为例)

  • 使用yum安装ImageMagick与ImageMagick-devel(也可以使用源码编译安装,不过依赖有些麻烦,有兴趣的小伙伴可以研究一下),注意ImageMagick-devel这个必须安装,否则在安装php扩展时会报错。
  • 使用convert -v测试是否安装成功

  • 同样使用windows中的那个php扩展的地址,下载.tar文件,使用phpize编译安装,然后重启服务(如果PHP不是源码安装的小伙伴可以自行百度)。

上代码

以下代码完全是本人自行编写,可能存在性能、资源上的不足,请各位大神多多指点,谢谢。

<?php
/*** +--------------------------------------------------------* | 多边形能力分析图* +--------------------------------------------------------* | @author Renling* +--------------------------------------------------------* | @email gang888.2011@qq.com* +--------------------------------------------------------* | @date 22:14 2018/8/21* +--------------------------------------------------------* | @method* | PolygonChart::setLevelColor($color) 设置辅助区域的颜色* |        $color array 5个颜色数据组成的数组 ,可参考PolygonChart::$levelFillColor* | PolygonChart::setSize($size) 设置图片大小* | PolygonChart::setNode($node) 设置边数* | PolygonChart::setGuideColor($color) 设置辅助线颜色* | PolygonChart::setMaxValue($color) 设置能力值* | PolygonChart::setAbilityLineColor($color) 设置能力轮廓线的颜色* | PolygonChart::setAbilityFillColor($color) 设置能力轮廓的填充颜色* | PolygonChart::setBackgroundColor($color) 设置图片的背景颜色* | PolygonChart::draw($data) 绘制图形* |        $data array 元素数量与边数对应* +--------------------------------------------------------*/
class PolygonChart
{private $backgroundColor = 'rgba(255, 255, 255, 0)'; //设置图像的背景颜色private $levelFillColor = ['rgba(35, 135, 147, 0.5)','rgba(59, 162, 174, 0.5)','rgba(89, 182, 193, 0.5)','rgba(138, 206, 214, 0.5)','rgba(178, 226, 232, 0.5)'];      //设置每个级别的多边形填充的颜色private $sideLength = 200;                          //图片的边长=多边形外接圆直径private $nodeNumber = 6;                            //节点的数量private $guideColor = '#217882';                    //辅助线的颜色private $nodeMaxValue = 100;                        //每个节点所代表的最大值private $abilityLineColor = '#aa604d';              //能力线的颜色private $abilityFillColor = 'rgba(227, 144, 62, 0.5)';   //能力图的填充颜色private $guideColorImagickPixel;                    //辅助线颜色资源private $circumscribedCircleRadius;                 //正多边形外接圆的半径private $points;                                    //各点坐标存储/*** 设置图像的背景颜色* @author Renling* @date 17:22 2018/8/22** @access public* @param $color string 颜色值** @return $this*/public function setBackgroundColor($color){$this->backgroundColor = $color;return $this;}/*** 设置每个级别的多边形填充的颜色* @author Renling* @date 14:06 2018/8/22** @access public* @param $color array 每个级别的多边形填充的颜色** @return $this*/public function setLevelColor($color){$this->levelFillColor = $color;return $this;}/*** 设置图片大小* @author Renling* @date 14:08 2018/8/22** @access public* @param $size int 图片的大小** @return $this*/public function setSize($size){$this->sideLength = $size;return $this;}/*** 设置多边形的边数* @author Renling* @date 14:10 2018/8/22** @access public* @param $node int 多边形的节点数** @return $this*/public function setNode($node){$this->nodeNumber = $node;return $this;}/*** 设置辅助线颜色* @author Renling* @date 14:12 2018/8/22** @access public* @param $color string 颜色值** @return $this*/public function setGuideColor($color){$this->guideColor = $color;return $this;}/*** 设置每个能力的最大值* @author Renling* @date 14:13 2018/8/22** @access public* @param $value int 能力值** @return $this*/public function setMaxValue($value){$this->nodeMaxValue = $value;return $this;}/*** 设置能力轮廓线的颜色* @author Renling* @date 14:15 2018/8/22** @access public* @param $color string 颜色值** @return $this*/public function setAbilityLineColor($color){$this->abilityLineColor = $color;return $this;}/*** 设置能力轮廓的填充颜色* @author Renling* @date 14:17 2018/8/22** @access public* @param $color string 颜色值** @return $this*/public function setAbilityFillColor($color){$this->abilityFillColor = $color;return $this;}/*** 获取辅助线的颜色资源* @author Renling* @date 22:24 2018/8/21** @access private** @return ImagickPixel*/private function getGuideColor(){if (is_null($this->guideColorImagickPixel)) {$this->guideColorImagickPixel = new ImagickPixel($this->guideColor);}return $this->guideColorImagickPixel;}/*** 根据多变形等级绘制正多边形* @author Renling* @date 22:34 2018/8/21 0021** @access private* @param $level int 正多边形的等级 1-5,等级越高,多边形等级越大** @return ImagickDraw*/private function drawPolygon($level = 5){//根据正多边形的等级计算坐标中需要进行偏移的距离$offsetLength = (5-$level)*$this->circumscribedCircleRadius/5;//获取当前等级的外接圆半径$levelCircumscribedCircleRadius = $level*$this->circumscribedCircleRadius/5;//根据边数获取节点的坐标$points = [];//获取角度$angle = 360/$this->nodeNumber;//获取第一个点坐标$points[] = ['x' => $levelCircumscribedCircleRadius+$offsetLength, 'y' => $offsetLength];//当前临时变量为了优化代码,不做解释$coordinateTmp = $levelCircumscribedCircleRadius+$offsetLength;//遍历获取后面的sideNumber-1个节点的坐标for ($i=1; $i<$this->nodeNumber; $i++) {//当前临时变量为了优化代码,不做解释$angleTmp = deg2rad($i*$angle);$y = $coordinateTmp-round(cos($angleTmp)*$levelCircumscribedCircleRadius, 2);$x = $coordinateTmp+round(sin($angleTmp)*$levelCircumscribedCircleRadius, 2);$points[] = ['x' => $x, 'y' => $y];}$this->points[] = $points;//获取辅助线的颜色资源$guideColor = $this->getGuideColor();//获取辅助图像的填充颜色$fillColor = new ImagickPixel($this->levelFillColor[$level-1]);//实例化ImagickDraw$draw = new ImagickDraw();//设置透明度$draw->setStrokeOpacity(1);//设置辅助线的颜色$draw->setStrokeColor($guideColor);//设置边的宽度$draw->setStrokeWidth(1);//设置辅助图形的填充颜色$draw->setFillColor($fillColor);//绘制正多边形$draw->polygon($points);return $draw;}/*** 绘制中心点到最大多边形节点的连线* @author Renling* @date 17:17 2018/8/22** @access private** @return ImagickDraw*/public function drawCenterToMaxLine(){//绘制中心点到最大多边形节点的连线$draw = new ImagickDraw();//设置透明度$draw->setStrokeOpacity(1);//设置辅助线的颜色$draw->setStrokeColor($this->getGuideColor());//设置边的宽度$draw->setStrokeWidth(1);//获取最大外接圆的节点坐标$points = $this->points[0];foreach ($points as $nodeItem) {$draw->line($this->circumscribedCircleRadius, $this->circumscribedCircleRadius, $nodeItem['x'], $nodeItem['y']);}return $draw;}/*** 构建一个多边形的背景图* @author Renling* @date 22:26 2018/8/21** @access private** @return Imagick*/private function drawPolygonBkImage(){//构建图像资源$image = new Imagick();//对图像资源进行属性设置(宽 高 颜色)$image->newImage($this->sideLength, $this->sideLength, new ImagickPixel($this->backgroundColor));//设置图像资源图片格式(PNG)$image->setImageFormat("png");return $image;}/*** 绘制能力图像* @author Renling* @date 22:57 2018/8/21 0021** @access private* @param $data array 能力数据** @return ImagickDraw*/private function drawAbility($data){if (!is_array($data)) {return null;}//获取中心点坐标$centerPoint = ['x' => $this->circumscribedCircleRadius, 'y' => $this->circumscribedCircleRadius];//获取每个节点的最大外接圆的点坐标$maxCircumscribedCirclePoints = $this->points[0];//获取每项的值的节点坐标$dataPoints = [];foreach ($maxCircumscribedCirclePoints as $key => $maxCircumscribedCirclePointsItem) {if (!isset($data[$key]))$value = 0;else$value = $data[$key];if ($value<0)$value = 0;elseif ($value>$this->nodeMaxValue)$value = $this->nodeMaxValue;$dataPoints[] = ['x'     => round($centerPoint['x'] + ($maxCircumscribedCirclePointsItem['x'] - $centerPoint['x'])*$value/$this->nodeMaxValue, 2),'y'     => round($centerPoint['y'] + ($maxCircumscribedCirclePointsItem['y'] - $centerPoint['y'])*$value/$this->nodeMaxValue, 2),];}//构建一个多边形$draw = new ImagickDraw();//获取能力图形线的颜色资源$abilityLineColor = new ImagickPixel($this->abilityLineColor);//设置透明度$draw->setStrokeOpacity(1);//设置能力图形线的颜色$draw->setStrokeColor($abilityLineColor);//设置边的宽度$draw->setStrokeWidth(1);//设置填充颜色$draw->setFillColor(new ImagickPixel($this->abilityFillColor));//绘制能力多边形$draw->polygon($dataPoints);return $draw;}/*** 自动制作一个正多边形能力图* @author Renling* @date 22:37 2018/8/21** @access public* @param $data array 能力数据** @return Imagick*/public function draw($data){//设置正多边形外接圆的半径$this->circumscribedCircleRadius = $this->sideLength/2;//构建一个图像资源$image = $this->drawPolygonBkImage();//从大到小的依次绘制5个正多边形for ($level=5; $level>0; $level--) {$draw = $this->drawPolygon($level);$image->drawImage($draw);unset($draw);}$image->drawImage($this->drawCenterToMaxLine());//构建能力图形//将能力图形绘制到图片上$image->drawImage($this->drawAbility($data));return $image;}
}

实例展示

<?php
require '../PolygonChart.php';
$chart = new PolygonChart;
$image = $chart->draw([58, 63, 44, 45, 75, 56]);
header('Content-Type:image/png');
echo $image->getImageBlob();

效果图展示

<?php
require '../PolygonChart.php';
$chart = new PolygonChart;
$image = $chart->setBackgroundColor('#ff0000')->setNode(5)->draw([58, 63, 44, 45, 75]);
header('Content-Type:image/png');
echo $image->getImageBlob();

效果图展示

还有很多其他的设置,欢迎小伙伴们尝试,如果有不足的地方,希望小伙伴们能够指正,谢谢。

PHP使用Imagick绘制六芒星能力图相关推荐

  1. 绘制六芒星战斗力属性图 —— h5 canvas 初体验

    在黄金的沙滩上 安息着远古的悲剧 在深绿的波涌中 停着灵魂的船 --<眼睛>,顾城 最近用MUI做Web app时想实现一个六芒星战斗力图的(类似LPL赛前战队实力分析图)效果,由于正多边 ...

  2. 「Python海龟画图」利用海龟画笔绘制六芒星阵

    利用海龟笔绘制1/3圆弧 功能要求 利用海龟笔绘制一个半径为100的,1/3圆弧,并隐藏海龟画笔,设置画笔颜色,设置海龟笔的宽度和海龟笔的颜色. 实例代码 import turtle'''设置画笔和画 ...

  3. python数据科学包(七)—— matplotlib实战之绘制球员能力图和股票K线图

    1.球员能力图 # -*- coding: utf-8 -*- import numpy as np import pandas as pd import matplotlib.pyplot as p ...

  4. 用css绘制六芒星,turtle库应用实例2-六芒星的绘制

    ‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬ 描述 ...

  5. 使用 Vue SVG 快速绘制曲线图(带动画)

    图表 当接到类似以上需求时,你的第一想法是不是跟我一样,使用 Canvas 来绘制,啥都不说就开始撸代码.如果你是用 Vue 之类的 MVVM 框架,那意味着你得提供一个结点供 Canvas 着陆,同 ...

  6. php 六边形 属性图 能力数值图,详解基于 Canvas 手撸一个六边形能力图

    一.前言 六边形能力图如下,由 6 个 六边形组成,每一个顶点代表其在某一方面的能力.这篇文章我们就来看看如何基于 canvas 去绘制这么一个六边形能力图.当然,你也可以基于其他开源的 js 方案来 ...

  7. html5如何编写六角形,详解基于 Canvas 手撸一个六边形能力图

    一.前言 六边形能力图如下,由 6 个 六边形组成,每一个顶点代表其在某一方面的能力.这篇文章我们就来看看如何基于 canvas 去绘制这么一个六边形能力图.当然,你也可以基于其他开源的 js 方案来 ...

  8. Coursera自动驾驶课程第5讲:Vehicle Dynamic Modeling

    在上一讲<Coursera自动驾驶课程第4讲:Safety Assurance for Autonomous Vehicles>中我们了解了自动驾驶汽车中一个非常重要的模块:安全模块. 本 ...

  9. 【JY】No.7.1力学架构结构力学求解器(SM)使用教程

    软件讲解示例之理论(电算/手算)分析思路: 1.结构建模,并完成结构假定,如定义梁端弯矩释放(详见第二章). 2.线性屈曲分析(是否失稳破坏分析): 3.强度/挠度计算:(构件本身强度是否达标) 4. ...

最新文章

  1. ASP .NET Core Web Razor Pages系列教程二:添加模型到Razor Pages网络应用程序
  2. ssh证书登录(实例详解)
  3. 怎么看到方法内引用方法的注释_网页内文字无法复制怎么办?一分钟看懂这些方法,让你随意复制...
  4. SAP Spartacus login 超链接和 login form 的区别
  5. [AGC031E] Snuke the Phantom Thief(网络流)
  6. webService上传图片
  7. KeyMob具有手机广告优化的管理平台
  8. linux+free参数类型,linux的free命令
  9. 使用Oracle 11g新特性 Active Database Duplication 搭建Dataguard环境
  10. stomp+websocket 集群问题_手把手搭建WebSocket多人在线聊天室
  11. Qt程序的国际化支持【收藏】
  12. java 冒号转义_java – 使用Hibernate查询:冒号被视为参数/转义冒号
  13. python是个坑_Python 有什么不为人知的坑?
  14. 光功率计(Optical power meter)
  15. html页面如何引用母版页,内容页面访问母版页控件的两种方法
  16. 计算机的空间复用技术应用,MIMO技术的介绍
  17. iOS 16 Beta如何降级iOS 15系统?详细图文教程!
  18. Python基础——修改Python字典中的key(键)
  19. Tennessee Eastman(TE过程)简介
  20. jsoup填充内容然后html转word

热门文章

  1. 目标-过程-结果经验分享及OKR工作法
  2. java实现海盗比酒量
  3. erlang httpc
  4. 浅谈C中的wprintf和宽字符显示
  5. 使用Locust进行性能测试,Locust启动失败
  6. 给win8、win10系统添加自定义右键菜单项目
  7. echarts之legend-改变图例的图标为自定义图片
  8. 高德API 经纬度转换地市区县(含读取文件)
  9. 杂项-一张图片和爆破一
  10. 建筑师又在用人工智能做什么?(2019年第三期)