[FastAdmin] 上传图片并加水印,压缩图片

 1.app\common\library\Upload.php 文件

upload方法
    /*** 普通上传* @return \app\common\model\attachment|\think\Model* @throws UploadException*/public function upload($savekey = null){if (empty($this->file)) {throw new UploadException(__('No file upload or server upload limit exceeded'));}$this->checkSize();$this->checkExecutable();$this->checkMimetype();$this->checkImage();$savekey = $savekey ? $savekey : $this->getSavekey();$savekey = '/' . ltrim($savekey, '/');$uploadDir = substr($savekey, 0, strripos($savekey, '/') + 1);$fileName = substr($savekey, strripos($savekey, '/') + 1);$destDir = ROOT_PATH . 'public' . str_replace('/', DS, $uploadDir);$sha1 = $this->file->hash();//如果是合并文件if ($this->merging) {if (!$this->file->check()) {throw new UploadException($this->file->getError());}$destFile = $destDir . $fileName;$sourceFile = $this->file->getRealPath() ?: $this->file->getPathname();$info = $this->file->getInfo();$this->file = null;if (!is_dir($destDir)) {@mkdir($destDir, 0755, true);}rename($sourceFile, $destFile);$file = new File($destFile);$file->setSaveName($fileName)->setUploadInfo($info);} else {$file = $this->file->move($destDir, $fileName);if (!$file) {// 上传失败获取错误信息throw new UploadException($this->file->getError());}}$this->file = $file;$config=Db::name('config')->where(['group'=>'attachment'])->column('value','name');if ($config['open_watermark']){$fontPath = 'assets/fonts/zk.ttf'; // 确保字体文件路径正确,并且该字体支持中文$this->addTextWatermark('.'.$uploadDir . $file->getSaveName(), '.'.$uploadDir . $file->getSaveName(), $fontPath,$config);}//开启图片压缩if ($config['open_thum']){if (in_array($this->fileInfo['type'], ['image/gif', 'image/jpg', 'image/jpeg', 'image/bmp', 'image/png', 'image/webp']) || in_array($this->fileInfo['suffix'], ['gif', 'jpg', 'jpeg', 'bmp', 'png', 'webp'])) {$filesize=filesize('.'.$uploadDir . $file->getSaveName());if ($filesize>200000){$this->compressImage('.'.$uploadDir . $file->getSaveName(),'.'.$uploadDir . $file->getSaveName(),$config['thum_quality']);$imgInfo = getimagesize('.'.$uploadDir . $file->getSaveName());$filesize=filesize('.'.$uploadDir . $file->getSaveName());$this->fileInfo['size']=$filesize;$this->fileInfo['imagewidth'] = $imgInfo[0] ?? 0;$this->fileInfo['imageheight'] = $imgInfo[1] ?? 0;}}}$category = request()->post('category');$category = array_key_exists($category, config('site.attachmentcategory') ?? []) ? $category : '';$auth = Auth::instance();$params = array('admin_id'    => (int)session('admin.id'),'user_id'     => (int)$auth->id,'filename'    => mb_substr(htmlspecialchars(strip_tags($this->fileInfo['name'])), 0, 100),'category'    => $category,'filesize'    => $this->fileInfo['size'],'imagewidth'  => $this->fileInfo['imagewidth'],'imageheight' => $this->fileInfo['imageheight'],'imagetype'   => $this->fileInfo['suffix'],'imageframes' => 0,'mimetype'    => $this->fileInfo['type'],'url'         => $uploadDir . $file->getSaveName(),'uploadtime'  => time(),'storage'     => 'local','sha1'        => $sha1,'extparam'    => '',);$attachment = new Attachment();$attachment->data(array_filter($params));$attachment->save();\think\Hook::listen("upload_after", $attachment);return $attachment;}/*** 压缩图片* @param $sourcePath //需要压缩的图片* @param $targetPath //压缩后的图片* @param $quality //压缩质量* @return bool*/public function compressImage($sourcePath, $targetPath, $quality) {$info = getimagesize($sourcePath);if ($info !== false) {$image = imagecreatefromstring(file_get_contents($sourcePath));imagejpeg($image, $targetPath, $quality); // 质量范围从0(差)到100(好)imagedestroy($image);return true;}return false;}/*** @param $imagePath 原图* @param $outputPath 输出图* @param $text 文字* @param $fontPath 字体路径* @param $fontSize 字体大小* @param $color 字体颜色* @param $position 位置* @return void*/public function addTextWatermark($imagePath, $outputPath, $fontPath, $config) {// 创建图片资源$image = imagecreatefromstring(file_get_contents($imagePath));// 获取图片尺寸list($width, $height) = getimagesize($imagePath);// 设置文字颜色$black = imagecolorallocatealpha($image, 0, 0, 0, 100); // 最后一个参数是透明度,范围从0(完全透明)到127(完全不透明)
//        $textColor = imagecolorallocate($image, hexdec(substr($color, 0, 2)), hexdec(substr($color, 2, 2)), hexdec(substr($color, 4, 2)));// 设置字体路径和大小$font = realpath($fontPath);$fontSize=abs($config['watermark_size']);if (empty($config['watermark_colour'])) {$textColor =imagecolortransparent($image, $black);}else{$rgb=Checking::hColor2RGB($config['watermark_colour']);$black = imagecolorallocatealpha($image, $rgb['r'], $rgb['g'], $rgb['b'], 100); // 最后一个参数是透明度,范围从0(完全透明)到127(完全不透明)$textColor =imagecolortransparent($image, $black);}if (empty($config['watermark_text'])){$text='专用水印';}else{$text=$config['watermark_text'];}$bbox = imagettfbbox($fontSize, 0, $fontPath, $text); // 获取文字的边界框$text_width = $bbox[2] - $bbox[0];$text_height = $bbox[7] - $bbox[1];if (!empty($config['watermark_position'])) {if ($width-$text_width*3>50){$watermark_position=explode(',', $config['watermark_position']);foreach ($watermark_position as $position) {switch ($position) {case 1:imagettftext($image, $fontSize, 0,  ($width - $text_width*3)/4 ,  $height/6 , $textColor, $font, $text);break;case 2:imagettftext($image, $fontSize, 0,  ($width - $text_width*3)/4 ,  $height/6*3 , $textColor, $font, $text);break;case 3:imagettftext($image, $fontSize, 0,  ($width - $text_width*3)/4 ,  $height/6*5 , $textColor, $font, $text);break;case 4:imagettftext($image, $fontSize, 0,  ($width - $text_width*3)/4*2+$text_width,  $height/6 , $textColor, $font, $text);break;case 5:imagettftext($image, $fontSize, 0,  ($width - $text_width*3)/4*2+$text_width,  $height/6*3 , $textColor, $font, $text);break;case 6:imagettftext($image, $fontSize, 0,  ($width - $text_width*3)/4*2+$text_width,  $height/6*5 , $textColor, $font, $text);break;case 7:imagettftext($image, $fontSize, 0,  ($width - $text_width*3)/4*3+$text_width*2,  $height/6 , $textColor, $font, $text);break;case 8:imagettftext($image, $fontSize, 0,  ($width - $text_width*3)/4*3+$text_width*2,  $height/6*3 , $textColor, $font, $text);break;case 9:imagettftext($image, $fontSize, 0,  ($width - $text_width*3)/4*3+$text_width*2,  $height/6*5 , $textColor, $font, $text);break;}}}}// 保存图片imagejpeg($image, $outputPath);imagedestroy($image);}
    /*** 颜色转换 16进制转rgb* @param $hexColor* @return array*/public static function hColor2RGB($hexColor){$color = str_replace('#', '', $hexColor);if (strlen($color) > 3) {$rgb = array('r' => hexdec(substr($color, 0, 2)),'g' => hexdec(substr($color, 2, 2)),'b' => hexdec(substr($color, 4, 2)));} else {$color = str_replace('#', '', $hexColor);$r = substr($color, 0, 1) . substr($color, 0, 1);$g = substr($color, 1, 1) . substr($color, 1, 1);$b = substr($color, 2, 1) . substr($color, 2, 1);$rgb = array('r' => hexdec($r),'g' => hexdec($g),'b' => hexdec($b));}return $rgb;}

 数据库配置

颜色选择器添加,请参考之前的文章

【FastAdmin】在页面中使用layui,以此引申使用颜色选择器示例-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/16726.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

windows系统远程桌面连接ubuntu18.04

记录一下自己在配置过程中遇到的问题,记录遇到的两大坑: windows系统通过xrdp远程桌面连接ubuntu18.04的蓝屏问题。参考以下第一章解决。 同一局域网内网段不同的连接问题。参考以下第三章解决,前提是SSH可连。 1. 在ubuntu上安装xrdp 参考&…

逻辑回归不能解决非线性问题,而svm可以解决

逻辑回归和支持向量机(SVM)是两种常用的分类算法,它们在处理数据时有一些不同的特点,特别是在面对非线性问题时。 1. 逻辑回归 逻辑回归本质上是一个线性分类模型。它的目的是寻找一个最适合数据的直线(或超平面&…

23页PDF | 国标《GB/T 44109-2024 信息技术 大数据 数据治理实施指南 》发布

一、前言 《信息技术 大数据 数据治理实施指南》是中国国家标准化管理委员会发布的关于大数据环境下数据治理实施的指导性文件,旨在为组织开展数据治理工作提供系统性的方法和框架。报告详细阐述了数据治理的实施过程,包括规划、执行、评价和改进四个阶…

ESM3(1)-介绍:用语言模型模拟5亿年的进化历程

超过30亿年的进化在天然蛋白质空间中编码形成了一幅生物学图景。在此,作者证明在进化数据上进行大规模训练的语言模型,能够生成与已知蛋白质差异巨大的功能性蛋白质,并推出了ESM3,这是一款前沿的多模态生成式语言模型,…

在大型语言模型(LLM)框架内Transformer架构与混合专家(MoE)策略的概念整合

文章目录 传统的神经网络框架存在的问题一. Transformer架构综述1.1 transformer的输入1.1.1 词向量1.1.2 位置编码(Positional Encoding)1.1.3 编码器与解码器结构1.1.4 多头自注意力机制 二.Transformer分步详解2.1 传统词向量存在的问题2.2 详解编解码…

【黑马点评】 使用RabbitMQ实现消息队列——3.批量获取1k个用户token,使用jmeter压力测试

【黑马点评】 使用RabbitMQ实现消息队列——3.批量获取用户token,使用jmeter压力测试 3.1 需求3.2 实现3.2.1 环境配置3.2.2 修改登录接口UserController和实现类3.2.3 测试类 3.3 使用jmeter进行测试3.4 测试结果3.5 将用户登录逻辑修改回去3.6 批量删除生成的用户…

【安全靶场】信息收集靶场

靶场:https://app.hackinghub.io/hubs/prison-hack 信息收集 子域名收集 1.subfinder files.jabprisons.com staging.jabprisons.com cobrowse.jabprisons.com a1.top.jabprisons.com cf1.jabprisons.com va.cobrowse.jabprisons.com vs.jabprisons.com c…

springboot239-springboot在线医疗问答平台(源码+论文+PPT+部署讲解等)

💕💕作者: 爱笑学姐 💕💕个人简介:十年Java,Python美女程序员一枚,精通计算机专业前后端各类框架。 💕💕各类成品Java毕设 。javaweb,ssm&#xf…

(一)获取数据和读取数据

获取公开数据 下载、爬虫、API 一些公开数据集网站: 爬虫: 发送请求获取网页源代码——解析网页源代码内容,提取数据 通过公开API获取: API定义了两个程序之间的服务合约,即双方是如何使用请求和响应来进行通讯的…

在MacBook Air上本地部署大模型deepseek指南

随着大模型技术的兴起,越来越多的人开始关注如何在本地部署这些强大的AI模型。如果你也想体验大模型的魅力,那么这篇文章将指导你如何在你的MacBook Air上本地部署大模型. 工具准备 为了实现本地部署,你需要以下工具: Ollama&a…

Windows中使用Docker安装Anythingllm,基于deepseek构建自己的本地知识库问答大模型,可局域网内多用户访问、离线运行

文章目录 Windows中使用Docker安装Anythingllm,基于deepseek构建自己的知识库问答大模型1. 安装 Docker Desktop2. 使用Docker拉取Anythingllm镜像2. 设置 STORAGE_LOCATION 路径3. 创建存储目录和 .env 文件.env 文件的作用关键配置项 4. 运行 Docker 命令docker r…

git学习【个人记录b站尚硅谷】

git学习 Git基本命令操作设置用户签名初始化本地库添加文件从工作区到暂存区将文件从暂存区添加到本地库修改文件重新提交 Git分支Github操作创建远程库上传到远程库克隆到本地文件夹拉取远程库最新版本到本地 总结 Git基本命令操作 设置用户签名 git config --global user.n…

【R语言】t检验

一、基本介绍 t检验(t-test)是用于比较两个样本均值是否存在显著差异的一种统计方法。 t.test()函数的调用格式: t.test(x, yNULL, alternativec("two.sided", "less", "greater"), mu0, pairFALSE, var.eq…

TDengine 产品由哪些组件构成

目 录 背景产品生态taosdtaosctaosAdaptertaosKeepertaosExplorertaosXtaosX Agent应用程序或第三方工具 背景 了解一个产品,最好从了解产品包括哪些内容开始,我这里整理了一份儿 TDegnine 产品包括有哪些组件,每个组件作用是什么的说明&a…

实现限制同一个账号最多只能在3个客户端(有电脑、手机等)登录(附关键源码)

如上图,我的百度网盘已登录设备列表,有一个手机,2个windows客户端。手机设备有型号、最后登录时间、IP等。windows客户端信息有最后登录时间、操作系统类型、IP地址等。这些具体是如何实现的?下面分别给出android APP中采集手机信…

使用 Docker 安装 Open WebUI 并集成 Ollama 的 DeepSeek 模型

文章目录 使用 Docker 安装 Open WebUI 并集成 Ollama 的 DeepSeek 模型前提条件1. 安装ollama2. 拉取deepseek的模型3. Open-WebUI 说明4. 启动容器文档的方法如下优化命令(可选)1. 增加了健康检查机制(--health-cmd)2. 使 WebUI…

Untiy3d 铰链、弹簧,特殊的物理关节

(一)铰链组件 1.创建一个立方体和角色胶囊 2.给角色胶囊挂在控制脚本和刚体 using System.Collections; using System.Collections.Generic; using UnityEngine;public class plyer : MonoBehaviour {// Start is called once before the first execut…

【NLP 21、实践 ③ 全切分函数切分句子】

当无数个自己离去,我便日益坦然 —— 25.2.9 一、jieba分词器 Jieba 是一款优秀的 Python 中文分词库,它支持多种分词模式,其中全切分方式会将句子中所有可能的词语都扫描出来。 1.原理 全切分方式会找出句子中所有可能的词语组合。对于一…

团结引擎 OpenHarmony 平台全面支持 UAAL,实现引擎能力嵌入原生应用

团结引擎1.4版本已于近日正式发布!在这一版本中,OpenHarmony 平台迎来了一个具有里程碑意义的更新:全面支持 Used as a Library(UAAL)。UAAL 这一技术方案,具有将引擎嵌入原生应用的独特能力,其…

自己部署DeepSeek 助力 Vue 开发:打造丝滑的标签页(Tabs)

前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏关注哦 💕 目录 自己…