ThinkPHP自动化为已经上传的图片添加「 响应式」水印(数据库字段部分)
版权属于: Postbird - There I am , in the world more exciting!
原文地址: http://www.ptbird.cn/thinkphp-image-water-sql/
转载时必须以链接形式注明原始出处及本声明。
TPImageWater 是ThinkPHP扩展的用来自动化为已经上传部分图片加水印的应用
这是第二部分,也就是从数据库中读取图片存储地址的字段内容,来实现图片添加水印。
如果想看之前的部分请参照:
在1的基础上,根据客户的需求,进行一个完善,具体的使用方法和原理介绍主要在第二篇文章以及代码中的注释(这估计是我写的最多的注释了)
1、ThinkPHP为已经上传的图片添加水印的插件【原始版本】
2、ThinkPHP自动化为已经上传的图片添加「 响应式」水印(文件遍历部分)
应用思想来源:
本来之前写了遍历文件夹方法来为所有的图片添加【响应式水印】,所谓响应式就是根据标准图片的大小,标准水印的大小和位置,自动化处理文件夹内的所有图片,以达到水印位置和大小符合实际不同图片大小的要求。
基于遍历文件夹的方法存在的问题,也就是客户的最新要求:只处理上传的产片图片,一些文章中的杂七杂八的图片不需要添加水印。
因为系统设计过程中,图片上传基本是以时间点为文件夹,并不区分图片的分类。
所以从数据库中读取字段值是一个很不错的方法。
关键解决:
1、需要处理的图片不一定只在一张表中的一个字段,因此需要准备多个字段的处理。
2、文件遍历方法中,我们需要遍历文件夹的所有内容,并进行相关的图片文件的筛选,但是从数据库读取字段,主要面临的问题是数据库字段中独处的数据能否直接用于图片地址的读取,而且可能存在空值
例如:我在应用的过程中,数据库中存的形式如下【/Uploads/image/20150911/55f2424d5a54d.jpg】
因此需要对字段进行处理,而在代码中,循环的时候预留了处理的代码空间,可以根据实际上自己的需求进行处理。
关键算法:
1、为了实现多个数据库字段内容的读取,我设计的第一个参数是数组,主要的实现也在代码的注释中(代码注释是一切)。
2、(重复一下之前文章提到的水印算法)
因为需要根据标准图片的大小和水印图片的大小以及位置计算出实际上水印图片的大小和位置,因此需要每次计算和生成新的水印并添加到图片中。
由于thinkphp本身的性质,我们每次对水印图片也就是【water.jpg】进行处理生成新的【tmpWater.jpg】,每次都采用覆盖形式的处理,所以到最后处理完成结束了,只会多一张【tmpwater.jpg】,而没有其他的变化。
提提之前文章的内容:
之前文章也就是【文件遍历部分】主要介绍了实现响应式水印的关键算法。
其中也提到了,ThinkPHP3.2实际上已经支持locate(x,y)的参数,也就是根据横纵坐标实现水印图片的位置,不是像官方手册介绍的只有那几种方法。我也不知道为什么手册不更新。
TPImageWater实现的效果:
代码查看(文件遍历和sql数据库字段整合在一起):
下面代码可能输出过程中html标签替代问题,建议直接下载gitosc或者是github的源码查看
码云:https://git.oschina.net/postbird/TPImageWater
github:https://github.com/postbird/TPImageWater.git
/* * * 使用thinkphp 循环为已经上传的图片添加水印 * * 从数据库读出部分图片的地址并转换成本地地址进行操作 * 从数据库中读图片,省去了遍历和筛选过滤的环节 * 相比遍历出来在进行比对,相对快速和方便 * 最终的函数没有本质的区别,只有参数变化了。 * 详细请看参数注释 * * by postbird * * http://www.ptbird.cn * * 2016-10-21 * * license MIT * */ namespace Home\Controller; use Think\Controller;//处理速度让人崩溃200张要30s //因此需要设置最大执行时间为无限 ini_set('max_execution_time','0');class SqlImageWaterController extends Controller {//禁止随便访问//访问的时候后面必须加上该字段的参数值public function check($code){$key="postbird";if(md5($key)!=md5($code)){return false;}else{return true;}}public function index(){$code=$_GET['code'];if(!$this->check($code)){echo "no such file";return;exit();die;}//两个参数 第一个是要处理的文件地址的合辑//从数据库中读取文件地址,可能不是操作一个表,因此需要将表和要读取的字段名称作为数组参数传递//第二个是水印图片的本地地址//我要处理三张表 每张表取出图片字段//数据库已经配置了表前缀//默认的存储形式是 /Uploads/image/20150920/55fe9a083ca65.jpg //因为我前面没有 . ,所以在后面进行处理的时候每张图片的前面加了.// 需要根据数据库字段进行设置 参照113-116行代码,在这里面设置就可以$imgSqlArr=array();$imgSqlArr[0]['table']='article_page';$imgSqlArr[0]['field']='cover';$imgSqlArr[1]['table']='item';$imgSqlArr[1]['field']='img';$imgSqlArr[2]['table']='item_img';$imgSqlArr[2]['field']='img';$this->imageWater($imgSqlArr,'./Uploads/water.jpg');$this->display();}//替换得到所有图片//返回数组,需要对数组进行组合 public function getImgBySql($imgSqlArr){//因为不确定处理几张表,因此每次都组合一次数组//要返回的结果$res=array();for($i=0;$i<count($imgSqlArr);$i++){ $tmpRes[$i]=array(); //返回需要的列的数据 $tmpRes[$i]=M($imgSqlArr[$i]['table'])->getField($imgSqlArr[$i]['field'],true);$res=array_merge($res,$tmpRes[$i]);}//返回数据 但是里面数据可能存在空值 空值需要跳过// p($res);exit();return $res;}//进行水印处理// 参数是 文件sql数组-imgSqlArr water// water是水印的位置public function imageWater($imgSqlArr,$water){if(!is_array($imgSqlArr)){echo"参数只能为数组";die;}//得到所有需要处理的图片$images=$this->getImgBySql($imgSqlArr);p($images);//使用Image类$Image = new \Think\Image(); //水印位置是存放在根目录下 water.png 可以根据自己需要改//设置临时的水印文件与water.png在同一目录,为了图省事可以放在根目录//下面使用分割拼接主要是为了通用性,可以根据实际的文件夹要求直接写死//现在的做法是将water.png分出来,再把water截取后面water.png的长度,就是目录//截取的前几位字符串接上tmpWater.png就是字符串$tmpWaterArr=explode("/",$water);$tmpWater="tmpWater.jpg";$tmpWater=substr($water, 0,strlen($tmpWaterArr[count($tmpWaterArr)-1])+1).$tmpWater;// 上面表达式的应用从 "./Uploads/water.png" 又生成 "./Uploads/tmpWater.png"// 从而实现了响应式的临时水印的位置,当然如果嫌麻烦直接根目录也没啥//因为是默认覆盖源文件的,因此即使每次生成tmpwater.png,最后也只会多处一张图片//循环遍历图片,并进行操作for($i=0;$i<count($images);$i++){ //判断数据库的空值进行跳过 if(strlen($images[$i])==0){ continue; }else{ //有了就不需要了 //我的数据库里面字段存的时候没有. //所以需要在这里操作一下 $images[$i]=".".$images[$i]; } //同样保存到文件中的过程中需要进行 转码成GB2312 $images[$i] = iconv('UTF-8','GB2312',$images[$i]); //打开原图片默认添加水印到左上角 并保存为原来位置和名称 自动覆盖 //因为每个图片的大小不确定,因此需要根据图片大小进行位置的确定 //关于水印位置和选项可以参照 thinkphp3.2 手册 // http://document.thinkphp.cn/manual_3_2.html#image $imageInfo=$Image->open($images[$i]);//标准图片宽度和高度$bw=430;$bh=430;//标准的水印大小$bww=130;$bwh=50;//标准的水印距离标准的图片的右方和下方间距//(总是以水印左上角为起点)$bsubw=30;$bsubh=80;//因此可以得出标准的水印的位置应该是$bpx=$bw-$bww-$bsubw;//270$bpy=$bh-$bwh-$bsubh;//300//获取实际图片(打开的图片)的大小$imgw=$imageInfo->width();$imgh=$imageInfo->height();//实际水印的大小根据距离的位置($bsub*)与图片($b*)的比例计算出来$ww=round($bww*($imgw/$bw));$wh=round($bwh*($imgh/$bh));//先前没有考虑实际上距离的位置也应随着图片大小的变化而变化$subw=round($bsubw*($imgw/$bw));$subh=round($bsubh*($imgh/$bh));//【正确】实际水印的位置按照之前的预算,距离底部和右边的距离理论上是不变的,// 这样子才能维持原来水印的位置,只不过现在水印的大小变了$px=$imgw-$ww-$subw;$py=$imgh-$wh-$subh;//水印location的位置$location=array($px,$py);//计算水印的大小 生成缩略图//大小是根据上面的比例算出来的//这里要用到我们上面截取生成的临时水印的文件//这个处理是为了解决thinkphp再上传保存后$tmpWater就不是string类型//因此找了一个临时变量来处理$tmpStr=$tmpWater;$Image->open($water)->thumb($ww, $wh,\Think\Image::IMAGE_THUMB_FILLED)->save($tmpStr);//这里本来写了再次打开tmpWater//thinkphp的机理就是save函数调用后,tmpWater自动成为Iamge的对象//因此不需要打开//测试最后的各个图片的大小和位置// echo("标准 图片 ".$bw." ".$bh." "." 水印 ".$bww." ".$bwh." 位置 ".$bpx." ".$bpy." ");// echo("现在 图片 ".$imgw." ".$imgh." "." 水印 ".$ww." ".$wh." 位置 ".$px." ".$py." ");// exit();//目前使用的水印就是上面生成的比例大小的水印文件//water的第一个参数是字符串类型的//这里我本来使用了imageInfo,因为之前已经打开过一张了//但是发现每次保存都保存成为现在的水印图片//不知道什么原因,无奈只能重新打开和保存if($Image->open($images[$i])->water($tmpWater,$location,80)->save($images[$i])){echo "< p >成功处理第".$i."张图片...";}}echo "< hr >< h1 >图片处理完成....< h1 >";echo "powered by < a href='http://www.ptbird.cn' >postbird ";} }
ThinkPHP自动化为已经上传的图片添加「 响应式」水印(数据库字段部分)相关推荐
- php上传图片到文件夹,2018.09.14PHP获取页面上传的图片存到指定文件夹再存到数据库中...
一.html代码 //传值方式必须是post 请选择要上传的文件: 二.php代码 session_start(); include 'mysql.php'; //获取图片所有的属性 $filenam ...
- WordPress彻底禁用上传媒体图片自动生成缩略图及多尺寸图片(亲测可用)
WordPress默认上传图片的时候会自动生成缩略图及多尺寸的图片文件,大部分网站都用不到这些多余的图片,不仅仅占用空间,而且上传的时候还会消耗额外的性能. 下面仅需两段函数代码即可彻底禁用该功能. ...
- php图片传入及改名代码,WordPress上传中文名图片自动重命名
这几天用Wordpress搭建了一个图片站,在填充内容时遇到一个问题当我在媒体库中上传图片时有些图片可以正常显示,但是个别图片就是显示不出来缩略图,这个问题着实让我纠结了一下午.没办法查找原因少不了研 ...
- Django搭建个人博客:上传头像图片
到目前为止我们的博客处理的都是文字.现代互联网早就进入了"读图"时代,图片的维护.展示也就相当重要. 上一章中预留了avatar字段,用来保存用户上传的头像,现在我们来实现这个功能 ...
- java 图片服务器 上传_Java实现把图片上传到图片服务器(nginx+vsftp)
前言: 在我另一篇笔记中已经记载了如何用nginx + vsftp搭建图片服务器(请参考nginx + vsftp搭建图片服务器),并且用vsftp的客户端工具filezilla测试过已经可用.但是在 ...
- 大华sdk(java)上传人脸图片到人脸库,订阅人脸识别对比
上传人脸图片到人脸库 controller: @RestController @RequestMapping("/facePicture") public class FacePi ...
- 菜鸟的springboot项目图片上传及图片路径分析
菜鸟的springboot项目图片上传及图片路径分析 说明 一.图片路径分析 二.实现图片上传 (1)单文件上传(非异步) (2)单文件上传(异步) 三.总结 四.更新配置文件 说明 更新时间:202 ...
- springboot实现图片上传和图片删除
图片上传主要将需要上传的图片上传到对应的存储地址当中,再通过url访问图片就可以了:本文存储地址在本地,如果是在服务器上,配置服务器端的地址就可以了. controller @ApiOperation ...
- eclipse关于图片上传,图片不显示,tomcat路径问题
tomcat的上传虚拟路径问题,图片上传,网页端图片不显示 本人使用Eclipse进行导入web项目时,项目中的图片上传成功,数据库端也有图片上传路径,但是在网页上显示不出来. 图片上传成功,在控制台 ...
最新文章
- java监听器定时删除,java监听器定时删除服务器上的文件
- Dijkstra的算法
- ubuntu-15.10-server-i386.iso 安装 Oracle 11gR2 数据库
- 翻译:Single Sign-On for Everyone
- 我都不敢信了 东芝芯片“又”将最后决定
- 安装部署Exchange Server 2010 CAS NLB MailBox DAG
- SAP Spartacus checkout Shipping address的页面实现
- Java中的ThreadPoolExecutor类
- python 收发邮件_python发送各类邮件的主要基本方法
- go int64转string_go常见问题收录
- Weblogic 10.3.5在64位Windows系统下的安装和配置
- 一个DirectSound的例子
- SD-WAN平台ActiveCore推出,领域新亮点精彩丰呈
- mysql cluster 乱码_Mysql中文乱码问题完美解决方案
- LaTeX —— 特殊符号与数学字体
- Linux的哲学思想
- 关于perl6的若干问题?
- word中 设置标题级别 的 快捷键
- 什么软件测试显示器响应时间准,一般人我不告诉他!显示器响应速度揭秘
- Win7 + VirtualBox安装Mac OS X雪豹操作系统图文详解[转]