PHP缩略图生成和图片水印制作

2025-05-29 0 18

1.开始

在网站上传图片过程,经常用到缩略图功能。这里我自己写了一个图片处理的image类,能生成缩略图,并且可以添加水印图。

2.如何生成缩略图

生成缩略图,关键的是如何计算缩放比率。

这里,我根据图片等比缩放,宽高的几种常见变化,得出一个算缩放比率算法是,使用新图(即缩略图)的宽高,分别除以原图的宽高,看哪个值大,就取它作为缩放比率:

缩放比率 = max( { 新图高度 / 原图高度 , 新图宽度 / 原图宽度 } )

也就是:

if ( (新图高度 / 原图高度) > (新图宽度 / 原图宽度 ) ) {

缩放比率 = 新图高度 / 原图高度;

}else {

缩放比率 = 新图宽度 / 原图宽度;

}

这里列出场景的图片缩放场景,及处理方法:

e.g

场景1,原图比新图大的情况, 缩放比率 = 新图宽度 / 原图宽度 :

PHP缩略图生成和图片水印制作

场景2,原图比新图大的情况,b. 缩放比率 = 新图高度 / 原图高度 :

PHP缩略图生成和图片水印制作

场景3,原图比新图大的情况,而且新图宽高相等,即新图形状是正方形,那么上面的缩放算法也是适用的。

场景4,如果 “新图宽度 >= 原图宽度” ,同时 “新图高度 >= 原图高度”,那么不缩放图片,也不放大图片,保持原图。

PHP缩略图生成和图片水印制作

场景5,如果 “新图宽度 < 原图宽度”,同时 “新图高度 >= 原图高度” ,那么先设置 “新图高度= 原图高度”,再剪切。

PHP缩略图生成和图片水印制作

场景6,如果 “新图高度 < 原图高度”,同时 “新图宽度 >= 原图宽度” ,那么先设置 “新图宽度= 原图宽度”,再剪切。

PHP缩略图生成和图片水印制作

3.如何添加水印图片
添加水印很容易,我这里没考虑那么复杂,主要是控制水印位置在图片的右下角,和控制水印在图片中的大小。如,当目标图片与水印图大小接近,那么需要先等比缩放水印图片,再添加水印图片。

PHP缩略图生成和图片水印制作

左边两幅图,上面是原图,下面是水印图,右边的缩放后加水印的新图。

4.类图

PHP缩略图生成和图片水印制作

5.php代码

5.1. 构造函数 __construct()

在image类中,除了构造函数__construct()是public,其它函数都为private.也就是在函数__construct()中,直接完成了生成缩略图和添加水印图的功能。如果,只生成缩略图而不需要添加水印,那么直接在__construct()的参数$markpath,设置为null即可。

其中,“$this->quality = $quality ? $quality : 75;” 控制输出为jpg图片时,控制图片质量(0-100),默认值为75;

?

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
/**

* image constructor.

* @param string $imagepath 图片路径

* @param string $markpath 水印图片路径

* @param int $new_width 缩略图宽度

* @param int $new_height 缩略图高度

* @param int $quality jpg图片格输出质量

*/

public function __construct(string $imagepath,

string $markpath = null,

int $new_width = null,

int $new_height = null,

int $quality = 75)

{

$this->imgpath = $_server['document_root'] . $imagepath;

$this->watermarkpath = $markpath;

$this->newwidth = $new_width ? $new_width : $this->width;

$this->newheight = $new_height ? $new_height : $this->height;

$this->quality = $quality ? $quality : 75;

list($this->width, $this->height, $this->type) = getimagesize($this->imgpath);

$this->img = $this->_loadimg($this->imgpath, $this->type);

//生成缩略图

$this->_thumb();

//添加水印图片

if (!empty($this->watermarkpath)) $this->_addwatermark();

//输出图片

$this->_outputimg();

}

note: 先生成缩略图,再在新图上添加水印 图片。

5.2. 生成缩略图函数_thumb()

?

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
/**

* 缩略图(按等比例,根据设置的宽度和高度进行裁剪)

*/

private function _thumb()

{

//如果原图本身小于缩略图,按原图长高

if ($this->newwidth > $this->width) $this->newwidth = $this->width;

if ($this->newheight > $this->height) $this->newheight = $this->height;

//背景图长高

$gd_width = $this->newwidth;

$gd_height = $this->newheight;

//如果缩略图宽高,其中有一边等于原图的宽高,就直接裁剪

if ($gd_width == $this->width || $gd_height == $this->height) {

$this->newwidth = $this->width;

$this->newheight = $this->height;

} else {

//计算缩放比率

$per = 1;

if (($this->newheight / $this->height) > ($this->newwidth / $this->width)) {

$per = $this->newheight / $this->height;

} else {

$per = $this->newwidth / $this->width;

}

if ($per < 1) {

$this->newwidth = $this->width * $per;

$this->newheight = $this->height * $per;

}

}

$this->newimg = $this->_createimg($gd_width, $gd_height, $this->type);

imagecopyresampled($this->newimg, $this->img, 0, 0, 0, 0, $this->newwidth, $this->newheight, $this->width, $this->height);

}

生成缩略图函数_thumb() ,是按照前面的分析来进行编码。

5.3. 添加水印图片函数 _addwatermark()

?

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
/**

* 添加水印

*/

private function _addwatermark()

{

$ratio = 1 / 5; //水印缩放比率

$width = imagesx($this->newimg);

$height = imagesy($this->newimg);

$n_width = $width * $ratio;

$n_height = $width * $ratio;

list($markwidth, $markheight, $marktype) = getimagesize($this->watermarkpath);

if ($n_width > $markwidth) $n_width = $markwidth;

if ($n_height > $markheight) $n_height = $markheight;

$img = $this->_loadimg($this->watermarkpath, $marktype);

$img = $this->_thumb1($img, $markwidth, $markheight, $marktype, $n_width, $n_height);

$markwidth = imagesx($img);

$markheight = imagesy($img);

imagecopyresampled($this->newimg, $img, $width - $markwidth - 10, $height - $markheight - 10, 0, 0, $markwidth, $markheight, $markwidth, $markheight);

imagedestroy($img);

}

在添加水印图片中,用到一个_thumb1()函数来缩放水印图片:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23
/**

* 缩略图(按等比例)

* @param resource $img 图像流

* @param int $width

* @param int $height

* @param int $type

* @param int $new_width

* @param int $new_height

* @return resource

*/

private function _thumb1($img, $width, $height, $type, $new_width, $new_height)

{

if ($width < $height) {

$new_width = ($new_height / $height) * $width;

} else {

$new_height = ($new_width / $width) * $height;

}

$newimg = $this->_createimg($new_width, $new_height, $type);

imagecopyresampled($newimg, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height);

return $newimg;

}

5.4. 完整代码:

?

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

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221
<?php

/**

* 图片处理,生成缩略图和添加水印图片

* created by phpstorm.

* user: andy

* date: 17-1-3

* time: 上午11:55

*/

class image

{

//原图

private $imgpath; //图片地址

private $width; //图片宽度

private $height; //图片高度

private $type; //图片类型

private $img; //图片(图像流)

//缩略图

private $newimg; //缩略图(图像流)

private $newwidth;

private $newheight;

//水印图路径

private $watermarkpath;

//输出图像质量,jpg有效

private $quality;

/**

* image constructor.

* @param string $imagepath 图片路径

* @param string $markpath 水印图片路径

* @param int $new_width 缩略图宽度

* @param int $new_height 缩略图高度

* @param int $quality jpg图片格输出质量

*/

public function __construct(string $imagepath,

string $markpath = null,

int $new_width = null,

int $new_height = null,

int $quality = 75)

{

$this->imgpath = $_server['document_root'] . $imagepath;

$this->watermarkpath = $markpath;

$this->newwidth = $new_width ? $new_width : $this->width;

$this->newheight = $new_height ? $new_height : $this->height;

$this->quality = $quality ? $quality : 75;

list($this->width, $this->height, $this->type) = getimagesize($this->imgpath);

$this->img = $this->_loadimg($this->imgpath, $this->type);

//生成缩略图

$this->_thumb();

//添加水印图片

if (!empty($this->watermarkpath)) $this->_addwatermark();

//输出图片

$this->_outputimg();

}

/**

*图片输出

*/

private function _outputimg()

{

switch ($this->type) {

case 1: // gif

imagegif($this->newimg, $this->imgpath);

break;

case 2: // jpg

if (intval($this->quality) < 0 || intval($this->quality) > 100) $this->quality = 75;

imagejpeg($this->newimg, $this->imgpath, $this->quality);

break;

case 3: // png

imagepng($this->newimg, $this->imgpath);

break;

}

imagedestroy($this->newimg);

imagedestroy($this->img);

}

/**

* 添加水印

*/

private function _addwatermark()

{

$ratio = 1 / 5; //水印缩放比率

$width = imagesx($this->newimg);

$height = imagesy($this->newimg);

$n_width = $width * $ratio;

$n_height = $width * $ratio;

list($markwidth, $markheight, $marktype) = getimagesize($this->watermarkpath);

if ($n_width > $markwidth) $n_width = $markwidth;

if ($n_height > $markheight) $n_height = $markheight;

$img = $this->_loadimg($this->watermarkpath, $marktype);

$img = $this->_thumb1($img, $markwidth, $markheight, $marktype, $n_width, $n_height);

$markwidth = imagesx($img);

$markheight = imagesy($img);

imagecopyresampled($this->newimg, $img, $width - $markwidth - 10, $height - $markheight - 10, 0, 0, $markwidth, $markheight, $markwidth, $markheight);

imagedestroy($img);

}

/**

* 缩略图(按等比例,根据设置的宽度和高度进行裁剪)

*/

private function _thumb()

{

//如果原图本身小于缩略图,按原图长高

if ($this->newwidth > $this->width) $this->newwidth = $this->width;

if ($this->newheight > $this->height) $this->newheight = $this->height;

//背景图长高

$gd_width = $this->newwidth;

$gd_height = $this->newheight;

//如果缩略图宽高,其中有一边等于原图的宽高,就直接裁剪

if ($gd_width == $this->width || $gd_height == $this->height) {

$this->newwidth = $this->width;

$this->newheight = $this->height;

} else {

//计算缩放比率

$per = 1;

if (($this->newheight / $this->height) > ($this->newwidth / $this->width)) {

$per = $this->newheight / $this->height;

} else {

$per = $this->newwidth / $this->width;

}

if ($per < 1) {

$this->newwidth = $this->width * $per;

$this->newheight = $this->height * $per;

}

}

$this->newimg = $this->_createimg($gd_width, $gd_height, $this->type);

imagecopyresampled($this->newimg, $this->img, 0, 0, 0, 0, $this->newwidth, $this->newheight, $this->width, $this->height);

}

/**

* 缩略图(按等比例)

* @param resource $img 图像流

* @param int $width

* @param int $height

* @param int $type

* @param int $new_width

* @param int $new_height

* @return resource

*/

private function _thumb1($img, $width, $height, $type, $new_width, $new_height)

{

if ($width < $height) {

$new_width = ($new_height / $height) * $width;

} else {

$new_height = ($new_width / $width) * $height;

}

$newimg = $this->_createimg($new_width, $new_height, $type);

imagecopyresampled($newimg, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height);

return $newimg;

}

/**

* 加载图片

* @param string $imgpath

* @param int $type

* @return resource

*/

private function _loadimg($imgpath, $type)

{

switch ($type) {

case 1: // gif

$img = imagecreatefromgif($imgpath);

break;

case 2: // jpg

$img = imagecreatefromjpeg($imgpath);

break;

case 3: // png

$img = imagecreatefrompng($imgpath);

break;

default: //其他类型

tool::alertback('不支持当前图片类型.' . $type);

break;

}

return $img;

}

/**

* 创建一个背景图像

* @param int $width

* @param int $height

* @param int $type

* @return resource

*/

private function _createimg($width, $height, $type)

{

$img = imagecreatetruecolor($width, $height);

switch ($type) {

case 3: //png

imagecolortransparent($img, 0); //设置背景为透明的

imagealphablending($img, false);

imagesavealpha($img, true);

break;

case 4://gif

imagecolortransparent($img, 0);

break;

}

return $img;

}

}

6.调用

调用非常简单,在引入类后,直接new 并输入对应参数即可:

e.g.

new image($_path, mark, 400, 200, 100);

7.小结
这个image 类能够生成缩略图,不出现黑边,添加水印图,能根据图片的大小缩放水印图。当然有个缺点,就是不能缩放gif的动画,因为涉及到帧的处理,比较麻烦。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持快网idc。

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 PHP缩略图生成和图片水印制作 https://www.kuaiidc.com/95477.html

相关文章

发表评论
暂无评论