h5生成海报到php生成海报

27 篇文章 1 订阅

1.h5生成海报

 <div id="qrcodeCanvas" style="position: absolute;left:-2000px"></div>
    <!--海报图画布-->
    <canvas id="myCanvas" style="position: absolute;right:-2000px"></canvas>
     <div class="showPoster"><img id="showImg" />
 <div>
<script type="text/javascript" src="./js/jquery.js"></script>
<script src="./js/showLoading/showLoading/jquery.showLoading.min.js"></script>
<script src="./js/showLoading/showLoading/jquery.showLoading.js"></script>
<script type="text/javascript" src="./js/qrcode.js"></script>
<script type="text/javascript">
    var qrcodeImg    //二维码img
    shareImg();
    function shareImg(){
        $('#showImg').showLoading('图片生成中...');
        //移除已生成的避免重复(必须!)
        $('#qrcodeCanvas').html("");
        var qrcode = new QRCode('qrcodeCanvas', {
            text: "二维码内容",
            width: 100,
            height: 100,
            colorDark: '#000000',
            colorLight: '#ffffff',
            correctLevel: QRCode.CorrectLevel.H
        });
        qrcodeImg = $("#qrcodeCanvas img")[0]
        qrcodeImg.crossOrigin = "anonymous"
        console.log(qrcodeImg)
        //这里必须用onload 二维码是异步生成,异步的意思不用多说吧?
        qrcodeImg.onload = function() {
            //画海报
            beginDraw()
        }
    }
    function beginDraw(){
        //画海报
        var width  = 320
        var height = 450
        var c      = document.getElementById("myCanvas");
        c.width    = width
        c.height   = height
        var ctx    = c.getContext("2d");
        //首先画上背景图
        //注意:H5中任何图片写入画布都是以img 例如(<img src="123.png">),以下代码console.log() 出来就是它
        var img = new Image();
        img.src = '图片地址';
        img.crossOrigin = "anonymous"
        img.onload = function() {
            //画入背景图
            ctx.drawImage(img,0,0,width,height);
            img.src = '图片地址';
            img.crossOrigin = "anonymous"
            img.onload = function() {
                //画入logo
                ctx.drawImage(img,90,30,150,140);
                img.src = '图片地址';
                img.crossOrigin = "anonymous"
                img.onload = function() {
                    //画入底部背景
                    ctx.drawImage(img,0,height-180,width,120);
                    img.src = '图片地址';
                    img.crossOrigin = "anonymous"
                    img.onload = function() {
                        //画入头像
                        ctx.drawImage(img,10,height-155,70,70);
                        //画入二维码
                        ctx.drawImage(qrcodeImg,210,height-170,100,100);
                        ctx.font ="18px Bold Arial";
                        ctx.fillStyle = "#fff";
                        ctx.fillText("文字",40,height-220);
                        ctx.font ="18px Medium Arial";
                        ctx.fillStyle = "#000";
                        ctx.fillText("文字",90,height-130);
                        ctx.font ="18px Medium Arial";
                        ctx.fillStyle = "#000";
                        ctx.fillText("文字 ",90,height-90);
                        //绘制完成,转为图片
                        setTimeout(function() {
                            base64_path = c.toDataURL("image/jpeg",1);
                            $('#showImg').attr('src',base64_path)
                            $('#showImg').hideLoading();
                            $('.mask').show()
                            $('.showPoster').show()
                        },100)

                    }
                }
            }
        }
    }
</script>

2.本以为大功告成 结果部分安卓手机在这里不执行

        qrcodeImg.onload = function() {
            //画海报
            beginDraw()
        } 

搜了一大顿资料,参考移动端File和Base64的坑  可能会解决吧

我就不试了

3.直接后台生成吧

        $new_file_name = $fiel_dir .$file_name;
        $fontpath = realpath('./ttf/simsunb.ttf');
//        $fontpath = 'https://cummins.weimobile.cc/ttf/arial.ttf';
        $config = array(
            'text'=>array(
                array(
                    'text'=>'文字',
                    'left'=>23,
                    'top'=>330,
                    'fontPath'=>$fontpath,     //字体文件
                    'fontSize'=>22,             //字号
                    'fontColor'=>'255,255,255',       //字体颜色
                    'angle'=>0,
                ),

            ),
            'image'=>array(
                array(
                    'url'=> '图片地址',//kmslogo
                    'left'=>120,
                    'top'=>60,
                    'stream'=>0,             //图片资源是否是字符串图像流
                    'right'=>0,
                    'bottom'=>0,
                    'width'=>150,
                    'height'=>150,
                    'opacity'=>100
                ),
                
            ),
            'background'=>'背景图路径',
        );
        $filename=createPoster($config,$new_file_name);
/**
 * 生成宣传海报
 * @param array  参数,包括图片和文字
 * @param string  $filename 生成海报文件名,不传此参数则不生成文件,直接输出图片
 * @return [type] [description]
 */
function createPoster($config=array(),$filename=""){
    //如果要看报什么错,可以先注释调这个header
    if(empty($filename))
        header("content-type: image/png");
    $imageDefault = array(
        'left'=>0,
        'top'=>0,
        'right'=>0,
        'bottom'=>0,
        'width'=>100,
        'height'=>100,
        'opacity'=>100
    );
    $textDefault = array(
        'text'=>'',
        'left'=>0,
        'top'=>0,
        'fontSize'=>32,       //字号
        'fontColor'=>'255,255,255', //字体颜色
        'angle'=>0,
    );
    $background = $config['background'];//海报最底层得背景
    //背景方法
    $backgroundInfo = getimagesize($background);
    $backgroundFun = 'imagecreatefrom'.image_type_to_extension($backgroundInfo[2], false);
    $background = $backgroundFun($background);
    $backgroundWidth = imagesx($background);  //背景宽度
    $backgroundHeight = imagesy($background);  //背景高度
    $imageRes = imageCreatetruecolor($backgroundWidth,$backgroundHeight);
    $color = imagecolorallocate($imageRes, 0, 0, 0);
    imagefill($imageRes, 0, 0, $color);
    // imageColorTransparent($imageRes, $color);  //颜色透明
    imagecopyresampled($imageRes,$background,0,0,0,0,imagesx($background),imagesy($background),imagesx($background),imagesy($background));
    //处理了图片
    if(!empty($config['image'])){
        foreach ($config['image'] as $key => $val) {
            $val = array_merge($imageDefault,$val);
            $info = getimagesize($val['url']);
            $function = 'imagecreatefrom'.image_type_to_extension($info[2], false);
            if($val['stream']){   //如果传的是字符串图像流
                $info = getimagesizefromstring($val['url']);
                $function = 'imagecreatefromstring';
            }
            $res = $function($val['url']);
            $resWidth = $info[0];
            $resHeight = $info[1];
            //建立画板 ,缩放图片至指定尺寸
            $canvas=imagecreatetruecolor($val['width'], $val['height']);
            imagefill($canvas, 0, 0, $color);
            //关键函数,参数(目标资源,源,目标资源的开始坐标x,y, 源资源的开始坐标x,y,目标资源的宽高w,h,源资源的宽高w,h)
            imagecopyresampled($canvas, $res, 0, 0, 0, 0, $val['width'], $val['height'],$resWidth,$resHeight);
            $val['left'] = $val['left']<0?$backgroundWidth- abs($val['left']) - $val['width']:$val['left'];
            $val['top'] = $val['top']<0?$backgroundHeight- abs($val['top']) - $val['height']:$val['top'];
            //放置图像
            imagecopymerge($imageRes,$canvas, $val['left'],$val['top'],$val['right'],$val['bottom'],$val['width'],$val['height'],$val['opacity']);//左,上,右,下,宽度,高度,透明度
        }
    }
    //处理文字
    if(!empty($config['text'])){
        foreach ($config['text'] as $key => $val) {
            $val = array_merge($textDefault,$val);
            list($R,$G,$B) = explode(',', $val['fontColor']);
            $fontColor = imagecolorallocate($imageRes, $R, $G, $B);
            $val['left'] = $val['left']<0?$backgroundWidth- abs($val['left']):$val['left'];
            $val['top'] = $val['top']<0?$backgroundHeight- abs($val['top']):$val['top'];
//            imagettftext($imageRes,$val['fontSize'],$val['angle'],$val['left'],$val['top'],$fontColor,'STHUPO.TTF',$val['text']);
            imagettftext($imageRes,$val['fontSize'],$val['angle'],$val['left'],$val['top'],$fontColor,$val['fontPath'],$val['text']);
        }
    }
    //生成图片
    if(!empty($filename)){
        $res = imagejpeg ($imageRes,$filename,90); //保存到本地
        imagedestroy($imageRes);
        if(!$res) return false;
        return $filename;
    }else{
        imagejpeg ($imageRes);     //在浏览器上显示
        imagedestroy($imageRes);
    }
}

 4.关于字体大小  摘自php中imagettftext()函数的使用_百度知道

共有8个参数,缺一不可:
  (1)$image 这个是画布资源,无需再解释;
  (2)$size,官方文档的解释是,字体大小,其长度单位依赖于GD库的版本,对于GD1来说是像素,对于GD2来说是磅(point)。现在一般都是GD2了,那么这个磅究竟是什么意思呢?这涉及到字体设计的基本知识。
  操作位图时,以像素位单位最精确合理,那么使用GD2库的时候,如何绘制大小为20像素的字呢?也就是多少磅才能等于20个像素呢?这必须通过分辨率才能计算出来,而问题是位图本身并没有分辨率的概念。
  现在把问题返回来,如果给定$size=20磅,那么imageTtfText()绘制完成时,究竟会占用多少像素。无论如何,imageTtfText()最终还是要把文字绘制落实到具体的位图像素上。
  这个问题确实非常棘手,此函数内部必然会使用某个分辨率PPI来计算被渲染的像素区域。而GD2库却没有提供任何让用户设置或者读取这个分辨率的方法。那么,我们只能动手测试了。使用不同的磅值绘制文字,然后测量文字占据的像素,通过公式:
  PPI = (72*像素数)/磅值。实验得出的结论是:
  [plain] view plaincopyprint?
  1磅==>4像素, PPI=288
  2磅==>5像素, PPI=180
  3磅==>7像素, PPI=168
  4磅==>8像素, PPI=144
  5磅==>9像素, PPI=129.6
  6磅==>10像素, PPI=120
  7磅==>11像素, PPI=113.14285714286
  8磅==>12像素, PPI=108
  9磅==>14像素, PPI=112
  10磅==>15像素, PPI=108
  11磅==>16像素, PPI=104.72727272727
  12磅==>17像素, PPI=102
  13磅==>18像素, PPI=99.692307692308
  14磅==>19像素, PPI=97.714285714286
  15磅==>21像素, PPI=100.8
  16磅==>22像素, PPI=99
  17磅==>23像素, PPI=97.411764705882
  18磅==>25像素, PPI=100
  19磅==>26像素, PPI=98.526315789474
  20磅==>27像素, PPI=97.2
  21磅==>28像素, PPI=96
  22磅==>29像素, PPI=94.909090909091
  23磅==>30像素, PPI=93.913043478261
  24磅==>32像素, PPI=96
  25磅==>33像素, PPI=95.04
  26磅==>34像素, PPI=94.153846153846
  27磅==>35像素, PPI=93.333333333333
  28磅==>36像素, PPI=92.571428571429
  29磅==>38像素, PPI=94.344827586207
  30磅==>39像素, PPI=93.6
  31磅==>40像素, PPI=92.903225806452
  32磅==>41像素, PPI=92.25
  33磅==>43像素, PPI=93.818181818182
  34磅==>44像素, PPI=93.176470588235
  35磅==>46像素, PPI=94.628571428571
  36磅==>47像素, PPI=94
  37磅==>48像素, PPI=93.405405405405
  38磅==>48像素, PPI=90.947368421053
  39磅==>50像素, PPI=92.307692307692
  40磅==>51像素, PPI=91.8
  41磅==>52像素, PPI=91.317073170732
  42磅==>53像素, PPI=90.857142857143
  43磅==>55像素, PPI=92.093023255814
  44磅==>56像素, PPI=91.636363636364
  45磅==>57像素, PPI=91.2
  46磅==>58像素, PPI=90.782608695652
  47磅==>60像素, PPI=91.914893617021
  48磅==>62像素, PPI=93
  49磅==>63像素, PPI=92.571428571429
  50磅==>63像素, PPI=90.72
  51磅==>64像素, PPI=90.352941176471
  52磅==>67像素, PPI=92.769230769231
  53磅==>68像素, PPI=92.377358490566
  54磅==>69像素, PPI=92
  55磅==>70像素, PPI=91.636363636364
  56磅==>71像素, PPI=91.285714285714
  57磅==>72像素, PPI=90.947368421053
  58磅==>74像素, PPI=91.862068965517
  59磅==>75像素, PPI=91.525423728814
  60磅==>76像素, PPI=91.2
  61磅==>77像素, PPI=90.885245901639
  62磅==>78像素, PPI=90.58064516129
  63磅==>79像素, PPI=90.285714285714
  64磅==>81像素, PPI=91.125
  65磅==>83像素, PPI=91.938461538462
  66磅==>84像素, PPI=91.636363636364
  67磅==>85像素, PPI=91.34328358209
  68磅==>86像素, PPI=91.058823529412
  69磅==>86像素, PPI=89.739130434783
  70磅==>88像素, PPI=90.514285714286
  71磅==>90像素, PPI=91.267605633803
  72磅==>91像素, PPI=91
  73磅==>92像素, PPI=90.739726027397
  74磅==>93像素, PPI=90.486486486486

可见当大于46磅时,PPI稳定在90,而小于46磅时,PPI一直在微变。
  所以,如果你想绘制20个像素大小的字体,那么必须设置$size参数为:14.5磅。
  另外需要注意的是,$size并不完全对应字体的显示大小,因为同样的$size,不同的字符占据的空间并不是一样的。例如,汉字“国”的宽度会比数字1的宽度大得多,对于标点符号,则更是这样,半角和全角符号也不同。
  总之,使用imageTtfText()不可能精确控制到像素级别,只能大概。这也算是矢量字体的一个小缺陷。

(4)(5)$x,$y 被绘制字符串的第一个字符的基线点。单位是像素。这里涉及到字体设计的基本知识--基线。这个点绝对不是左上角,(这里要注意)而具体是什么取决于所使用的字体是如何设计的。对于宋体、楷体、黑体等常见的字体中的汉字,这个点大概位于字体的左下部分;而对于英文字母和标点符号,则各不相同。

5.以为可以成功了,

字体文件是windows下的font文件下复制的,结果字体不识别,一顿正方形是啥意思。。。码云上搜的成功案例的字体文件使用,嗯 这下可以了

6.php gd库怎么把一个图片裁剪成圆形的

方法1:

function yuan_img($imgpath) {

  $ext     = pathinfo($imgpath);

  $src_img = null;

  switch ($ext['extension']) {

  case 'jpg':

      $src_img = imagecreatefromjpeg($imgpath);

      break;

  case 'png':

      $src_img = imagecreatefrompng($imgpath);

      break;

  }

  $wh  = getimagesize($imgpath);

  $w   = $wh[0];

  $h   = $wh[1];

  $w   = min($w, $h);

  $h   = $w;

  $img = imagecreatetruecolor($w, $h);

  //这一句一定要有

  imagesavealpha($img, true);

  //拾取一个完全透明的颜色,最后一个参数127为全透明

  $bg = imagecolorallocatealpha($img, 255, 255, 255, 127);

  imagefill($img, 0, 0, $bg);

  $r   = $w / 2; //圆半径

  $y_x = $r; //圆心X坐标

  $y_y = $r; //圆心Y坐标

  for ($x = 0; $x < $w; $x++) {

      for ($y = 0; $y < $h; $y++) {

          $rgbColor = imagecolorat($src_img, $x, $y);

          if (((($x - $r) * ($x - $r) + ($y - $r) * ($y - $r)) < ($r * $r))) {

              imagesetpixel($img, $x, $y, $rgbColor);

          }

      }

  }
  $dest_path = $path.uniqid().'.png';  
  imagesavealpha($img, true);  
  imagepng($img, $dest_path);  
  imagedestroy($img);  
  imagedestroy($src_img); 
  return $dest_path;

}

方法2: 

    private function yuan_img($imgpath)
    {
        $wh  = getimagesize($imgpath);//pathinfo()不准
        $src_img = null;
        switch ($wh[2]) {
            case 1:
                //gif
                $src_img = imagecreatefromgif($imgpath);
                break;
            case 2:
                //jpg
                $src_img = imagecreatefromjpeg($imgpath);
                break;
            case 3:
                //png
                $src_img = imagecreatefrompng($imgpath);
                break;
        }
        $w   = $wh[0];
        $h   = $wh[1];
        $w   = min($w, $h);
        $h   = $w;
        $img = imagecreatetruecolor($w, $h);
        //这一句一定要有
        imagesavealpha($img, true);
        //拾取一个完全透明的颜色,最后一个参数127为全透明
        $bg = imagecolorallocatealpha($img, 255, 255, 255, 127);
        imagefill($img, 0, 0, $bg);
        $r   = $w / 2; //圆半径
        $y_x = $r; //圆心X坐标
        $y_y = $r; //圆心Y坐标
        for ($x = 0; $x < $w; $x++) {
            for ($y = 0; $y < $h; $y++) {
                $rgbColor = imagecolorat($src_img, $x, $y);
                if (((($x - $r) * ($x - $r) + ($y - $r) * ($y - $r)) < ($r * $r))) {
                    imagesetpixel($img, $x, $y, $rgbColor);
                }
            }
        }
        return [$img,$w];
    }

7.php 图片水印imagecopymerge和imagecopy

imagecopymerge可以把不符合大小尺寸的图片压缩或拉伸成合适的水印大小,并对整个水印图片加透明度,但水印图片内部的透明度会被填充为默认黑色,

imagecopy可以对原图素材裁剪,但不做压缩或填充。合成后保留png本身的透明度

8. php生成圆形头像,合并到其他图片,以及二维码的合并

   public function planetshareAction()
    {
        putenv('GDFONTPATH=' . realpath(__DIR__ . '/../../assets'));
        $param = $_GET;
        header("Content-Type:application/json;");
        $token = !empty($param['token']) ? $param['token'] : '';
//        if(empty($token)){
//            $result=array('code'=>2,'message'=>'参数有误');
//            echo json_encode($result,JSON_UNESCAPED_UNICODE);
//            return true;
//        }
        $loginArr= JWTAuth::checkLoginV2($token);
        $uid=empty($loginArr['uid'])?0:$loginArr['uid'];
        $muid=empty($loginArr['muid'])?0:$loginArr['muid'];

        $uid = 147;$muid = 0;
        $rpcParam['user'] = array('module'=>'user_user','method'=>'getUserInfoByUidOrMuid','param'=>array($uid,$muid));
        $rpcParam['code'] = array('module'=>'user_user','method'=>'getUserInviteCodeByMuidAndUid','param'=>array($uid,$muid));
        $rpcRes = RpcClient2::multiResult($rpcParam);
        foreach($rpcRes as $k=>$res){
            if($res['code']!= ServiceCode::SUCCESS){
                $this->logger->error("RpcClient2::multiResult error",array('param'=>$rpcParam[$k],'res'=>$res));
                echo json_encode(array('code'=>2,'message'=>'系统错误'),JSON_UNESCAPED_UNICODE);
                return true;
            }
        }

        $userInfo = !empty($rpcRes['user']['res']) ? $rpcRes['user']['res'] : [];
        $codeInfo = !empty($rpcRes['code']['res']) ? $rpcRes['code']['res'] : [];
        $userName = $userInfo['real_name'] ? $userInfo['real_name'] : $userInfo['nickname'];
        $headimgurl = $userInfo['headimgurl'];
        $inviteCodeText = '邀请码:'.$codeInfo['invite_code'];

        $totalWdith = 280 * 2;
        $totalHeight = 518 * 2;
        $headimgOneWidth = 280 * 2;
        $headimgOneHeight = 78 * 2;
        $headimgTwoWidth = 270 * 2;
        $headimgTwoHeight = 318 * 2;
        $currentHeight = $headimgOneHeight + $headimgTwoHeight;
        $img = imagecreatetruecolor($totalWdith, $totalHeight);
        $white = imagecolorallocate($img, 255, 255, 255);
        $black = imagecolorallocate($img, 0, 0, 0);
        $grey = imagecolorallocate($img, 136, 136, 136);
        //背景色
        imagefilledrectangle($img, 0, 0, $totalWdith, $totalHeight, $white);
        //头部带阴影图片
        $headerimg = imagecreatefrompng(__DIR__ . '/../../assets/planet_one.png');
        imagecopy($img, $headerimg, 0, -1, 0, 0, $headimgOneWidth, $headimgOneHeight);
        imagedestroy($headerimg);
        //头部第二张图片
        $headerimgTwo = imagecreatefrompng(__DIR__ . '/../../assets/planet_two.png');
        imagecopy($img, $headerimgTwo, 5*2, 78 * 2, 0, 0, $headimgTwoWidth, $headimgTwoHeight);
        imagedestroy($headerimg);
        //用户头像
        //圆形图像参数
        $p_tmpWidth = 400;
        $p_tmpHeight = 300;
        $p_cutWidth = 0;
        $p_cutHeight = 0;
        $p_cutX = 0;
        $p_cutY = 0;
        $p_finalWidth = 45 * 2;
        $p_finalHeight = 45 * 2;
        $headImg = $this->cutPicture($headimgurl,$p_tmpWidth, $p_tmpHeight, $p_cutWidth, $p_cutHeight, $p_cutX, $p_cutY, $p_finalWidth, $p_finalHeight);
        imagecopy($img, $headImg, 16.5 * 2, $currentHeight + 15 * 2, 0, 0, $p_finalWidth, $p_finalHeight);
        imagefttext($img, 15 * 1.5, 0, 71.5 * 2, $currentHeight + 45 * 2, imagecolorallocate($img, 51, 51, 51), 'PingFang', $userName);

        imagefttext($img, 11 * 1.5, 0, 16.5 * 2, $currentHeight + 80 * 2, imagecolorallocate($img, 51, 51, 51), 'PingFang', $inviteCodeText);
        imagefttext($img, 11 * 1.5, 0, 103 * 2, $currentHeight + 80 * 2, imagecolorallocate($img, 136, 136, 136), 'PingFang', '(仅限5名)');
        //矩形框
        $leftSpace = 16.5 * 2;
        imagerectangle($img,$leftSpace,$currentHeight + 90 * 2, $leftSpace + 129.5 * 2, $currentHeight + 108 * 2,$grey);
        imagefttext($img, 11 * 1.5, 0, 21 * 2, $currentHeight + 103 * 2, imagecolorallocate($img, 136, 136, 136), 'PingFang', '长按二维码查看我的星球');
        //二维码
        $url = "https://m.bxcc.vip/notes/note1";
        $qr = new PhpQrcode();
        $qrCodeUrl =__DIR__ . '/../../assets/planetQrCode.png';
        $qr->generateQrCode($url, $qrCodeUrl, QR_ECLEVEL_L,5.5,2,true);
        //二维码图片合并
        $qrcodeImgWidth = 80 * 2;
        $qrcodeImgHeight = 80 * 2;
        $qrcodeImg = imagecreatefrompng($qrCodeUrl);
        imagecopy($img,  $qrcodeImg, 187 * 2, $currentHeight + 32 * 2, 0, 0, $qrcodeImgWidth, $qrcodeImgHeight);

        header("Content-Type:image/png");
        imagepng($img);
        imagedestroy($img);
        unlink($qrCodeUrl);
    }


    /**
     * 裁剪图片处理
     *
     * 图片裁剪的原理:
     * 1、先建立一个和前端裁剪控件宽高相同的基础画板。
     * 2、再把原图按原图自身的宽高比,以画板的宽或高为缩放基准等比缩放在画板上。
     * 3、再按照前端控件传过来的裁切的宽高和相对于前端画板原点的坐标,在后端生成画板中裁切出图片。
     * 4、再把裁剪出的图片按它自身的宽高比,以最终图像(200*200的图片)的宽或高为缩放基准等比缩放在最终图像上,且生成图像是透明背景。
     *
     * @param  [type]  $tmpname       图片上传成功后的临时目录
     * @param  [type]  $saveName      处理后的图片的保存路径和名称
     * @param  integer $p_tmpWidth    画板宽
     * @param  integer $p_tmpHeight   画板高
     * @param  integer $p_cutWidth    裁剪/选区的宽
     * @param  integer $p_cutHeight   裁剪/选区的高
     * @param  integer $p_cutX        选区左上角的点相对于等比缩放后的图片的原点的横坐标
     * @param  integer $p_cutY        选区左上角的点相对于等比缩放后的图片的原点的纵坐标
     * @param  integer $p_finalWidth  最终图像的宽
     * @param  integer $p_finalHeight 最终图像的高
     * @return [type]                 [description]
     */
    public function cutPicture($tmpname,$p_tmpWidth = 400, $p_tmpHeight = 300, $p_cutWidth = 0, $p_cutHeight = 0, $p_cutX = 0, $p_cutY = 0, $p_finalWidth = 200, $p_finalHeight = 200)
    {
        // 原图信息
        $imgInfo   = getimagesize($tmpname);
        $imgWidth  = $imgReWidth =  $imgInfo['0'];
        $imgHeight = $imgReHeight = $imgInfo['1'];
        $imgMime   = $imgInfo['mime'];

        // 打开原图
        if ($imgMime == 'image/gif') {
            $imgSource = imagecreatefromgif($tmpname);
        } elseif ($imgMime == 'image/jpeg' || $imgMime == 'image/jpg') {
            $imgSource = imagecreatefromjpeg($tmpname);
        } elseif ($imgMime == 'image/png') {
            $imgSource = imagecreatefrompng($tmpname);
        }

        // 原图exif信息,判断是否需要旋转图片
//        if (function_exists('exif_read_data')) {
//            $exif = @exif_read_data($tmpname);
//            if (isset($exif['Orientation'])) {
//                if ($exif['Orientation'] == 1) {
//                    // 不需要旋转
//                } elseif ($exif['Orientation'] == 6) {
//                    // 顺时针旋转90度
//                    $imgSource = imagerotate($imgSource, -90, 0);
//                    // 图片旋转90度以后,原图宽和高要调换
//                    $imgWidth  = $imgReWidth = $imgInfo['1'];
//                    $imgHeight = $imgReHeight= $imgInfo['0'];
//                } elseif ($exif['Orientation'] == 8) {
//                    // 逆时针旋转90度
//                    $imgSource = imagerotate($imgSource, 90, 0);
//                    // 图片旋转90度以后,原图宽和高要调换
//                    $imgWidth  = $imgReWidth = $imgInfo['1'];
//                    $imgHeight = $imgReHeight= $imgInfo['0'];
//                } elseif ($exif['Orientation'] == 3) {
//                    // 逆时针旋转180度
//                    $imgSource = imagerotate($imgSource, 180, 0);
//                }
//            }
//        }

        // 计算等比缩放到画板上时,原图的宽高
        $tmpWidth     = $p_tmpWidth;  			 // 画板的宽高(与前端裁剪控件的画板宽高相同)
        $tmpHeight    = $p_tmpHeight; 			 // 画板的宽高(与前端裁剪控件的画板宽高相同)
        $ratio_1      = $imgWidth / $imgHeight;  // 原图宽高比
        $ratio_2      = $tmpWidth / $tmpHeight;  // 画板宽高比
        if ($ratio_1  >= $ratio_2) {
            $imgWidth = $tmpWidth; 			 	 // 以画板宽为基准,计算等比缩放到画板上的原图的高
            $imgHeight= $imgWidth / $ratio_1;
        } else {
            $imgHeight= $tmpHeight;		 	 	 // 以画板高为基准,计算等比缩放到画板上的原图的宽
            $imgWidth = $imgHeight * $ratio_1;
        }

        // 创建画板
        $im_2 = imagecreatetruecolor($tmpWidth, $tmpHeight);
        // 将原图等比缩放到画板$im_2上,然后再在画板上裁剪需要的图片。注意:这种缩放并不一定完全占用整个画板的区域。
        imagecopyresampled($im_2, $imgSource, 0, 0, 0, 0, $imgWidth, $imgHeight, $imgReWidth, $imgReHeight);
        // 要裁剪的宽高(选区的宽高)
        $cutWidth  = $p_cutWidth;
        $cutHeight = $p_cutHeight;

        // 如果没有选择要裁剪的区域,默认把等比缩放后的整张图片作为选区,即裁剪整张图片
        if (empty($cutWidth) || empty($cutHeight)) {
            $cutWidth = $imgWidth;
            $cutHeight= $imgHeight;
        }

        // 创建与选区(要裁剪的图片)宽高相同的底版
        $im_3  = imagecreatetruecolor($cutWidth, $cutHeight);

        // 选区左上角的点相对于等比缩放后的图片的原点的坐标
        $cutX = $p_cutX;
        $cutY = $p_cutY;

        // 从画板中按坐标、裁切的宽高裁剪图片,并将裁剪的图片偏复制到$im_3上
        imagecopy($im_3, $im_2, 0, 0, $cutX, $cutY, $cutWidth, $cutHeight);

        // 最终图像的宽高
        $finalWidth  = $p_finalWidth;
        $finalHeight = $p_finalHeight;

        // 计算等比缩放到最终上图像时,裁切的图片的宽高
        $cutRatio    = $cutWidth / $cutHeight;
        $finalRatio  = $finalWidth / $finalHeight;
        if ($cutRatio >= $finalRatio) {
            $finalCutWidth = $finalWidth; // 以最终图像的宽为基准,计算等比缩放到最终图像上的裁切图的高
            $finalCutHeight= $finalCutWidth / $cutRatio;
        } else {
            $finalCutHeight= $finalHeight;// 以最终图像的高为基准,计算等比缩放到最终图像上的裁切图的宽
            $finalCutWidth = $finalHeight * $cutRatio;
        }

        // 居中的坐标值
        $finalX = ($finalWidth  - $finalCutWidth) / 2;
        $finalY = ($finalHeight - $finalCutHeight) / 2;

        // 最终图像
        $im_final = imagecreatetruecolor($finalWidth, $finalHeight);

        // 设置透明背景色,使$im_final底版透明
        $bgColor  = imagecolorallocatealpha($im_final, 0, 0, 0, 127);
        imagealphablending($im_final, false);
        imagefill($im_final, 0, 0, $bgColor);
        imagesavealpha($im_final, true);

        // 将从画板中裁切的图片居中并等比缩放到(默认200*200)的图像中
        imagecopyresampled($im_final, $im_3, $finalX, $finalY, 0, 0, $finalCutWidth, $finalCutHeight, $cutWidth, $cutHeight);

        //上面代码是缩放图片的
        //下面部分是圆形图片代码
        $w   = $finalWidth;
        $h   = $finalHeight;
        $w   = min($w, $h);
        $h   = $w;
        $img = imagecreatetruecolor($w, $h);
        imagesavealpha($img, true);
        $bg = imagecolorallocatealpha($img, 255, 255, 255, 127);//背景色 白色
//        $bg = imagecolorallocatealpha($img, 255, 255, 255, 255);//背景色 黑色
        imagefill($img, 0, 0, $bg);
        $r   = $w / 2; //圆半径
        $y_x = $r; //圆心X坐标
        $y_y = $r; //圆心Y坐标
        for ($x = 0; $x < $w; $x++) {
            for ($y = 0; $y < $h; $y++) {
                $rgbColor = imagecolorat($im_final, $x, $y);
                if (((($x - $r) * ($x - $r) + ($y - $r) * ($y - $r)) < ($r * $r))) {
                    imagesetpixel($img, $x, $y, $rgbColor);
                }
            }
        }

        return $img;
//        header("Content-Type:image/png");
//        imagepng($img);
        imagedestroy($im_final);
        imagedestroy($imgSource);
        imagedestroy($im_2);
        imagedestroy($im_3);
    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值