深入理解 WordPress `wp_get_attachment_image_src()` 函数的源码:如何根据图片尺寸获取 URL 和尺寸信息。

各位观众,早上好!我是你们今天的WordPress源码探险导游,咱们今天就来扒一扒wp_get_attachment_image_src()这个函数的老底,看看它到底是怎么把一张图片,按照你的尺寸要求,给你变出对应的URL和尺寸信息的。准备好你们的放大镜,咱们开始吧!

一、wp_get_attachment_image_src():你的图片百宝箱

首先,咱们得搞清楚wp_get_attachment_image_src()是干嘛的。简单来说,它就像一个图片百宝箱,你告诉它图片的ID和想要的尺寸,它就能给你返回图片的URL、宽度和高度。这在WordPress主题开发中简直太常见了,比如你想在文章列表页显示缩略图,或者在详情页显示不同尺寸的大图,都离不开它。

二、源码寻宝:从入口开始

咱们直接进入源码的世界,看看wp-includes/media.php文件里的wp_get_attachment_image_src()函数。为了方便理解,我稍微简化一下源码,保留核心逻辑:

function wp_get_attachment_image_src( $attachment_id, $size = 'thumbnail', $icon = false ) {
    $attachment_id = intval( $attachment_id );
    if ( ! is_int( $attachment_id ) || $attachment_id < 1 ) {
        return false;
    }

    $image = false;
    $size = $size ? $size : 'thumbnail';

    $image = wp_get_attachment_image_srcset( $attachment_id, $size, $icon );

    if ( $image ) {
        return array( $image[0], $image[1], $image[2], true ); // url, width, height, is_intermediate
    }

    $image = image_downsize( $attachment_id, $size );

    if ( ! $image ) {
        return false;
    }

    return $image;
}

别害怕,咱们一步步来。

  1. 参数校验:首先,它会检查你传入的$attachment_id是不是一个有效的整数。如果不是,直接返回false,告诉你参数不对。

  2. 默认尺寸:如果你没有指定$size,它会默认使用'thumbnail',也就是缩略图尺寸。

  3. srcset抢先看:它会优先调用wp_get_attachment_image_srcset来生成srcset属性的值。如果srcset生成成功,就直接返回。

  4. 核心降维打击:image_downsize():如果srcset生成失败,或者WordPress版本不支持,那就轮到image_downsize()出场了。这个函数才是真正负责根据尺寸调整图片大小的。

  5. 最终结果:如果image_downsize()也失败了,那就返回false,告诉你图片找不到了。否则,返回一个数组,包含图片的URL、宽度和高度。

三、image_downsize():尺寸魔法师

image_downsize()才是这个函数的核心,它位于wp-includes/media.php中。同样,我们简化一下源码:

function image_downsize( $attachment_id, $size = 'medium' ) {
    $imagedata = wp_get_attachment_metadata( $attachment_id );

    if ( ! $imagedata ) {
        return false;
    }

    $width  = $height = 0;
    $is_intermediate = true;
    $img_url = wp_get_attachment_url( $attachment_id );

    // Get the sizes
    $sizes = get_intermediate_image_sizes();

    // Check for registered image sizes first.
    if ( in_array( $size, $sizes, true ) ) {
        $resized = image_get_intermediate_size( $attachment_id, $size );
        if ( $resized ) {
            $img_url = $resized['url'];
            $width = $resized['width'];
            $height = $resized['height'];
        }
    }

    // If there's different width/height, we can crop the image.
    if ( intval( $width ) > 0 && intval( $height ) > 0 ) {
        return array( $img_url, intval( $width ), intval( $height ), $is_intermediate );
    }

    // Check if the unedited image is smaller than the requested size.
    if ( isset( $imagedata['width'] ) && isset( $imagedata['height'] ) ) {
        $original_width  = intval( $imagedata['width'] );
        $original_height = intval( $imagedata['height'] );

        if ( $original_width > 0 && $original_height > 0 ) {
            if ( $original_width <= $width || $original_height <= $height ) {
                return array( $img_url, $original_width, $original_height, $is_intermediate );
            }
        }
    }

    // Finally, fall back to the full size image.
    $width  = intval( $imagedata['width'] );
    $height = intval( $imagedata['height'] );
    return array( $img_url, $width, $height, $is_intermediate );
}
  1. 获取图片元数据:首先,它会通过wp_get_attachment_metadata()获取图片的元数据,包括图片的宽度、高度、文件路径等等。如果获取失败,说明图片不存在,直接返回false

  2. 获取原始图片URL:通过wp_get_attachment_url()获取原始图片的URL,作为后续操作的基础。

  3. 检查注册的图片尺寸get_intermediate_image_sizes()获取WordPress注册的所有图片尺寸,比如thumbnailmediumlarge等等。然后,它会检查你传入的$size是否在这些注册的尺寸中。

  4. 查找已生成的缩略图:如果$size是注册的尺寸之一,它会尝试通过image_get_intermediate_size()查找是否已经生成了对应尺寸的缩略图。如果找到了,就直接返回缩略图的URL、宽度和高度。

  5. 原始图片尺寸小于请求尺寸:如果$size不是注册的尺寸,或者没有找到对应尺寸的缩略图,它会检查原始图片的尺寸是否小于你请求的尺寸。如果是,就直接返回原始图片的URL、宽度和高度。

  6. 兜底策略:返回原始图片:如果以上所有条件都不满足,那就说明你请求的尺寸大于原始图片,或者发生了其他错误。在这种情况下,它会返回原始图片的URL、宽度和高度。

四、image_get_intermediate_size():缩略图查找器

image_get_intermediate_size()函数负责查找已经生成的缩略图。

function image_get_intermediate_size( $attachment_id, $size = 'thumbnail' ) {
    $imagedata = wp_get_attachment_metadata( $attachment_id );

    if ( empty( $imagedata['sizes'] ) ) {
        return false;
    }

    if ( empty( $imagedata['sizes'][ $size ] ) ) {
        return false;
    }

    $intermediate_size = $imagedata['sizes'][ $size ];

    $image_url = wp_get_attachment_url( $attachment_id );
    $image_basename = wp_basename( $image_url );

    if ( false === strpos( $image_url, $intermediate_size['file'] ) ) {
        $dir = trailingslashit( dirname( $image_url ) );
        $url = $dir . $intermediate_size['file'];
    } else {
        $url = str_replace( $image_basename, $intermediate_size['file'], $image_url );
    }

    $intermediate_size['url'] = $url;

    return $intermediate_size;
}
  1. 获取图片元数据:和image_downsize()一样,它首先获取图片的元数据。

  2. 检查是否存在sizes:它会检查元数据中是否存在sizes键。这个键包含了所有已经生成的缩略图的信息。如果不存在,说明还没有生成任何缩略图,返回false

  3. 检查指定尺寸是否存在:它会检查sizes中是否存在你请求的$size。如果不存在,说明没有生成对应尺寸的缩略图,返回false

  4. 构建缩略图URL:如果找到了对应尺寸的缩略图,它会根据缩略图的文件名和原始图片的URL,构建出缩略图的完整URL。

  5. 返回缩略图信息:最后,它会返回一个数组,包含缩略图的URL、宽度和高度。

五、wp_get_attachment_metadata():元数据侦探

wp_get_attachment_metadata()函数负责从数据库中获取图片的元数据。

function wp_get_attachment_metadata( $attachment_id, $unfiltered = false ) {
    $attachment_id = intval( $attachment_id );
    if ( ! is_int( $attachment_id ) || $attachment_id < 1 ) {
        return false;
    }

    $data = wp_get_post_metadata( $attachment_id, '_wp_attachment_metadata', true );

    if ( empty( $data ) ) {
        return false;
    }

    if ( $unfiltered ) {
        return $data;
    }

    return apply_filters( 'wp_get_attachment_metadata', $data, $attachment_id );
}

这个函数比较简单,它直接从wp_postmeta表中获取_wp_attachment_metadata这个meta key对应的值。这个值是一个序列化的数组,包含了图片的各种信息,比如宽度、高度、文件路径、缩略图信息等等。

六、尺寸的奥秘:WordPress如何定义尺寸

WordPress默认定义了一些图片尺寸,比如thumbnailmediumlargefull。你也可以在functions.php文件中自定义图片尺寸。

// 添加自定义图片尺寸
add_image_size( 'my-custom-size', 300, 200, true ); // 300px宽,200px高,裁剪模式

这里的true表示裁剪模式,WordPress会裁剪图片以适应指定的尺寸。如果设置为false,则会按比例缩放图片,可能会导致图片小于指定的尺寸。

七、实战演练:用起来才算数

现在,咱们来实际用一下wp_get_attachment_image_src()函数。

<?php
$attachment_id = get_post_thumbnail_id(); // 获取文章特色图像ID

if ( $attachment_id ) {
    $image_data = wp_get_attachment_image_src( $attachment_id, 'medium' ); // 获取中等尺寸的图片信息

    if ( $image_data ) {
        $image_url = $image_data[0]; // 图片URL
        $image_width = $image_data[1]; // 图片宽度
        $image_height = $image_data[2]; // 图片高度

        echo '<img src="' . esc_url( $image_url ) . '" width="' . esc_attr( $image_width ) . '" height="' . esc_attr( $image_height ) . '" alt="' . get_the_title() . '">';
    } else {
        echo '找不到图片';
    }
} else {
    echo '文章没有特色图像';
}
?>

这段代码会获取文章的特色图像,然后使用wp_get_attachment_image_src()函数获取中等尺寸的图片信息,最后将图片显示在页面上。

八、总结:图片处理的万花筒

wp_get_attachment_image_src()函数是一个非常实用的工具,它可以根据你的需要,获取不同尺寸的图片URL和尺寸信息。它的核心在于image_downsize()函数,这个函数会根据注册的尺寸、原始图片尺寸以及你的请求,智能地选择合适的图片。

表格总结

函数名 功能 所在文件
wp_get_attachment_image_src() 根据图片ID和尺寸,获取图片URL和尺寸信息 wp-includes/media.php
image_downsize() 根据尺寸调整图片大小 wp-includes/media.php
image_get_intermediate_size() 查找已经生成的缩略图 wp-includes/media.php
wp_get_attachment_metadata() 获取图片的元数据 wp-includes/media.php

希望今天的源码探险之旅能帮助你更好地理解wp_get_attachment_image_src()函数。下次再遇到图片尺寸的问题,你就知道该怎么做了! 记住:代码的世界,永远充满着惊喜和挑战! 下次再见!

发表回复

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