PHP图像处理之封装一个具有添加水印、缩放图片功能的工具类

一 前言

PHP在处理图像时因为GD库的存在操作起来是非常快捷方便的 , 不仅可以用来制作验证码 , 还用来给图片添加水印缩放图片等等。那么接下来我将封装一个具有添加水印缩放图片功能的工具类

二 需要使用的函数

getimagesize( ) 取得图像大小

?
1
2
3
4
5
6
7
8
9
10
11
12
/**
 * 该函数可测定任何GIF,JPG,PNG,SWF,SWC,PSD,TIFF,BMP,IFF,JP2,JPX,JB2,JPC,XBM或WBMP图像文件的大小
 * 并返回图像的尺寸以及文件类型和一个可以用于普通 HTML 文件中 IMG 标记中的 height/width 文本字符串。
 * 如果不能访问 filename 指定的图像或者其不是有效的图像,将返回 FALSE 并产生一条 E_WARNING 级的错误。
 *
 * 返回值 是一个具有四个单元的数组。索引 0 包含图像宽度的像素值,索引 1 包含图像高度的像素值。
 * 索引 2 是图像类型的标记:1 = GIF,2 = JPG,3 = PNG,4 = SWF,5 = PSD,6 = BMP,
 * 7 = TIFF(intel byte order),8 = TIFF(motorola byte order),9 = JPC,10 = JP2,11 = JPX,
 * 12 = JB2,13 = SWC,14 = IFF,15 = WBMP,16 = XBM。这些标记与 PHP 4.3.0 新加的 IMAGETYPE 常量对应。
 * 索引 3 是文本字符串,内容为“height="yyy" width="xxx"”,可直接用于 IMG 标记。
 */
array getimagesize ( string $filename [, array &$imageinfo ] )

image_type_to_extension( ) 取得图像类型的文件后缀

?
1
2
3
4
5
6
/**
 * 根据给定的常量 IMAGETYPE_XXX 返回后缀名。
 * $imagetype  是IMAGETYPE_XXX 系列常量之一。
 * $include_dot 是否在后缀名前加一个点。默认是 TRUE。
 */
string image_type_to_extension ( int $imagetype [, bool $include_dot = TRUE ] )

imagecreatefrompng( ) || imagecreatefromjpeg( ) || imagecreatefromgif( ) 由文件或 URL 创建一个新图象

?
1
2
3
4
5
6
/**
 * imagecreatefrompng() 返回一图像标识符,代表了从给定的文件名取得的图像。
 * $filename 是 PNG 图像的路径。
 * 成功后返回图象资源,失败后返回 FALSE 。
 */
resource imagecreatefrompng ( string $filename )

imagesx( ) || imagesy( ) 取得图像宽度/高度

?
1
2
3
4
5
6
/**
 * imagesx() 返回 $image 所代表的图像的宽度。
 * imagesy() 返回 $image 所代表的图像的高度。
 */
int imagesx ( resource $image )
int imagesy ( resource $image )

imagecopymerge ) 拷贝合并图像的一部分

?
1
2
3
4
5
6
7
8
/**
 * 将 src_im 图像中的坐标从 src_x,src_y 开始,
 * 宽度为 src_w,高度为 src_h 的一部分拷贝到 dst_im 图像中坐标为 dst_x 和 dst_y 的位置上。
 * 两图像将根据 pct 来决定合并程度,其值范围从 0 到 100。
 * 当 pct = 0 时,实际上什么也没做,当为 100 时对于调色板图像本函数和 imagecopy() 完全一样,
 * 它对真彩色图像实现了 alpha 透明。
 */
bool imagecopymerge ( resource $dst_im , resource $src_im , int $dst_x , int $dst_y , int $src_x , int $src_y , int $src_w , int $src_h , int $pct )

imagecopyresized( ) 拷贝部分图像并调整大小

?
1
2
3
4
5
6
7
8
9
10
11
12
/**
 * imagecopyresized() 将一幅图像中的一块矩形区域拷贝到另一个图像中。
 * dst_image 和 src_image 分别是目标图像和源图像的标识符。
 * 换句话说 imagecopyresized() 会把 src_image 中的 坐标从 src_x, src_y开始的
 * 一块宽为src_w 高为src_h 的矩形区域 放到另一块矩形区域中
 * 这块矩形区域就是dst_image 坐标从 dst_x, dst_y开始 , 宽为 dst_w, 高为 dst_h
 *
 * 如果源和目标的宽度和高度不同,则会进行相应的图像收缩和拉伸。坐标指的是左上角。
 * 本函数可用来在同一幅图内部拷贝(如果 dst_image 和 src_image 相同的话)区域,
 * 但如果区域交迭的话则结果不可预知。
 */
bool imagecopyresized ( 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 )

imagecreatetruecolor( ) 新建一个色图像

1
2
3
//顾名思义 创建真彩图像资源
//创建出一副宽x高y的黑色图像
resource imagecreatetruecolor ( int $width , int $height )

imagejpeg( ) || imagepng( ) || imagegif( ) || imagewbmp( ) || imagexbm( ) 输出图象到浏览器或文件

1
2
3
//imagepng() 将 GD 图像流(image)以 PNG 格式输出到标准输出(通常为浏览器),
//或者如果用 filename 给出了文件名则将其输出到该文件。
bool imagepng ( resource $image [, string $filename ] )
imagedestroy( ) 销毁一图像

1
2
3
//imagedestroy() 释放与 image 关联的内存。
//image 是由图像创建函数返回的图像标识符,例如 imagecreatetruecolor()。
bool imagedestroy ( resource $image )

三 封装Image类
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
<?php
class Image {
    //图片资源
    private $img;
    //图片路径
    private $src;
    //图片类型
    private $type;
    //方法名称imagePng
    private $output;
 
    /**
     * Image constructor.
     * @param $src [将要操作的图片的路径]
     */
    public function __construct( $src ) {
        $this->src = $src;
        //获取后缀
        $this->type = $this->getType( $src );
        $this->output = 'image' . $this->type;
    }
 
    /**
     * 获取图片类型后缀
     * @param $src [图片路径]
     * @return bool|string [图片类型后缀]
     */
    private function getType( $src ) {
        return image_type_to_extension( getimagesize( $src ) [2], false );
    }
 
    /**
     * 获取方法名
     * @param $type [图片类型后缀]
     * @return string [方法名imagecreatefrompng]
     */
    private function getFun( $type ) {
        return 'imagecreatefrom' . $type;
    }
 
    /**
     * 若当前图片资源未获取 则获取资源 否则不执行任何操作
     */
    private function getImg() {
        if( ! isset( $this->img ) ) {
            $this->img = ( $this->getFun( $this->type ) )( $this->src );
        }
    }
 
    /**
     * 添加水印
     * @param $src [水印logo图片路径]
     * @param int $bottom [logo距离原图右边的距离]
     * @param int $right [logo距离原图下边的距离]
     * @param float $opacity [logo透明度]
     */
    public function mark( $src, $bottom = 0, $right = 0, $opacity = 0.3 ) {
        //获取图片资源
        $this->getImg();
        $srcImg = ( $this->getFun( $this->getType($src) ) )( $src );
        //获取水印logo宽高
        $srcWidth = imagesX( $srcImg );
        $srcHeight = imagesY( $srcImg );
        //计算水印位置
        $dstX = imagesX( $this->img ) - $srcWidth - $bottom;
        $dstY = imagesY( $this->img ) - $srcHeight - $right;
        //合并水印
        imagecopymerge( $this->img, $srcImg, $dstX, $dstY, 0, 0, $srcWidth, $srcHeight, 100 - $opacity * 100 );
        imagedestroy( $srcImg );
    }
 
    /**
     * @param $width [压缩后的宽度]
     * @param $height [压缩后的高度]
     */
    public function resize( $width , $height ) {
        $dstImg = imagecreatetruecolor( $width, $height );
        $this->getImg();
        $srcW = imagesX( $this->img );
        $srcH = imagesY( $this->img );
        imagecopyresized( $dstImg, $this->img, 0, 0, 0, 0, $width, $height, $srcW, $srcH );
        $this->img = $dstImg;
    }
 
    /**
     * 显示图片
     * @param null $path [图片保存路径]
     */
    public function show( $path = null ) {
        if( is_null($path) ){
            header('Content-type:image/' . $this->type);
            ($this->output)( $this->img );
        }else{
            $this->save( $path );
        }
    }
 
    /**
     * 保存图片
     * @param null $path (不传参则默认保存至default目录下)
     * @return null|string [图片保存后的完整路径]
     */
    public function save( $path = null ) {
        if( is_null($path) ) {
            $path =  __DIR__ . '/default/' . uniqid() . '.' $this->type;
        }
        ($this->output)( $this->img , $path );
        return $path;
    }
 
    public function __destruct() {
        imagedestroy( $this->img );
    }
}
调用方式 :
?
1
2
3
4
5
6
7
8
9
10
11
12
<?php
require 'Image.php';
//传入将要操作的图片
$img = new Image('./images/taylors.png');
//缩放图片
$img->resize(500,400);
//加盖水印 传入logo图, logo距离原图左边的距离 logo距离原图左边的距离 与透明度 0~1之间的float
$img->mark('./images/logo.jpg', 20, 20, .3);
//显示图片 如传入路径 则保存图片至该路径
$img->show();
//保存图片 若传入路径 则保存图片至该路径 默认保存到./default文件夹下 并且会return 保存后的路径
$img->save();
运行结果如下 :

Logo图 : 263 * 263像素 JPEG格式图片 10K大小

原图 : 1000 * 667像素 png格式 708K大小


加盖水印后的图片 : 500 * 400 PNG格式图片 279K大小

使用PHP加盖水印并且缩放图片原来可以这么简单 真是可怕!

再来试张JPEG格式的图片

原图 : 640 * 627像素 JPEG格式 708K大小

加盖水印后的图片 : 500 * 400 JPEG格式图片 47K大小

哈哈 2种格式都成功了 真是舒服!

本项目gayhub传送门

发布评论
还没有评论,快来抢沙发吧!