详解 WordPress `add_image_size()` 函数源码:如何注册图片尺寸并与 `_wp_attachment_metadata` 关联。

各位观众老爷们,晚上好! 今天咱们来聊聊WordPress里一个非常实在的函数—— add_image_size()。 这家伙虽然看起来不起眼,但却掌控着咱们网站上图片的“身材”,用得好能让网站颜值蹭蹭往上涨,用不好嘛… 那就只能怪自己没好好听课啦!

开场白:图片,网站的门面担当

话说回来,一个网站漂不漂亮,很大程度上取决于图片。 图片清晰度、尺寸、比例,都会影响用户体验。 你总不想看到一个拉伸变形的图片,或者一个巨无霸图片把页面撑爆吧? WordPress 默认提供了一些图片尺寸,比如缩略图、中等尺寸、大型尺寸,但这些往往不够用。 想象一下,你想在博客首页展示一个特定尺寸的图片,或者在文章内容里插入一个方形的缩略图,这时 add_image_size() 就派上大用场了。

add_image_size() 函数:定做你的图片身材

add_image_size() 函数的作用很简单,就是注册一个新的图片尺寸。 它的基本语法如下:

add_image_size( string $name, int $width, int $height, bool|array $crop = false )

参数解释:

  • $name:尺寸名称,这个名字随便你起,但最好有意义,方便以后使用。 比如 'featured-image''square-thumbnail' 等。
  • $width:宽度,单位是像素。
  • $height:高度,单位也是像素。
  • $crop:裁剪模式,这是一个布尔值或者数组,决定了图片在尺寸不匹配时如何处理。

    • false:不裁剪,保持原始比例,可能会导致图片变形或者留白。
    • true:裁剪,以适应指定的宽度和高度,可能会丢失部分图像内容。默认从中心裁剪。
    • array( string|int $x_crop_position, string|int $y_crop_position ): 自定义裁剪位置。$x_crop_position$y_crop_position 可以是字符串 'top', 'center', 'bottom', 'left', 'right',也可以是 0 到 1 之间的数字,表示相对于原始图像的百分比。

源码剖析:add_image_size() 背后的秘密

别看 add_image_size() 函数用起来简单,但它内部可没少干活。 咱们来扒一扒它的源码,看看它到底做了些什么。

// wp-includes/media.php

/**
 * Adds a new image size.
 *
 * @since 2.9.0
 *
 * @global array $_wp_additional_image_sizes
 *
 * @param string       $name   Image size identifier.
 * @param int          $width  Image width in pixels.
 * @param int          $height Image height in pixels.
 * @param bool|array $crop   Optional. Whether to crop images to specified height and width or resize.
 *                           An array can specify positioning of the crop area. Default false.
 * @return true
 */
function add_image_size( $name, $width = 0, $height = 0, $crop = false ) {
    global $_wp_additional_image_sizes;

    $_wp_additional_image_sizes[ $name ] = array(
        'width'  => absint( $width ), // 确保是整数
        'height' => absint( $height ), // 确保是整数
        'crop'   => $crop,
    );

    return true;
}

从源码可以看出, add_image_size() 函数主要做了两件事:

  1. 定义尺寸信息: 它把我们传入的尺寸名称、宽度、高度、裁剪模式等信息,存储到一个全局变量 $_wp_additional_image_sizes 中。 这个变量是个数组,用来保存所有自定义的图片尺寸。
  2. 返回 true 只是简单地返回 true,表示添加成功。

这个 $_wp_additional_image_sizes 全局变量非常重要,它就像一个“图片尺寸登记簿”,记录了所有自定义的图片尺寸信息。 当我们上传图片时,WordPress 会读取这个登记簿,生成对应的缩略图。

_wp_attachment_metadata:图片的“户口本”

当我们上传一张图片到 WordPress 时,WordPress 会为它生成一些元数据,包括图片的原始尺寸、文件路径、以及各种缩略图的信息。 这些元数据都保存在 _wp_attachment_metadata 这个文章元数据字段中。

_wp_attachment_metadata 是一个序列化的数组,里面包含了图片的所有重要信息。 我们可以使用 get_post_meta() 函数来获取它:

$attachment_id = 123; // 替换为你的图片ID
$metadata = get_post_meta( $attachment_id, '_wp_attachment_metadata', true );

// 打印元数据
echo '<pre>';
print_r( $metadata );
echo '</pre>';

这个数组的结构大概是这样的:

Array
(
    [width] => 1920 // 原始宽度
    [height] => 1080 // 原始高度
    [file] => 2023/10/image.jpg // 文件路径
    [sizes] => Array
        (
            [thumbnail] => Array
                (
                    [file] => image-150x150.jpg // 缩略图文件路径
                    [width] => 150 // 缩略图宽度
                    [height] => 150 // 缩略图高度
                    [mime-type] => image/jpeg // MIME 类型
                )

            [medium] => Array
                (
                    [file] => image-300x169.jpg
                    [width] => 300
                    [height] => 169
                    [mime-type] => image/jpeg
                )

            [large] => Array
                (
                    [file] => image-1024x576.jpg
                    [width] => 1024
                    [height] => 576
                    [mime-type] => image/jpeg
                )

            [my-custom-size] => Array // 自定义尺寸
                (
                    [file] => image-500x300.jpg
                    [width] => 500
                    [height] => 300
                    [mime-type] => image/jpeg
                )
        )

    [image_meta] => Array // 图片的 EXIF 信息
        (
            [aperture] => 2.8
            [credit] =>
            [camera] => Canon EOS 5D Mark IV
             =>
            [created_timestamp] => 1698765432
            [copyright] =>
            [focal_length] => 50
            [iso] => 100
            [shutter_speed] => 0.008
            [title] =>
            [orientation] => 1
            [keywords] => Array
                (
                )
        )
)

可以看到,_wp_attachment_metadata 包含了图片的原始尺寸、文件路径、以及各种缩略图的信息。 sizes 数组里存储了所有缩略图的信息,包括 WordPress 默认的缩略图,以及我们通过 add_image_size() 函数添加的自定义尺寸。

关联:add_image_size() 如何影响 _wp_attachment_metadata

当我们使用 add_image_size() 函数注册了一个新的图片尺寸后,WordPress 会在上传图片时,自动生成对应尺寸的缩略图,并将缩略图的信息添加到 _wp_attachment_metadatasizes 数组中。

这个过程主要发生在 wp_generate_attachment_metadata() 函数中。 这个函数负责生成附件的元数据,包括各种缩略图。 它会读取 $_wp_additional_image_sizes 全局变量,遍历所有自定义的图片尺寸,并为每种尺寸生成对应的缩略图。

// 简化的 wp_generate_attachment_metadata() 函数

function wp_generate_attachment_metadata( $attachment_id, $file ) {
    // ...

    // 获取所有自定义的图片尺寸
    global $_wp_additional_image_sizes;

    // 遍历所有自定义的图片尺寸
    foreach ( $_wp_additional_image_sizes as $size => $size_data ) {
        // 生成缩略图
        $resized = image_make_intermediate_size(
            $file,
            $size_data['width'],
            $size_data['height'],
            $size_data['crop']
        );

        if ( $resized ) {
            // 将缩略图信息添加到 $metadata['sizes'] 数组中
            $metadata['sizes'][ $size ] = $resized;
        }
    }

    // ...

    // 更新文章元数据
    wp_update_attachment_metadata( $attachment_id, $metadata );

    return $metadata;
}

从代码可以看出,wp_generate_attachment_metadata() 函数会遍历 $_wp_additional_image_sizes 数组,并调用 image_make_intermediate_size() 函数来生成缩略图。 然后,它会将缩略图的信息添加到 $metadata['sizes'] 数组中,最后通过 wp_update_attachment_metadata() 函数将元数据更新到数据库。

实战演练:添加自定义图片尺寸并使用

光说不练假把式,咱们来实际操作一下,添加一个自定义的图片尺寸,并在主题中使用它。

  1. functions.php 文件中添加以下代码:
add_action( 'after_setup_theme', 'my_theme_setup' );

function my_theme_setup() {
    add_image_size( 'my-custom-size', 500, 300, true ); // 添加一个名为 'my-custom-size' 的尺寸,宽度为 500px,高度为 300px,裁剪模式为 true
}

这段代码会在主题初始化时,注册一个新的图片尺寸。

  1. 上传一张图片到 WordPress。

  2. 在文章或页面中使用该尺寸的图片。

    • 方法一:在编辑器中使用。 在编辑器中插入图片时,你会在“尺寸”选项中看到 my-custom-size 这个选项。 选择它,即可插入对应尺寸的图片。

    • 方法二:在主题模板中使用代码。 在主题模板中,可以使用 wp_get_attachment_image() 函数来获取指定尺寸的图片:

$attachment_id = get_post_thumbnail_id(); // 获取特色图像的 ID
$image = wp_get_attachment_image( $attachment_id, 'my-custom-size' ); // 获取 'my-custom-size' 尺寸的图片
echo $image; // 输出图片 HTML 代码

进阶技巧:自定义裁剪位置

如果默认的中心裁剪不能满足你的需求,你可以自定义裁剪位置。 add_image_size() 函数的 $crop 参数可以接受一个数组,用来指定裁剪位置。

add_image_size( 'my-custom-size', 500, 300, array( 'left', 'top' ) ); // 从左上角裁剪
add_image_size( 'my-custom-size', 500, 300, array( 'center', 'bottom' ) ); // 从底部中心裁剪
add_image_size( 'my-custom-size', 500, 300, array( 0.2, 0.8 ) ); // x轴从20%开始裁剪,y轴从80%开始裁剪

注意事项:

  • regenerate thumbnails: 修改了 add_image_size() 后,需要重新生成缩略图。 可以使用一些插件,比如 "Regenerate Thumbnails",来批量重新生成缩略图。

  • 性能优化: 不要添加过多的图片尺寸,否则会增加服务器的负担,影响网站性能。

  • 主题切换: 自定义的图片尺寸是主题相关的。 如果切换主题,可能需要重新添加 add_image_size() 代码。

总结:

add_image_size() 函数是 WordPress 中一个非常实用的函数,可以帮助我们自定义图片尺寸,让网站的图片更加美观、协调。 掌握了这个函数,就能更好地控制网站的视觉效果,提升用户体验。

表格总结:

函数/变量 作用
add_image_size() 注册一个新的图片尺寸。
$_wp_additional_image_sizes 全局变量,存储所有自定义的图片尺寸信息。
_wp_attachment_metadata 文章元数据字段,存储附件的元数据,包括图片的原始尺寸、文件路径、以及各种缩略图的信息。
wp_generate_attachment_metadata() 生成附件的元数据,包括各种缩略图。它会读取 $_wp_additional_image_sizes 全局变量,遍历所有自定义的图片尺寸,并为每种尺寸生成对应的缩略图。
wp_get_attachment_image() 获取指定附件的图片 HTML 代码。 可以指定图片尺寸。

好了,今天的讲座就到这里。 感谢各位观众老爷的观看! 希望大家能从今天的讲座中学到一些东西,并在实际项目中灵活运用 add_image_size() 函数。 咱们下期再见!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注