按比例缩放,留白(推荐用于商品图、展示图)
这种方式会保持图片原始比例,将图片完整显示在缩略框内,多余的部分用背景色填充(留白),这样图片不会变形,但会有部分区域是空白的。

修改方法:
-
找到并打开
include/image.func.php文件,这是织梦处理图片的核心函数文件。 -
找到
thumb()函数,找到下面这行代码:$destImage = imagecreatetruecolor($toW, $toH);
-
在它后面添加填充背景色的代码,为了通用性,我们使用白色作为背景色,完整的代码块应该是这样的:
(图片来源网络,侵删)// 创建目标图像 $destImage = imagecreatetruecolor($toW, $toH); // ====== 添加以下代码,用于填充白色背景,防止变形 ====== $white = imagecolorallocate($destImage, 255, 255, 255); imagefilledrectangle($destImage, 0, 0, $toW, $toH, $white); // ===================================================== // ... 后面的代码保持不变 ...
-
修改缩放逻辑,找到
thumb()函数中处理缩放方式的if语句块,默认情况下,它使用的是if ($toWH['w'] < $toWH['h'])这种方式来裁剪,我们需要把它改成按比例缩放。找到类似这样的代码块:
// ... 前面的代码 ... if ($toWH['w'] < $toWH['h']) { $h = $toH; $w = $srcW * ($toH / $srcH); $x = -(($w - $toW) / 2); $y = 0; } else { $w = $toW; $h = $srcH * ($toW / $srcW); $x = 0; $y = -(($h - $toH) / 2); } // ... 后面的代码 ...将它替换为按比例缩放并居中显示的代码:
// ... 前面的代码 ... // 计算缩放比例 $ratio = min($toW / $srcW, $toH / $srcH); $w = $srcW * $ratio; $h = $srcH * $ratio; // 计算居中位置 $x = ($toW - $w) / 2; $y = ($toH - $h) / 2; // ... 后面的代码 ...
经过以上两步修改,thumb() 函数就会生成一个尺寸固定、图片完整、比例不变、背景留白的缩略图,这是解决变形问题最常用、最稳妥的方法。

按比例裁剪,不留白(推荐用于封面图、头像)
这种方式会保持图片比例,从图片的中心区域裁剪出一块与你设定尺寸比例相同的部分,这样图片不会变形,也不会留白,但可能会裁掉图片的边缘部分。
修改方法:
这个方案同样需要修改 include/image.func.php 文件,但逻辑与方案一不同。
-
打开
include/image.func.php文件。 -
找到
thumb()函数,找到计算缩放比例和位置的逻辑部分。 -
替换为裁剪模式的代码:
// ... 前面的代码 ... // 计算裁剪区域 $ratio_w = $toW / $srcW; $ratio_h = $toH / $srcH; if ($ratio_w > $ratio_h) { // 如果目标宽高比大于原图宽高比,则高度先达到目标 $h = $toH; $w = $srcW * ($toH / $srcH); $x = ($toW - $w) / 2; $y = 0; } else { // 如果目标宽高比小于等于原图宽高比,则宽度先达到目标 $w = $toW; $h = $srcH * ($toW / $srcW); $x = 0; $y = ($toH - $h) / 2; } // ... 后面的代码 ...这个逻辑和方案一的逻辑看起来很像,但核心区别在于
imagecopyresampled函数的使用方式,在thumb()函数的末尾,有一行关键代码:imagecopyresampled($destImage, $srcImage, $x, $y, 0, 0, $w, $h, $srcW, $srcH);对于方案一(缩放),
$x和$y是目标画布上的位置,目的是将缩小的图片居中放置。 对于方案二(裁剪),$x和$y是源图片$srcImage上的起始坐标,目的是从源图片上裁剪出一个区域。你需要将上面代码中的$x和$y的计算逻辑稍作调整,使其从源图上计算裁剪区域。修正后的裁剪逻辑代码:
// ... 前面的代码 ... // 计算裁剪区域(从源图上计算) $ratio_w = $toW / $srcW; $ratio_h = $toH / $srcH; if ($ratio_w > $ratio_h) { // 高度先达到目标,宽度超出,需要裁剪左右 $h = $toH; $w = $srcW * ($toH / $srcH); $src_x = ($srcW - $w) / 2; // 源图的起始X坐标 $src_y = 0; // 源图的起始Y坐标 } else { // 宽度先达到目标,高度超出,需要裁剪上下 $w = $toW; $h = $srcH * ($toW / $srcW); $src_x = 0; // 源图的起始X坐标 $src_y = ($srcH - $h) / 2; // 源图的起始Y坐标 } // 在目标画布上,图片从 (0,0) 开始绘制 $dst_x = 0; $dst_y = 0; // ... 后面的代码 ... -
修改
imagecopyresampled函数调用: 将原来的:imagecopyresampled($destImage, $srcImage, $x, $y, 0, 0, $w, $h, $srcW, $srcH);修改为:imagecopyresampled($destImage, $srcImage, $dst_x, $dst_y, $src_x, $src_y, $w, $h, $w, $h);(注意:最后两个参数是源图上裁剪区域的宽高,这里用$w, $h,因为我们裁剪的就是计算出的这个区域)。
方案二通过改变裁剪的源区域,实现了从中心点裁剪的效果,确保了缩略图的主体内容完整且不变形。
动态调用,按需选择(最灵活)
如果你想在不同的地方使用不同的缩略图效果(比如列表图用方案一,封面图用方案二),最好的方法是创建一个新的函数,然后在模板中根据需要调用。
步骤:
- 在
include/image.func.php中复制thumb()函数,并重命名,thumb_fixed()。 - 在
thumb_fixed()函数内部,直接使用方案一或方案二的代码逻辑。 - 在模板文件中,你可以使用
{dede:field name='litpic' function='thumb_fixed(@me, 宽度, 高度)'/}的方式来调用。
这样,你就可以在不影响原有 thumb() 函数的情况下,灵活地生成不同样式的缩略图。
最终建议与注意事项
- 首选方案一:对于大多数网站(如文章列表、商品列表),方案一(按比例缩放,留白) 是最安全、最不容易出错的,它保证了图片内容的完整性,只是背景色可能需要根据你的网站风格调整。
- 备选方案二:如果你的缩略图是用于封面、轮播图等需要充满整个容器且不能有留白的地方,方案二(按比例裁剪) 是最佳选择。
- 修改前备份:在修改
include/image.func.php文件之前,务必备份原文件!以防修改出错导致网站图片无法生成。 - 清空缓存:修改完代码后,需要到织梦后台的【系统】-【SQL命令行工具】中执行
DELETE FROM dede_arctiny;和DELETE FROM dede_archives;来清空文章表,或者直接重新生成所有文章的HTML,这样缩略图才会重新生成并应用新规则。 - 检查水印:如果你的缩略图需要加水印,确保水印的位置计算逻辑在新代码中依然正确,通常方案一和方案二的修改不会影响水印的添加。
通过以上方法,你就可以彻底解决织梦CMS缩略图变形的问题,让你的网站图片显示更加专业和美观。
