Continuing from the previous article. The GD library can be used in many ways, and of course it has to do with drawing. In addition to the previous verification code and watermark, it can also perform image scaling, cropping, rotation and other operations, which can be seen in many applications.
1. Add watermark
As we know before, we can use imagechar or imagestring to draw characters or strings (even Chinese characters) onto the image to achieve the purpose of watermarking. There is a better way, which can not only add character watermarks, but also Able to add image watermark: imagecopy.
Prototype: 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). Look at the name to know that this is a copy, No. 1 , the two parameters are the target image handle and the source file handle. When adding a watermark, if the watermark image is a small picture and is added to a large picture, then the first parameter is the large picture handle, and the second parameter is the small picture handle. . The 3rd and 4th parameters are the x and y coordinates of the watermark on the target image. The 5th and 6th parameters are the starting x and y coordinates of the watermark image. The 7th and 8th parameters are the watermark images that will be used as watermarks. The width and height of the watermark image src_im, so the meaning of this method is to copy the part where the upper left corner vertex coordinates (src_x, src_y) of the watermark image src_im, the width and height are src_w, src_h respectively, to the image dst_im, and then copy this dst_im image Draw on the canvas and save or output it, it will be a watermarked picture, code:
<?<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>);
Effect:
Here, simply place the watermark image in the lower right corner of the image, so placing it in the lower right corner of the image requires a simple calculation. When calling imagecopy, start from the upper left corner vertex (coordinates 0,0) of the watermark image (width (high width and height of the incoming watermark image) is copied to the image to be watermarked, and then imagejpeg draws the image and saves it. Note that when drawing functions such as imagejpeg (use it simply here) pass in the second parameter, the image is saved as a file, and It is not output to the browser, so there is no need to adjust the header function to send header information.
Of course, you also need to figure out which is the source file (src) and which is the target file (dst). When adding a small picture to a large picture, the source file is the small picture watermark, and copy it to the large picture. , the big picture is the goal.
You can use pictures as watermarks because the second parameter of imagecopy is an image handle, so you can create one from an existing picture (such as imagecreatefromjpeg). Of course, you can also create a character image handle variable from existing characters-- - Use imagecreatefromstring method, so this one is more general.
2. Image zoom
In many applications, the picture list is a small picture. When you click on a certain one, the complete large picture will be displayed. This involves a picture shrinking process. There are two methods available: imagecopyresized and imagecopyresampled, which are almost the same. The difference is that the latter resamples the image (seems to be my professional word), so the image quality is better (resampling also depends on which method is used) methods, some will become worse), pick one and say:
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 )
The first and second parameters are similar to the above. How to achieve scaling? For example, here, a part of the picture at the upper left corner vertex of the original image, with coordinates (src_x, src_y), width and height src_w, src_h, is drawn to the target image with coordinates (dst_x, dst_y), width and height dst_w, dst_h. place, so if the width and height of the target image are smaller than the width and height of the selected part of the original image, it will become a reduced version. Of course, the coordinate values of the two upper left corner vertices need to be the same. Take the jpg type as an example:
<?<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>);
Effect:
Here, we can store the original image and the small image in two sets, display the small image in the list, and display the original image in low-level search.
3. Image cropping
Consider the above imagecopyresampled method. If you do not start from the upper left corner of the original image, but start from the upper left corner to the lower right corner, the width and height of the cut image will no longer be equal to the complete width and height of the source file, but a partial width and height. , then the new resampled image is part of the source image, achieving the effect of cropping, so the method used for cropping and scaling is the same
<?<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);
Effect:
A common application is that when we change the avatar for one of our applications, if the avatar is too big, we will use cropping. This can be used to make a simulation implementation.
4. Image rotation
图片旋转也十分常见,主要用到函数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