GD库使用小结---2,gd小结---2
接着上一篇。GD库可以折腾很多用法出来,当然得跟画图相关,除了前面的验证码、水印外,还可以进行图片的缩放,裁剪、旋转等操作,这在很多应用中可以见到。
1. 加水印
前面已经知道,我们可以使用imagechar或者imagestring等将字符或字符串(甚至中文字符)绘制到图像上,以达到水印的目的,还有个更好的方式,不仅能加字符水印,还能加图片水印:imagecopy。
原型:bool imagecopy (resource $dst_im , resource $src_im , int $dst_x , int $dst_y , int $src_x , int $src_y , int $src_w , int $src_h),看名字知道这是复制,第1、2个参数分别是目标图像句柄、源文件句柄,加水印时,如果水印图片是一张小图,加在一张大图上面,那么第一个参数就是大图句柄,第二个参数就是小图句柄。第3、4个参数是水印在目标图像上的x、y坐标值,第5、6个参数是水印图片上开始的x、y坐标值,第7、8个参数是水印图片即将要作为水印的宽和高,因此这个方法的意思就是,将水印图像src_im上左上角顶点坐标为(src_x, src_y)处,宽和高分别为src_w、src_h的部分复制到图像dst_im上,再将这个dst_im图像画到画布上保存或输出,即为加过水印后的图片了,代码:
<?<span>php date_default_timezone_set(</span>'Asia/Shanghai'<span>); </span><span>define</span>('DS',<span> DIRECTORY_SEPARATOR); </span><span>//</span><span> 加水印,文字、图片水印,以图片为例</span> <span>function</span> watermark(<span>$srcFile</span> = '', <span>$markFile</span> = '', <span>$dstFile</span> = ''<span>) { </span><span>if</span>(!<span>file_exists</span>(<span>$srcFile</span>) || !<span>file_exists</span>(<span>$markFile</span><span>)) { </span><span>echo</span> 'file not exists!<br/>'<span>; </span><span>return</span> <span>false</span><span>; } </span><span>//</span><span> 获取原始图片与水印图片的宽高</span> <span>list</span>(<span>$srcWidth</span>, <span>$srcHeight</span>) = <span>getimagesize</span>(<span>$srcFile</span><span>); </span><span>list</span>(<span>$markWidth</span>, <span>$markHeight</span>) = <span>getimagesize</span>(<span>$markFile</span><span>); </span><span>//</span><span> 水印图片不能比原始图片像素还大</span> <span>if</span>(<span>$markWidth</span> > <span>$srcWidth</span> || <span>$markHeight</span> > <span>$srcHeight</span><span>) { </span><span>return</span> <span>false</span><span>; } </span><span>//</span><span> 获取即将被加水印的原始图片句柄、水印图片句柄</span> <span>$dstImg</span> = imagecreatefromjpeg(<span>$srcFile</span><span>); </span><span>$markImg</span> = imagecreatefrompng(<span>$markFile</span><span>); </span><span>//</span><span> 加水印的位置,简单放在右下角</span> <span>$dst_x</span> = <span>$srcWidth</span> - <span>$markWidth</span><span>; </span><span>$dst_y</span> = <span>$srcHeight</span> - <span>$markHeight</span><span>; </span><span>//</span><span> 获取文件信息</span> <span>$fileinfo</span> = <span>pathinfo</span>(<span>$srcFile</span><span>); </span><span>if</span>(<span>empty</span>(<span>$dstFile</span><span>)) { </span><span>$dstFile</span> = <span>rtrim</span>(<span>$fileinfo</span>['dirname'], DS).DS.'mark_'.<span>$fileinfo</span>['filename'].<span>date</span>('YmdHis').<span>mt_rand</span>(1, 1000).'.jpeg'<span>; } </span><span>//</span><span> 将水印图片复制到已有图片上</span> imagecopy(<span>$dstImg</span>, <span>$markImg</span>, <span>$dst_x</span>, <span>$dst_y</span>, 0, 0, <span>$srcWidth</span>, <span>$srcHeight</span><span>); </span><span>//</span><span> 将新加完水印的图片保存起来</span> imagejpeg(<span>$dstImg</span>, <span>$dstFile</span><span>); imagedestroy(</span><span>$dstImg</span><span>); imagedestroy(</span><span>$markImg</span><span>); </span><span>return</span> <span>true</span><span>; } </span><span>$srcFile</span> = 'G:\wamp\www\html\image\p125.jpg'; <span>//</span><span> 原图片</span> <span>$markFile</span> = 'G:\wamp\www\html\image\ooopic_5.png'; <span>//</span><span> 水印图片</span> watermark(<span>$srcFile</span>, <span>$markFile</span>);
效果:
在这里,简单将水印图片放在图片右下角,所以放在图片的右下角要一个简单的计算,调用imagecopy时,从水印图片的左上角顶点(坐标0,0)开始全部(宽高传入水印图片宽高)复制到待加水印图片上,然后imagejpeg绘制图像并保存,注意类似imagejpeg(这里简单使用它)等绘图函数传入第二个参数时是保存图片为一个文件,而不是输出到浏览器,所以也不需调header函数发送头信息。
当然还要搞清楚哪是源文件(src),哪是目标文件(dst),把一张小图加水印到一张大图上时,源文件是小图水印,把它复制到大图上,大图就是目标。
能用图片作为水印,在于imagecopy的第二个参数是图像句柄,所以可以从现有图片来创建一个(如imagecreatefromjpeg),当然也能从现有的字符创建一个字符图像句柄变量---使用imagecreatefromstring方法,所以这个更通用。
2. 图片缩放
很多应用,图片列表是小图,当你点击某一个时,才会展现完整大图,这涉及到一个图片收缩的处理。有两个方法可供使用:imagecopyresized和imagecopyresampled,几乎一样,不同的是后者对图片进行重采样(貌似是我专业的词),所以成图质量更好(重采样的话也得看采取哪种方法,有的会变得更渣),挑一个说:
bool imagecopyresampled ( resource $dst_image , resource $src_image , int $dst_x , int $dst_y , int $src_x , int $src_y , int $dst_w , int $dst_h , int $src_w , int $src_h )
第一、二个参数与上面相似,如何做到缩放?比如这里,是将原图像上左上角顶点处,坐标为(src_x, src_y),宽高为src_w、src_h的部分图片,画到目标图像上坐标为(dst_x, dst_y),宽高为dst_w、dst_h的地方,所以如果目标图片上的宽高比原图上选取部分的宽高小的话,就成了缩小版了,当然还需要两个左上角顶点的坐标值相同,以jpg类型为例:
<?<span>php date_default_timezone_set(</span>'Asia/Shanghai'<span>); </span><span>define</span>('DS',<span> DIRECTORY_SEPARATOR); </span><span>//</span><span> 缩小图片</span> <span>/*</span><span>* * @param src 原图像路径 * @param percent 缩小比例 * @param dstFile 保存图片的路径 </span><span>*/</span> <span>function</span> zoomPic(<span>$srcFile</span> = '', <span>$percent</span> = 0.5, <span>$dstFile</span> = ''<span>) { </span><span>if</span>(!<span>file_exists</span>(<span>$srcFile</span><span>)) { </span><span>return</span> <span>false</span><span>; } </span><span>list</span>(<span>$width</span>, <span>$height</span>) = <span>getimagesize</span>(<span>$srcFile</span>); <span>//</span><span> 获取宽高</span> (<span>$percent</span> <= 0 || <span>$percent</span> > 1) && <span>$percent</span> = 0.5<span>; </span><span>$newWidth</span> = <span>floor</span>(<span>$width</span> * <span>$percent</span>); <span>//</span><span> 缩小后的宽高</span> <span>$newHeight</span> = <span>floor</span>(<span>$height</span> * <span>$percent</span><span>); </span><span>$dstImg</span> = imagecreatetruecolor(<span>$newWidth</span>, <span>$newHeight</span>); <span>//</span><span> 创建新图像宽高的画布</span> <span>$srcImg</span> = imagecreatefromjpeg(<span>$srcFile</span>); <span>//</span><span> 从原图像文件创建画布</span> <span>$pathinfo</span> = <span>pathinfo</span>(<span>$srcFile</span><span>); </span><span>if</span>(!<span>$dstFile</span>) <span>$dstFile</span> = <span>rtrim</span>(<span>$pathinfo</span>['dirname'], DS).DS.'zoom_'.<span>$pathinfo</span>['filename'].<span>date</span>('YmdHis').<span>mt_rand</span>(1, 1000).".jpeg"<span>; </span><span>//</span><span> 从源文件左上角顶点开始进行缩小 //imagecopyresized($dstImg, $srcImg, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height); </span> imagecopyresampled(<span>$dstImg</span>, <span>$srcImg</span>, 0, 0, 0, 0, <span>$newWidth</span>, <span>$newHeight</span>, <span>$width</span>, <span>$height</span><span>); </span><span>//</span><span> 绘制且保存图像</span> imagejpeg(<span>$dstImg</span>, <span>$dstFile</span><span>); </span><span>//</span><span> 销毁资源</span> imagedestroy(<span>$dstImg</span><span>); imagedestroy(</span><span>$srcImg</span><span>); </span><span>return</span> <span>true</span><span>; } </span><span>//</span><span> 测试</span> <span>$srcFile</span> = 'G:\wamp\www\html\image\p179.jpg'<span>; zoomPic(</span><span>$srcFile</span>);
效果:
在这里,我们可以将原图与小图分两套存放,列表展示小图,低级查就展示原图。
3. 图片裁剪
考虑上面的imagecopyresampled方法,如果不从原图像的左上角开始,而是左上角偏右下某一点开始,切图的宽高也再等于源文件完整的宽高,而是部分宽高,那么新的重采样的图片,就是源图片的一部分,就达到了裁剪的效果,所以裁剪与缩放使用的方法一样
<?<span>php date_default_timezone_set(</span>'Asia/Shanghai'<span>); </span><span>define</span>('DS',<span> DIRECTORY_SEPARATOR); </span><span>//</span><span> cut a picture</span> <span>function</span> cutPic(<span>$srcFile</span> = '', <span>$x</span> = 0, <span>$y</span> = 0, <span>$width</span> = 16, <span>$height</span> = 16, <span>$dstFile</span> = ''<span>) { </span><span>if</span>(!<span>file_exists</span>(<span>$srcFile</span><span>)) { </span><span>return</span> <span>false</span><span>; } </span><span>list</span>(<span>$srcWidth</span>, <span>$srcHeight</span>, <span>$type</span>) = <span>getimagesize</span>(<span>$srcFile</span><span>); </span><span>$x</span> < 0 && <span>$x</span> = 0<span>; </span><span>$y</span> < 0 && <span>$y</span> = 0<span>; </span><span>//</span><span> 宽高设置</span> ((<span>$width</span> + <span>$x</span>) > <span>$srcWidth</span>) && <span>$width</span> = <span>$srcWidth</span><span>; ((</span><span>$height</span> + <span>$y</span>) > <span>$srcHeight</span>) && <span>$height</span> = <span>$srcHeight</span><span>; (</span><span>$width</span> <= 0) && <span>$width</span> = <span>$srcWidth</span><span>; (</span><span>$height</span> <= 0) && <span>$height</span> = <span>$srcHeight</span><span>; </span><span>$dstImg</span> = imagecreatetruecolor(<span>$width</span>, <span>$height</span>); <span>//</span><span> 目标文件资源 </span> <span>switch</span>(<span>$type</span><span>) { </span><span>case</span> IMG_GIF: <span>$srcImg</span> = imagecreatefromgif(<span>$srcFile</span>); <span>//</span><span> 获取源文件资源句柄及扩展名处理,以使用合适的函数和扩展</span> <span>$ext</span> = 'gif'<span>; </span><span>$imagefun</span> = 'imagegif'<span>; </span><span>break</span><span>; </span><span>case</span> IMG_JPG: <span>$srcImg</span> = imagecreatefromjpeg(<span>$srcFile</span><span>); </span><span>$ext</span> = 'jpeg'<span>; </span><span>$imagefun</span> = 'imagejpeg'<span>; </span><span>break</span><span>; </span><span>default</span>: <span>$srcImg</span> = imagecreatefrompng(<span>$srcFile</span><span>); </span><span>$ext</span> = 'png'<span>; </span><span>$imagefun</span> = 'imagepng'<span>; </span><span>break</span><span>; } </span><span>//</span><span> 设置保存剪切后的文件路径</span> <span>$fileinfo</span> = <span>pathinfo</span>(<span>$srcFile</span><span>); </span><span>if</span>(<span>empty</span>(<span>$dstFile</span><span>)) { </span><span>$dstFile</span> = <span>rtrim</span>(<span>$fileinfo</span>['dirname'], DS).DS.'cut_'.<span>$fileinfo</span>['filename'].<span>date</span>('YmdHis').<span>mt_rand</span>(1, 1000).".{<span>$ext</span>}"<span>; } </span><span>//</span><span> 执行剪切操作</span> imagecopyresampled(<span>$dstImg</span>, <span>$srcImg</span>, 0, 0, <span>$x</span>, <span>$y</span>, <span>$width</span>, <span>$height</span>, <span>$width</span>, <span>$height</span><span>); </span><span>//</span><span> 画于画布并保存文件</span> <span>$imagefun</span>(<span>$dstImg</span>, <span>$dstFile</span><span>); imagedestroy(</span><span>$dstImg</span><span>); imagedestroy(</span><span>$srcImg</span><span>); </span><span>return</span> <span>true</span><span>; } </span><span>//</span><span> 测试</span> <span>$srcFile</span> = 'G:\wamp\www\html\image\p221.jpg'<span>; cutPic(</span><span>$srcFile</span>, 50, 50, 50, 50);
效果:
常见的应用是,我们在给自己的某个应用换头像时,头像太大,就会用到裁剪,用这就可以做一个模拟实现。
4. 图片旋转
图片旋转也十分常见,主要用到函数imagerotate,原型:resource imagerotate ( resource $image , float $angle , int $bgd_color [, int $ignore_transparent = 0 ] ),第一个参数是待旋转图像句柄,第二个参数angle 是旋转的角度数值,第三个参数指定一个颜色,即当旋转后出现空的地方是使用哪种颜色填充,第四个参数是指定一个透明色,默认0表示保留透明色。该方法返回一个新的图像句柄,就是经过旋转后的图像资源变量,将它绘制保存即可。还要注意的是,旋转的角度可以指定0到360之间,为逆时针旋转,以jpg为例:
<?<span>php date_default_timezone_set(</span>'Asia/Shanghai'<span>); </span><span>define</span>('DS',<span> DIRECTORY_SEPARATOR); </span><span>/*</span><span>* * 图片旋转 * @param angular 旋转角度值 0-360 </span><span>*/</span> <span>function</span> rotatePic(<span>$srcFile</span> = '', <span>$angular</span> = 0, <span>$dstFile</span> = ''<span>) { </span><span>if</span>(!<span>file_exists</span>(<span>$srcFile</span><span>)) { </span><span>echo</span> 'file not exists<br/>'<span>; </span><span>return</span> <span>false</span><span>; } </span><span>$srcImg</span> = imagecreatefromjpeg(<span>$srcFile</span><span>); </span><span>//</span><span> 处理保存文件地址</span> <span>$fileinfo</span> = <span>pathinfo</span>(<span>$srcFile</span><span>); </span><span>if</span>(<span>empty</span>(<span>$dstFile</span><span>)) { </span><span>$dstFile</span> = <span>rtrim</span>(<span>$fileinfo</span>['dirname'], DS).DS.'rotate_'.<span>$fileinfo</span>['filename'].<span>date</span>('YmdHis').<span>mt_rand</span>(1, 1000).'.jpeg'<span>; } </span><span>$white</span> = imagecolorallocate(<span>$srcImg</span>, 0xff, 0xff, 0xf1<span>); </span><span>//</span><span> 执行旋转,注意是逆时针方向</span> <span>$dstImg</span> = imagerotate(<span>$srcImg</span>, <span>$angular</span>, <span>$white</span><span>); </span><span>//</span><span> 画到画布,保存文件</span> imagejpeg(<span>$dstImg</span>, <span>$dstFile</span><span>); imagedestroy(</span><span>$dstImg</span><span>); imagedestroy(</span><span>$srcImg</span><span>); </span><span>return</span> <span>true</span><span>; } </span><span>//</span><span> 测试</span> <span>$srcFile</span> = 'G:\wamp\www\html\image\p219.jpg'<span>; rotatePic(</span><span>$srcFile</span>, 220);
效果:原图 旋转后
5. 图片翻转
这个在应用中不那么常见。所谓翻转,就是对图像进行镜面翻转,比如以图片中间竖直线为轴线,左边换到右边,右边换到左边,对调一下位置,就是左右翻转。想象一下,以中间竖直线为对称轴的情况,Y轴像素点不变,X轴上的像素点左右对调,仍可以使用imagecopy方法,对于源文件,在复制到目标图像时,进行这个操作,以绕Y轴旋转,jpg类型图片为例
<?<span>php </span><span>//</span><span> 图片翻转</span> date_default_timezone_set('Asia/Shanghai'<span>); </span><span>define</span>('DS',<span> DIRECTORY_SEPARATOR); </span><span>//</span><span> 沿Y轴翻转,x坐标值对调</span> <span>function</span> turnY(<span>$srcFile</span> = '', <span>$dstFile</span> = ''<span>) { </span><span>if</span>(!<span>file_exists</span>(<span>$srcFile</span><span>)) { </span><span>return</span> <span>false</span><span>; } </span><span>//</span><span> 原图像句柄和宽高获取</span> <span>$srcImg</span> = imagecreatefromjpeg(<span>$srcFile</span><span>); </span><span>$srcWidth</span> = imagesx(<span>$srcImg</span><span>); </span><span>$srcHeight</span> = imagesy(<span>$srcImg</span><span>); </span><span>$dstImg</span> = imagecreatetruecolor(<span>$srcWidth</span>, <span>$srcHeight</span><span>); </span><span>//</span><span> 沿Y轴翻转,x轴上的像素点左右对调</span> <span>for</span>(<span>$i</span> = 0; <span>$i</span> < <span>$srcWidth</span>; <span>$i</span>++<span>) { imagecopy(</span><span>$dstImg</span>, <span>$srcImg</span>, <span>$srcWidth</span>-<span>$i</span>-1, 0, <span>$i</span>, 0, 1, <span>$srcHeight</span><span>); } </span><span>//</span><span> 画像保存路径处理</span> <span>$fileinfo</span> = <span>pathinfo</span>(<span>$srcFile</span><span>); </span><span>if</span>(<span>empty</span>(<span>$dstFile</span><span>)) { </span><span>$dstFile</span> = <span>rtrim</span>(<span>$fileinfo</span>['dirname'], DS).DS.'turnx_'.<span>$fileinfo</span>['filename'].<span>date</span>('YmdHis').<span>mt_rand</span>(1, 1000).'.jpeg'<span>; } </span><span>//</span><span> 绘制图像,保存文件</span> imagejpeg(<span>$dstImg</span>, <span>$dstFile</span><span>); imagedestroy(</span><span>$dstImg</span><span>); imagedestroy(</span><span>$srcImg</span><span>); </span><span>return</span> <span>false</span><span>; } </span><span>//</span><span> 测试</span> <span>$srcFile</span> = 'G:\wamp\www\html\image\p311.jpg'<span>; turnY(</span><span>$srcFile</span>);
效果: 翻转前 翻转后
主要就是for循环那儿,得到源文件的宽度$srcWidth后,如果源文件上坐标是($i, 0)则对应目标图像上坐标($srcWidth-$i-1, 0),然后将宽度为1个像素,高为源文件整个高度$srcHeight的资源复制过去,循环完成后就全部复制到一个图片上了,相当于是一条一条线的画过去的。
无意浏览手册感觉被坑,看到imageflip函数猜到是这个功能,一看果然是的,可是看的书已经落后几年了,原型:bool imageflip ( resource $image , int $mode ),第一个参数是目标图像资源,第二个参数是翻转的方式,使用php自带的枚举变量即可,有IMG_FLIP_HORIZONTAL(水平)、IMG_FLIP_HORIZONTAL(竖直)、IMG_FLIP_BOTH(水平竖直)三种方式,一个函数即可实现。
反正都挺简单,不如练练手玩玩 :-D

使用數據庫存儲會話的主要優勢包括持久性、可擴展性和安全性。 1.持久性:即使服務器重啟,會話數據也能保持不變。 2.可擴展性:適用於分佈式系統,確保會話數據在多服務器間同步。 3.安全性:數據庫提供加密存儲,保護敏感信息。

在PHP中實現自定義會話處理可以通過實現SessionHandlerInterface接口來完成。具體步驟包括:1)創建實現SessionHandlerInterface的類,如CustomSessionHandler;2)重寫接口中的方法(如open,close,read,write,destroy,gc)來定義會話數據的生命週期和存儲方式;3)在PHP腳本中註冊自定義會話處理器並啟動會話。這樣可以將數據存儲在MySQL、Redis等介質中,提升性能、安全性和可擴展性。

SessionID是網絡應用程序中用來跟踪用戶會話狀態的機制。 1.它是一個隨機生成的字符串,用於在用戶與服務器之間的多次交互中保持用戶的身份信息。 2.服務器生成並通過cookie或URL參數發送給客戶端,幫助在用戶的多次請求中識別和關聯這些請求。 3.生成通常使用隨機算法保證唯一性和不可預測性。 4.在實際開發中,可以使用內存數據庫如Redis來存儲session數據,提升性能和安全性。

在無狀態環境如API中管理會話可以通過使用JWT或cookies來實現。 1.JWT適合無狀態和可擴展性,但大數據時體積大。 2.Cookies更傳統且易實現,但需謹慎配置以確保安全性。

要保護應用免受與會話相關的XSS攻擊,需採取以下措施:1.設置HttpOnly和Secure標誌保護會話cookie。 2.對所有用戶輸入進行輸出編碼。 3.實施內容安全策略(CSP)限制腳本來源。通過這些策略,可以有效防護會話相關的XSS攻擊,確保用戶數據安全。

优化PHP会话性能的方法包括:1.延迟会话启动,2.使用数据库存储会话,3.压缩会话数据,4.管理会话生命周期,5.实现会话共享。这些策略能显著提升应用在高并发环境下的效率。

theSession.gc_maxlifetimesettinginphpdeterminesthelifespanofsessiondata,setInSeconds.1)它'sconfiguredinphp.iniorviaini_set().2)abalanceisesneededeededeedeedeededto toavoidperformance andunununununexpectedLogOgouts.3)

在PHP中,可以使用session_name()函數配置會話名稱。具體步驟如下:1.使用session_name()函數設置會話名稱,例如session_name("my_session")。 2.在設置會話名稱後,調用session_start()啟動會話。配置會話名稱可以避免多應用間的會話數據衝突,並增強安全性,但需注意會話名稱的唯一性、安全性、長度和設置時機。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

Dreamweaver CS6
視覺化網頁開發工具

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

SublimeText3 英文版
推薦:為Win版本,支援程式碼提示!

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能