WordPress 原生函数 wp_get_attachment_image_srcset,可以实现响应式图片加载,但这只是针对媒体库图片,在网站开发,有时图片素菜放置主题目录下,这时原生函数就无法调用了,为了完全控制图片质量和版本,为此开发自定义响应式图片加载。
◆ 图片宽度数值设计
断点范围 | 宽度 | 适用场景 | DPR处理 |
≤480px | 600w | 手机竖屏 | 2x自动适配 |
481-768px | 900w | 手机横屏/小平板 | 浏览器自动优化 |
769-1024px | 1200w | 平板/小笔记本 | 浏览器自动优化 |
1025-1440px | 1600w | 主流桌面显示器 | 浏览器自动优化 |
≥1441px | 2000w | 4K/大屏设备 | 浏览器自动优化 |
比例 | 适用场景 | 尺寸(宽×高) |
16:9 | 视频封面、横幅图 | 1920×1080 |
4:3 | 博客文章配图 | 1200×900 |
1:1 | 头像、图标 | 600×600 |
3:2 | 摄影作品 | 1200×800 |
♦ 代码实现
参考上面表格,结合实际业务场景,我打算用4张不同尺寸图片。分别是640px、960px、1280px、1920px。刚好和DPR倍数适配,如640适配2倍DPR,则是1280px。3倍则是1920px。
◆ class-responsive-image-handler.php
<?php
namespace CHENZZ_THEME\Inc;
use CHENZZ_THEME\Inc\Traits\Singleton;
/**
* Responsive_Image_Handler 类负责处理非媒体库图片的响应式显示
* 它使用单例模式确保整个应用中只有一个该类的实例
*/
class Responsive_Image_Handler {
use Singleton;
protected function __construct() {
// load class.
}
/**
* 生成图片的完整 URL
*
* @param string $src 图片文件名(不包含扩展名)
* @param string $format 图片格式,如 'webp' 或 'jpg'
* @return string 生成的图片完整 URL
*/
public function generate_source($src, $format) {
$file = "{$src}.{$format}";
return esc_url(get_template_directory_uri().'/assets/src/img/'.$file);
}
/**
* 获取响应式图片的 src 或 srcset 信息
*
* @param string $filename 图片文件名(不包含尺寸和扩展名)
* @param string $size 图片尺寸,默认为 'full',表示生成完整的 srcset
* @param string $defaultFormat 图片默认格式,默认为 'jpg'
* @return string 单尺寸请求时返回图片的 src URL,完整请求时返回 srcset 字符串
*/
public function get_theme_responsive_image($filename, $size = 'full', $defaultFormat = 'jpg') {
// 基础配置,定义图片存储的基础目录
$base_dir = '/assets/src/img/';
$sizes_config = [
'sm' => ['width' => 640, 'dpr' => [1,2], 'format' => ['webp', 'jpg']],
'md' => ['width' => 960, 'dpr' => [1,2], 'format' => ['webp', 'jpg']],
'lg' => ['width' => 1280, 'dpr' => [1], 'format' => ['webp', 'jpg']],
'xl' => ['width' => 1920, 'dpr' => [1], 'format' => ['webp', 'jpg']]
];
// 安全检测,如果请求的尺寸不在配置中且不是 'full',则返回 fallback 图片的 URL
if (!array_key_exists($size, $sizes_config) && $size !== 'full') {
return esc_url(get_template_directory_uri().$base_dir.'fallback.jpg');
}
// 单尺寸请求处理,如果请求的不是完整的 srcset
if ($size !== 'full') {
// 获取请求尺寸的配置信息
$target = $sizes_config[$size];
// 拼接图片文件名(包含尺寸)
$src = "{$filename}-{$target['width']}w";
// 调用 generate_source 方法生成该图片的 URL 并返回
return $this->generate_source($src, $defaultFormat);
}
// 生成完整 srcset
$sources = [];
// 遍历所有尺寸配置
foreach ($sizes_config as $breakpoint) {
// 遍历每个尺寸对应的设备像素比(DPR)
foreach ($breakpoint['dpr'] as $dpr) {
$width = $breakpoint['width'] * $dpr;
$src = "{$filename}-{$width}w";
// 只添加指定格式的图片链接
if (in_array($defaultFormat, $breakpoint['format'])) {
// 调用 generate_source 方法生成图片 URL,并添加宽度描述符,然后存入数组
$sources[] = $this->generate_source($src, $defaultFormat) . " {$width}w";
}
}
}
// 将数组中的元素用逗号连接成字符串,并去除重复项,最后返回该字符串作为 srcset
return implode(', ', array_unique($sources));
}
}
html实现
<? php
$responsive_image_handler_class = \CHENZZ_THEME\Inc\Responsive_Image_Handler::get_instance();
?>
<picture>
<source type="image/webp" srcset="<?php echo $responsive_image_handler_class->get_theme_responsive_image('about-fanhua5', 'full', 'webp'); ?>">
<img class="responsive-bg-image"
src="<?php echo $responsive_image_handler_class->get_theme_responsive_image('about-fanhua5', 'lg', 'jpg'); ?>"
srcset="<?php echo $responsive_image_handler_class->get_theme_responsive_image('about-fanhua5', 'full', 'jpg'); ?>"
sizes="(max-width: 640px) 640px,
(max-width: 960px) 960px,
(max-width: 1280px) 1280px,
1920px"
alt="<?php esc_attr_e('《繁花》人物关系全景图', 'textdomain'); ?>"
loading="lazy"
decoding="async">
</picture>
浏览器显示结果
<picture>
<source type="image/webp" srcset="https://example3.chenzhuzhen.cn/wp-content/themes/example3/assets/src/img/about-fanhua5-640w.webp 640w,
https://example3.chenzhuzhen.cn/wp-content/themes/example3/assets/src/img/about-fanhua5-1280w.webp 1280w,
https://example3.chenzhuzhen.cn/wp-content/themes/example3/assets/src/img/about-fanhua5-960w.webp 960w,
https://example3.chenzhuzhen.cn/wp-content/themes/example3/assets/src/img/about-fanhua5-1920w.webp 1920w">
<img class="responsive-bg-image"
src="https://example3.chenzhuzhen.cn/wp-content/themes/example3/assets/src/img/about-fanhua5-1280w.jpg"
srcset="https://example3.chenzhuzhen.cn/wp-content/themes/example3/assets/src/img/about-fanhua5-640w.jpg 640w,
https://example3.chenzhuzhen.cn/wp-content/themes/example3/assets/src/img/about-fanhua5-1280w.jpg 1280w,
https://example3.chenzhuzhen.cn/wp-content/themes/example3/assets/src/img/about-fanhua5-960w.jpg 960w,
https://example3.chenzhuzhen.cn/wp-content/themes/example3/assets/src/img/about-fanhua5-1920w.jpg 1920w"
sizes="(max-width: 640px) 640px,
(max-width: 960px) 960px,
(max-width: 1280px) 1280px,
1920px"
alt="《繁花》人物关系全景图"
loading="lazy"
decoding="async">
</picture>
♦ 媒体库相关函数
◆ wp_get_attachment_metadata
$image_meta = wp_get_attachment_metadata( $attachment_id );
Array
(
[width] => 2000
[height] => 1411
[file] => 2025/02/fanhua-10-5.jpg
[filesize] => 427780
[sizes] => Array
(
)
[image_meta] => Array
(
[aperture] => 0
[credit] =>
[camera] =>
=>
[created_timestamp] => 0
[copyright] =>
[focal_length] => 0
[iso] => 0
[shutter_speed] => 0
[title] =>
[orientation] => 1
[keywords] => Array
(
)
)
)
查看php当前内容限制
echo '<pre>';
print_r('当前 WordPress 内存限制: '. ini_get('memory_limit'));
wp_die();
// 当前 WordPress 内存限制: 128M