包子

木森技术分享

路漫漫其修远兮,吾将上下而求索。

您现在的位置是:网站首页 > THINKPHP

ThinkPHP5 压缩水印图片后透明背景变成白色背景的问题

2022-04-21 10:32:28625

  需求:在用户上传图片时添加图片水印,水印图大小需要根据用户上传的图片大小变化;

  思路:上传图片时,使用TP5封装好的图片处理类对上传的图片进行添加水印,水印图需要根据上传图片的大小进行适当压缩;

  问题:水印图压缩之后,原本透明底变成白色底;

  解决:小改tp5封装的图片处理类的压缩方法;

  过程:定位至:thinkphp\labrary\think-image\src->crop() 方法(我们用到的thumb()方法最后还会经过该方法处理)

// 调整默认颜色
$color = imagecolorallocate($img, 255, 255, 255);

  改成:

// 调整默认颜色
// $color = imagecolorallocate($img, 255, 255, 255);
$color = imagecolorallocatealpha($img, 0, 0, 0, 127);

1.png

  成功将将透明底色的图片加印至上传图...

  补充详细过程:

  1. 封装通用上传方法:

    /**
     * 单图上传
     * @param   string  $dir        保存在upload文件夹下的目录
     * @param   bool    $is_thumb   是否开启压缩图
     * @param   integer $width      缩略图最大宽度
     * @param   integer $height     缩略图最大高度
     * @param   int      $type      缩略图裁剪类型
     * @return array
     * @throws  Error
     */
    function _upload( $dir="api",$is_water = false,$is_thumb=true,$width=1024,$height=1024,$type=1)
    {
        // 简单校验
        $validate = [
            'size' => 1567800,
            'ext' => 'jpg,gif,png,bmp,jpeg,JPG'
        ];
        // 上传
        if ($file = request()->file('file')) {
            // 保存路径
            $savePath = ROOT_PATH . 'upload' . DS . $dir . DS . date('Ym') . DS . date('d') . DS ;
            // 访问路径
            $_file_path = ROOT_DIR . 'upload/' . $dir . '/' . date('Ym/d/');
            // 创建目录
            !is_dir($savePath) && mkdir(iconv("UTF-8", "GBK", $savePath),0777,true);
            // 移动文件
            $info = $file->rule('uniqid')->validate($validate)->move($savePath);
 
            if ($info) {
 
                // 压缩图片
                $savePath = $savePath . $info->getSaveName();
                $is_thumb && \think\Image::open($savePath)->thumb($width, $height, $type)->save($savePath);
 
                // 添加水印
                if(true == $is_water){
                    // 自适应logo图
                    $image = \think\Image::open($savePath);
                    $logo_width = $image->width()/4;
                    $logo_height = $image->height()/4;
                    // 原水印路径
                    $logo_img = config('api.water_logo');
                    // 临时水印路径
                    $temp_logo = ROOT_PATH.'upload/temp_'.uniqid().'.png';
                    \think\Image::open($logo_img)->thumb($logo_width, $logo_height)->save($temp_logo);
 
                    // 加水印
                    $image->water($temp_logo,9,60)->save($savePath);
                    // 销毁临时水印
                    file_exists($temp_logo) && unlink($temp_logo);
                }
 
                $_file = $_file_path . str_replace('\\', '/', $info->getSaveName());
 
                return [
                    'code' => 1,
                    'msg' => '上传成功',
                    'data' => $_file
                ];
 
            } else {
                // 上传失败获取错误信息
                throw new Error($file->getError(), 47002);
            }
        } else {
            throw new Error('上传失败,请检查参数', 47001);
        }
    }

  2 . 测试调用:

    public function test(){
       $rs = _upload('test',true);
       dump($rs);
    }

  3 . 查看结果:

1.png

1.png

  上传的结果图已经成功添加水印,但是,原本透明底的水印图变成的白底,那是因为tp5在处理图片压缩时会创建一张白底的图片,然后使用imagecopyresampled进行拷贝:

  4 . 处理:

  为了兼容默认用法,建议使用传参的方式进行控制:

$color = imagecolorallocate($img, 255, 255, 255);
// $is_alpha为自定义参数,默认false
if(true === $is_alpha){
    $color = imagecolorallocatealpha($img, 0, 0, 0, 127);
}