跳到正文
图片与多媒体

为什么 WordPress 图片上传后变模糊(以及修复方法)

十有八九图片本身并不模糊——是 WordPress 在上传时把它压缩降尺寸了,现在给你显示的是被限制后的那份副本。从 WordPress 5.3 起,任何

发布于

十有八九图片本身并不模糊——是 WordPress 在上传时把它压缩降尺寸了,现在给你显示的是被限制后的那份副本。从 WordPress 5.3 起,任何宽度或高度超过 2560px 的图片都会被悄悄替换成一份 -scaled 版本,最长边被限制在 2560px,而你的主题拿去撑满首屏大图、全宽区块或高清(Retina)屏幕的,正是这份更小的文件。修复思路是:先证明确实是这么回事,然后要么调高这个阈值,要么就别再上传那些需要比它所在容器还大的图片。

为什么会这样

当你上传一张照片时,WordPress 会运行 wp_create_image_subsizes()(位于 wp-admin/includes/image.php)。如果最长边超过 big_image_size_threshold——默认是 2560px——它就会调用 _wp_image_meta_replace_original(),生成 your-photo-scaled.jpg,并重写附件的元数据,让 full 尺寸现在指向这份缩放后的副本。你真正的原图仍会以 your-photo.jpg 保留在磁盘上,并由 wp_get_original_image_path() 引用,但前台不会用它来显示。每一个中间尺寸、每一个 srcset 候选文件,都是从那份 2560px 的缩放文件生成的,而不是从你上传的原图。

模糊就出在这里。你为一个全出血(full-bleed)页头上传了一张清晰的 4000px 图片。WordPress 把它限制到 2560px。在标准屏幕、1600px 宽的容器里,这没问题。但在 2 倍高清屏上,浏览器大约需要 3200 个真实像素才能把容器填得清晰锐利,而它只有 2560 个,于是就把差额部分放大插值。边缘发虚、图内文字糊成一团——这正是”上传后变模糊”的典型症状。

同一个问题的另一半,是 srcset 挑选了一个过小的尺寸。如果你的主题上报的内容宽度和实际渲染出来的盒子对不上,WordPress 就会把一份 -1024x683-1536x1024 的中间图交给浏览器,然后它被拉伸放大。同样的成因——显示盒子大于可用像素——只是触发点不同。

检查 WordPress 实际提供了什么

别猜。在模糊的图片上点右键,在新标签页里打开它,看 URL 里的文件名。如果它以 -scaled.jpg 结尾,或者带有像 -1024x683.jpg 这样的尺寸后缀,那就确认了:浏览器渲染的是一份降尺寸的衍生图,而不是你上传的原图。你也可以检查(inspect)该元素、读取 currentSrc,看浏览器到底选了哪个候选文件。

在重新上传任何东西之前,想看清全貌,就把图片拖进 WordPress 图片尺寸工具——它会显示 WordPress 会从这个具体文件生成的每一个衍生图,包括是否会创建 -scaled 副本、以及尺寸是多少,这样你事先就能知道你的源图对于要放的位置来说是否够大。

在服务器上,你可以列出每一个被限制的文件:

find wp-content/uploads -name '*-scaled.*'

如何修复,按顺序来

1. 如果你的图片确实需要大于 2560px(大幅首屏图、高清屏、印刷级画质图库),那就调高阈值:

// functions.php or a small mu-plugin
add_filter( 'big_image_size_threshold', function () {
    return 3840; // longest edge, in pixels
} );

或者干脆彻底关掉这个限制:

add_filter( 'big_image_size_threshold', '__return_false' );

2. 重新上传受影响的图片。 这一步是大家会跳过的。修改阈值只对上传生效。已经在媒体库里的图片仍保留旧的元数据,而重新生成缩略图是从被限制的 -scaled 文件重建中间尺寸——它并不会把已经丢掉的分辨率加回来。可靠的做法是:改好过滤器,删掉附件,再重新上传。

3. 如果你的源图本来就 ≤2560px 却仍然模糊, 那问题不在阈值——是显示盒子比图片还大。上传一张更大的源图,或者把容器缩小。要在高清屏上锐利,你的源图分辨率大约需要是它所填充盒子 CSS 像素宽度的两倍。

4. 只有在做完上述步骤之后,再去重新生成缩略图, 让中间尺寸保持一致——但要明白这只是收尾清理,不是治本。

不要做的事

别把 JPEG 质量拉到 100。 WordPress 通过 wp_editor_set_quality 以默认质量 82 进行压缩,而网上一半的建议都叫你去覆盖它:

add_filter( 'wp_editor_set_quality', function () { return 90; } );

用它来减少压缩伪影是没问题的,但一张被拉伸、被放大的图片是分辨率问题,不是压缩问题。从 82 调到 100 会让文件臃肿,而对你看到的那种发虚几乎毫无帮助。

别一遇到问题就下意识地禁用 -scaled 关掉这个限制(有个工具能做这件事)在你确实要提供 2560px 以上图片时是正确选择——但如果你真正的问题是一份过小的中间图被拉伸,那禁用它什么都改变不了,你还白白损失了节省的带宽。先诊断。

别先去怪缓存,也别先去重新生成缩略图。 重新生成读取的是同一份被限制的源图,所以它无法恢复细节。清空 CDN 或页面缓存,也碰不到一个本来在磁盘上就小的文件。

别去动主题的 CSS 或 object-fit 再多的样式也加不出像素来。如果提供的文件以 -scaled 或某个尺寸后缀结尾,那问题出在文件本身,不在布局。

还是搞不定?

如果你已经确认提供的文件就是你的全分辨率上传原图——没有 -scaled,没有尺寸后缀——它却依然发虚,那就查一下是不是某个插件(图片优化器、CDN 图片缩放器,或懒加载库)把你的 src 改写成了一个压缩过的代理地址。把图片跑一遍 图片尺寸工具,确认 WordPress 本应生成什么,再拿它和浏览器实际加载的内容做对比。当这两者对不上时,罪魁祸首就在 WordPress 和浏览器之间的某个环节。