核心提示: 缩略图的实现原理其实就是将你的源图通过等比缩放、裁切宽高的方式去适配指定尺寸的画布的过程。
一、这里有壹个重要的PHP函数: i m a g e c o p y r e s a m p l e d \color{#FF3030}{imagecopyresampled} imagecopyresampled
1、函数功能预览,
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 ) : bool
i m a g e c o p y r e s a m p l e d ( ) 将 一 幅 图 像 中 的 一 块 矩 形 区 域 拷 贝 到 另 一 个 图 像 中 , 平 滑 地 插 入 像 素 值 。 \color{#FF3030}{imagecopyresampled()将一幅图像中的一块矩形区域拷贝到另一个图像中,平滑地插入像素值。} imagecopyresampled()将一幅图像中的一块矩形区域拷贝到另一个图像中,平滑地插入像素值。因此,尤其是,减小了图像的大小而仍然保持了极大的清晰度。
如 果 源 和 目 标 的 宽 度 和 高 度 不 同 , 则 会 进 行 相 应 的 图 像 收 缩 和 拉 伸 。 坐 标 指 的 是 左 上 角 。 \color{#FF3030}{如果源和目标的宽度和高度不同,则会进行相应的图像收缩和拉伸。坐标指的是左上角。} 如果源和目标的宽度和高度不同,则会进行相应的图像收缩和拉伸。坐标指的是左上角。本函数可用来在同一幅图内部拷贝(如果 dst_image 和src_image 相同的话)区域,但如果区域交迭的话则结果不可预知。
2、参数介绍
参数 | 解释 |
---|---|
dst_image | 目标图象连接资源 |
src_image | 源图象连接资源 |
dst_x | 目标 X 坐标点 |
dst_y | 目标 Y 坐标点 |
src_x | 源的 X 坐标点 |
src_y | 源的 Y 坐标点 |
dst_w | 目标宽度 |
dst_h | 目标高度 |
src_w | 源图象的宽度 |
src_h | 源图象的高度 |
3、返回值
成功时返回 TRUE, 或者在失败时返回 FALSE。
二、缩略图类Thumb功能实现:thumb.php
在本示例代码中,由于我们是将自己的图片通过缩放、裁切的方式拷贝到画布上面,壹般情况都是以左上角开始,所以核心点就是通过计算得出拷贝矩形区域的宽、高和画布的宽、高,然后进行合并。这里提供了3种缩略图类型,以整数数值类型变量 t h u m b T y p e \color{#FF3030}{thumbType} thumbType 区分,分别是:
- 1——保存画布宽度,高度自动
- 2——保存画布高度,宽度自动
- 3——保存画布宽高,裁切原图
我们最终生成的缩略图尺寸是根据用户输入的画布的宽($canvasWidth)、高($canvasHeight)为参考而计算出的。
注意: 这里画布的宽($canvasWidth)、高($canvasHeight)作为用户输入的参数值 只是参考,用来计算缩放比例,因为除了第3种缩略图方式是完全将原图裁切以匹配画布尺寸外,1和2所以代表的缩略图方式会根据给定宽度依据比例自动计算出高度,或者根据给定高度依据比例自动计算出宽度。
所以,在代码实现时,imagecopyresampled 的第7、第8两个参数,并没有用 $canvasWidth 和 $canvasHeight 的值,而是通过 getSize 函数返回的数组 $size 的第0、第1两个元素,即 $size[0] 和 $size[1] 值来作为最终实际输出的画布宽高尺寸。
<?php
class Thumb
{
//入口方法
public function make(string $sourceImage, string $destinationImage, int $canvasWidth, int $canvasHeight, int $thumbType = 3)
{
$this->checkImage($sourceImage);
$image = $this->getResource($sourceImage);
//根据传入的缩略图类型,计算出画布尺寸或裁切后的图片尺寸
$size = $this->getSize($canvasWidth,$canvasHeight,imagesx($image),imagesy($image),$thumbType);
//根据画布尺寸创建图像资源
$res = imagecreatetruecolor($size[0],$size[1]);
//核心
imagecopyresampled($res,$image,0,0,0,0,$size[0],$size[1],$size[2],$size[3]);
header("Content-type:image/jpeg");
//保存图片
return $this->showAction($sourceImage)($res,$destinationImage);
}
//获取尺寸数据
public function getSize(int $canvasWidth, int $canvasHeight, int $imageWidth, int $imageHeight, int $thumbType)
{
switch ($thumbType) {
//保存画布宽度,高度自动
case 1:
$canvasHeight = $canvasWidth / $imageWidth * $imageHeight;
break;
//保存画布高度,宽度自动
case 2:
$canvasWidth = $canvasHeight / $imageHeight * $imageWidth;
break;
//保存画布宽高,裁切原图
case 3:
default:
if ($imageWidth / $canvasWidth > $imageHeight / $canvasHeight) {
$imageWidth = $imageHeight / $canvasHeight * $canvasWidth;
} else {
$imageHeight = $imageWidth / $canvasWidth * $canvasHeight;
}
}
return [$canvasWidth,$canvasHeight,$imageWidth,$imageHeight];
}
//根据图片获取资源
protected function getResource(string $image)
{
$info = getimagesize($image);
$functions = [1 => 'imagecreatefromgif', 2 => 'imagecreatefromjpeg', 3 => 'imagecreatefrompng'];
$call = $functions[$info[2]];
return $call($image);
}
//渲染图片
protected function showAction(string $image)
{
$info = getimagesize($image);
$functions = [1 => 'imagegif', 2 => 'imagejpeg', 3 => 'imagepng'];
return $functions[$info[2]];
}
//图片校验
protected function checkImage(string $image)
{
if (!is_file($image) || getimagesize($image) === false) {
throw new Exception("File dont exists or it's not image");
}
}
}
三、调用方式:index.php
引入文件,调用缩略图类,需要给make方法传递的参数依次是源图路径、目标图片保存路径、目标图片宽度(画布宽)、目标图片高度和缩略图类型。
<?php
include "thumb.php";
try {
$thumb = new Thumb();
$thumb->make("img/001.jpg","img/002.jpg",700,200,3);
}catch (Exception $exception){
echo $exception->getMessage();
}
好了,就到这里吧!关于三种缩略图的缩放、裁切原理,因为我比较懒,这里没有画图说明,你可以根据代码细品,你细细品~~~