原生PHP上传图片并且裁剪图片生成推广海报

<?php

ini_set('memory_limit', '-1');
/**
 *生成宣传海报
 * @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,
        'right' => 0,
        'bottom' => 0,
        'width' => 100,
        'height' => 100,
        'opacity' => 100
    );

    $textDefault = array(
        'text' => '',
        'left' => 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,
                $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);
    }
}


/**
 * 裁剪圆角
 * @param string $imgpath
 * @param int $radius
 * @return false|GdImage|resource
 */
function radius_img($imgpath = 'image/ditu.jpg', $radius = 15) {
    $ext     = pathinfo($imgpath);
    $src_img = null;
    switch ($ext['extension']) {
        case 'jpg':
//            $src_img = imagecreatefromjpeg($imgpath);
            $src_img = imagecreatefromstring(file_get_contents($imgpath));
            break;
        case 'png':
//            $src_img = imagecreatefrompng($imgpath);
            $src_img = imagecreatefromstring(file_get_contents($imgpath));
            break;
        default:
            $src_img = imagecreatefromstring(file_get_contents($imgpath));
            break;
    }
    $wh = getimagesize($imgpath);
    $w  = $wh[0];
    $h  = $wh[1];
    // $radius = $radius == 0 ? (min($w, $h) / 2) : $radius;
    $img = imagecreatetruecolor($w, $h);
    //这一句一定要有
    imagesavealpha($img, true);
    //拾取一个完全透明的颜色,最后一个参数127为全透明
    $bg = imagecolorallocatealpha($img, 255, 255, 255, 127);
    imagefill($img, 0, 0, $bg);
    $r = $radius; //圆 角半径
    for ($x = 0; $x < $w; $x++) {
        for ($y = 0; $y < $h; $y++) {
            $rgbColor = imagecolorat($src_img, $x, $y);
            if (($x >= $radius && $x <= ($w - $radius)) || ($y >= $radius && $y <= ($h - $radius))) {
                //不在四角的范围内,直接画
                imagesetpixel($img, $x, $y, $rgbColor);
            } else {
                //在四角的范围内选择画
                //上左
                $y_x = $r; //圆心X坐标
                $y_y = $r; //圆心Y坐标
                if (((($x - $y_x) * ($x - $y_x) + ($y - $y_y) * ($y - $y_y)) <= ($r * $r))) {
                    imagesetpixel($img, $x, $y, $rgbColor);
                }
                //上右
                $y_x = $w - $r; //圆心X坐标
                $y_y = $r; //圆心Y坐标
                if (((($x - $y_x) * ($x - $y_x) + ($y - $y_y) * ($y - $y_y)) <= ($r * $r))) {
                    imagesetpixel($img, $x, $y, $rgbColor);
                }
                //下左
                $y_x = $r; //圆心X坐标
                $y_y = $h - $r; //圆心Y坐标
                if (((($x - $y_x) * ($x - $y_x) + ($y - $y_y) * ($y - $y_y)) <= ($r * $r))) {
                    imagesetpixel($img, $x, $y, $rgbColor);
                }
                //下右
                $y_x = $w - $r; //圆心X坐标
                $y_y = $h - $r; //圆心Y坐标
                if (((($x - $y_x) * ($x - $y_x) + ($y - $y_y) * ($y - $y_y)) <= ($r * $r))) {
                    imagesetpixel($img, $x, $y, $rgbColor);
                }
            }
        }
    }
    return $img;
}

/**
 * 上传图片
 */
function uploads()
{
    $filename=$_FILES['file']['name'];//上传的文件名字,myFile为约定键名,前端与后端要一致
    if($filename=='' || empty($filename)){
        echo returnJson(402,'接收的文件为空');die;
    }
    $type_name=substr(strrchr($filename, '.'), 1);//获取文件名后缀
    //如果不是jpg或者png的后缀,则返回错误值
    if($type_name!='jpg' && $type_name!='png' && $type_name!='jpeg' ){
        echo returnJson(402,'请上传jpg,png,jpeg格式的文件');die;
    }
    $tmp_name=$_FILES['file']['tmp_name'];//文件地址,储存的临时文件名
    $error=$_FILES['file']['error'];//状态
    //保存于服务器的路径,文件名为时间戳+格式名
    $path = 'uploads/image/'.date('Ymd');
    if(!mkdirs($path)){
        echo returnJson(402,'文件夹创建失败');die;
    }
    $str_name = time().'.'.$type_name;
    $save_name = $path.'/'.$str_name;
    move_uploaded_file($tmp_name, $save_name);//保存图片
    if ($error==0) {
        $size_src=getimagesize($save_name);
        $h=$size_src['1'];
        $max=840;
        $w=$max;
        $h=$h*($max/$size_src['0']);
        //压缩图片
        $src = getThumb($str_name,$save_name,$w,$h);
        if(!file_exists($src)){
            var_dump('图片失效');
            die;
        }
        //裁剪图片
        imagecropper($src,840,1210);
        //设置圆角
        $imgg = radius_img($src, 100);
        imagegif($imgg, $src);
        $paths = 'uploads/synthetic/'.date('Ymd');
        if(!mkdirs($paths)){
            echo returnJson(402,'文件夹创建失败');die;
        }
        $data = hecheng($paths,$src);
        echo returnJson(200,'上传成功',$data);die;
    }else{
        $str = '上传失败';
        //这些报错在配置文件里修改
        switch ($error){
            case 1:
                $str = "超过了上传文件的最大值,请上传2M以下文件";
                break;
            case 2:
                $str = "上传文件过多,请一次上传20个及以下文件!";
                break;
            case 3:
                $str = "文件并未完全上传,请再次尝试!";
                break;
            case 4:
                $str = "未选择上传文件!";
                break;
            case 5:
                $str = "上传文件为0";
                break;
        }
        echo returnJson(402,$str);die;
    }
}
function mkdirs($dir, $mode = 0777){
    if (is_dir($dir) || @mkdir($dir, $mode)) return TRUE;
    if (!mkdirs(dirname($dir), $mode)) return FALSE;
    return @mkdir($dir, $mode);
}

function returnJson($code,$msg,$data = '')
{
    $arr = [
        'code' => $code,
        'msg' => $msg,
        'data' => $data,
    ];
    return json_encode($arr);
}

function hecheng($paths,$images)
{
    $size_src=getimagesize($images);
    $h=$size_src['1'];
    if($h > 1210){
        $h = 1210;
    }

    //示例一:生成带有二维码的海报
    $config = array(
        'image' => array(
            array(
                'url' => 'image/ewcode.png',     //二维码资源
                'stream' => 0,
                'left' => 930,
                'top' => 90,
                'right' => 0,
                'bottom' => 0,
                'width' => 178,
                'height' => 178,
                'opacity' => 100
            ),
            array(
                'url' => $images,
                'stream' => 0,
                'left' => 185,
                'top' => 420,
                'right' => 0,
                'bottom' => 0,
                'width' => $size_src[0],
                'height' => $h,
                'opacity' => 100
            )
        ),
        'background' => 'image/dit.jpg'          //背景图
    );

    $filename = $paths.'/' . time() . '.png';
    return createPoster($config,$filename);
}

/**

 * 图片压缩处理

 * @param string $sFile 图片路径

 * @param int $iWidth 自定义图片宽度

 * @param int $iHeight 自定义图片高度

 */

function getThumb($name,$sFile,$iWidth,$iHeight){
    //判断该图片是否存在
    if(!file_exists($sFile)) return $sFile;

    //压缩图片
    $sFileNameS = str_replace($name, 's_'.$name, $sFile);
    //判断是否已压缩图片,若是则返回压缩图片路径
    if(file_exists($sFileNameS)){
        return $sFileNameS;
    }
    //生成压缩图片,并存储到原图同路径下
    resizeImage($sFile, $sFileNameS, $iWidth, $iHeight);
    if(!file_exists($sFileNameS)){
        return $sFile;
    }
    return $sFileNameS;
}


/**
 * 生成图片
 * @param string $im 源图片路径
 * @param string $dest 目标图片路径
 * @param int $maxwidth 生成图片宽
 * @param int $maxheight 生成图片高
 */

function resizeImage($im, $dest, $maxwidth, $maxheight) {
    $img = getimagesize($im);
    switch ($img[2]) {
        case 1:
            $im = @imagecreatefromgif($im);
            break;
        case 2:
            $im = @imagecreatefromjpeg($im);
            break;
        case 3:
            $im = @imagecreatefrompng($im);
            break;
    }
    $pic_width = imagesx($im);
    $pic_height = imagesy($im);
    $resizewidth_tag = false;
    $resizeheight_tag = false;
    if (($maxwidth && $pic_width > $maxwidth) || ($maxheight && $pic_height > $maxheight)) {
        if ($maxwidth && $pic_width > $maxwidth) {
            $widthratio = $maxwidth / $pic_width;
            $resizewidth_tag = true;
        }

        if ($maxheight && $pic_height > $maxheight) {
            $heightratio = $maxheight / $pic_height;
            $resizeheight_tag = true;
        }
        if ($resizewidth_tag && $resizeheight_tag) {
            $ratio = $widthratio;
        }
        if ($resizewidth_tag && !$resizeheight_tag)
            $ratio = $widthratio;
        if ($resizeheight_tag && !$resizewidth_tag)
            $ratio = $widthratio;
            $newwidth = $pic_width * $ratio;
            $newheight = $pic_height * $ratio;
        if (function_exists("imagecopyresampled")) {
            $newim = imagecreatetruecolor($newwidth, $newheight);
            imagecopyresampled($newim, $im, 0, 0, 0, 0, $newwidth, $newheight, $pic_width, $pic_height);
        } else {
            $newim = imagecreate($newwidth, $newheight);
            imagecopyresized($newim, $im, 0, 0, 0, 0, $newwidth, $newheight, $pic_width, $pic_height);
        }
        imagejpeg($newim, $dest);
        imagedestroy($newim);
    } else {
        if ($maxwidth && $pic_width < $maxwidth) {
            $widthratio = $maxwidth / $pic_width;
            $resizewidth_tag = true;
        }
        if ($maxheight && $pic_height < $maxheight) {
            $heightratio = $maxheight / $pic_height;
            $resizeheight_tag = true;
        }
        if ($resizewidth_tag && $resizeheight_tag) {
            $ratio = $widthratio;
        }
        if ($resizewidth_tag && !$resizeheight_tag)
            $ratio = $widthratio;
        if ($resizeheight_tag && !$resizewidth_tag)
            $ratio = $widthratio;
            $newwidth = $pic_width * $ratio;
            $newheight = $pic_height * $ratio;
        if (function_exists("imagecopyresampled")) {
            $newim = imagecreatetruecolor($newwidth, $newheight);
            imagecopyresampled($newim, $im, 0, 0, 0, 0, $newwidth, $newheight, $pic_width, $pic_height);
        } else {
            $newim = imagecreate($newwidth, $newheight);
            imagecopyresized($newim, $im, 0, 0, 0, 0, $newwidth, $newheight, $pic_width, $pic_height);
        }
        imagejpeg($newim, $dest);
        imagedestroy($newim);
    }
}


/**
 * 图像裁剪
 * @param $title string 原图路径
 * @param $content string 需要裁剪的宽
 * @param $encode string 需要裁剪的高
 */
function imagecropper($source_path, $target_width, $target_height)
{
    $source_info = getimagesize($source_path);
    $source_width = $source_info[0];
    $source_height = $source_info[1];
    $source_mime = $source_info['mime'];
    $source_ratio = $source_height / $source_width;
    $target_ratio = $target_height / $target_width;

// 源图过高
    if ($source_ratio > $target_ratio) {
        $cropped_width = $source_width;
        $cropped_height = $source_width * $target_ratio;
        $source_x = 0;
        $source_y = ($source_height - $cropped_height) / 2;
    } // 源图过宽
    elseif ($source_ratio < $target_ratio) {
        $cropped_width = $source_height / $target_ratio;
        $cropped_height = $source_height;
        $source_x = ($source_width - $cropped_width) / 2;
        $source_y = 0;
    } // 源图适中
    else {
        $cropped_width = $source_width;
        $cropped_height = $source_height;
        $source_x = 0;
        $source_y = 0;
    }

    switch ($source_mime) {
        case 'image/gif':
            $source_image = imagecreatefromgif($source_path);
            break;

        case 'image/jpeg':
            $source_image = imagecreatefromjpeg($source_path);
            break;

        case 'image/png':
            $source_image = imagecreatefrompng($source_path);
            break;

        default:
            return false;
            break;
    }

    $target_image = imagecreatetruecolor($target_width, $target_height);
    $cropped_image = imagecreatetruecolor($cropped_width, $cropped_height);

// 裁剪
    imagecopy($cropped_image, $source_image, 0, 0, $source_x, $source_y, $cropped_width, $cropped_height);
// 缩放
    imagecopyresampled($target_image, $cropped_image, 0, 0, 0, 0, $target_width, $target_height, $cropped_width, $cropped_height);

//保存图片到本地(两者选一)
    $new = imagepng($target_image, $source_path);
    imagedestroy($target_image);
    return true;
}

uploads();
?>

比较长,大家可以借鉴一下,根据需求来使用

最后上个效果图

 引用的两张图片

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奥特曼想做个好人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值