最近突然想着给博客增加一个相册页面,将近些年外出游玩儿拍摄的图片上传到博客中,但迫于原始图片过于庞大,导致页面加载缓慢,虽然可以先行本地压缩后再行上传,但难免有些繁琐。对于图片的存储、压缩、裁剪,一直使用的是腾讯云的数据万象服务,虽然很省心,但毕竟需要额外付费。此次改造主要目的是使用插件来远程压缩图片,并生成对应的缩略图。
通过Google检索,发现了这款名为TinyPNG_for_Typecho的插件,经测试后发现仅能进行压缩,虽然压缩比很高,但对于缩略图而言文件还是太过庞大,翻阅了TinyPNG的文档,经过简单改造后新增缩略图生成功能。
主要针对插件文件中的第131行到第151行进行修改,原版源代码如下:
$fileName = sprintf('%u', crc32(uniqid())) . '.' . $ext;
$path = $path . '/' . $fileName;
// 中间部分无关紧要,省略
if ($isimage) {
$source->toFile($path);
$file['size'] = filesize($path);
} else if (!isset($file['size'])) {
$file['size'] = filesize($path);
}
修改文件命名规则
首先是需要对$path
变量进行改造,避免压缩后的图片和缩略图文件名冲突,这里为了更好的区分变量分别命名为“compress_path”和“thumbnail_path”。最终生成的文件分别为“xxx.png”和“xxx.png!thumbnail”,方便在模版中进行调用。
$fileName = sprintf('%u', crc32(uniqid())) . '.' . $ext;
$compress_path = $path . '/' . $fileName;
$thumbnail_path = $path . '/' . $fileName . '!thumbnail';
新增缩略图生成方法
这里需要参考TinyPng开发文档进行修改,例如下面的示例就会生成宽度为400的缩略图。因为上面代码中修改了$path变量的缘故,原有的图片压缩方法也需要进行修改,代码如下:
if ($isimage) {
$source->toFile($compress_path);
$file['size'] = filesize($compress_path);
$resized = $source->resize(array(
"method" => "scale",
"width" => 400
));
$resized->toFile("$thumbnail_path");
} else if (!isset($file['size'])) {
$file['size'] = filesize($compress_path);
}
完成以上修改后,将插件上传到Typecho插件目录,启用并填入TinyPNG的API key,就可以使用了,原始图片上传后,会自动对图片进行压缩,并生成对应尺寸的缩略图。以19.7MB的一张风景图作为测试对象,无损压缩后为3MB左右,而缩略图仅有56KB。
大概是因为网络的缘故,图片上传过程非常缓慢,9张共计170MB的图片上传完成总计消耗了将近2分钟,相比较在服务器中使用ImageMagick等工具进行压缩而言,耗时过久,但好在远程压缩不会占用服务器资源,也算是一个很好的解决方案了。