函数文档

wp_image_editor()

💡 云策文档标注

概述

wp_image_editor() 函数用于加载 WordPress 的图像编辑界面,处理附件图像的编辑操作,包括裁剪、旋转、缩放等功能。它生成 HTML 界面并集成 JavaScript 交互,支持参数传递和错误消息显示。

关键要点

  • 函数参数:$post_id(必需,附件 ID)和 $msg(可选,用于显示更新或错误消息的对象)。
  • 核心功能:生成图像编辑器的 HTML 结构,包括工具栏(如裁剪、旋转按钮)、图像预览区域和设置面板。
  • 数据处理:使用 wp_get_attachment_metadata() 获取图像元数据,检查备份尺寸以支持恢复操作,并计算缩放比例。
  • Hook 支持:通过 apply_filters('image_edit_thumbnails_separately', $show) 允许单独编辑缩略图。
  • 安全措施:使用 wp_create_nonce() 生成安全令牌,并集成 esc_html_e() 等函数进行输出转义。

代码示例

function wp_image_editor( $post_id, $msg = false ) {
    $nonce     = wp_create_nonce( "image_editor-$post_id" );
    $meta      = wp_get_attachment_metadata( $post_id );
    $thumb     = image_get_intermediate_size( $post_id, 'thumbnail' );
    $sub_sizes = isset( $meta['sizes'] ) && is_array( $meta['sizes'] );
    $note      = '';

    if ( isset( $meta['width'], $meta['height'] ) ) {
        $big = max( $meta['width'], $meta['height'] );
    } else {
        die( __( 'Image data does not exist. Please re-upload the image.' ) );
    }

    $sizer = $big > 600 ? 600 / $big : 1;

    $backup_sizes = get_post_meta( $post_id, '_wp_attachment_backup_sizes', true );
    $can_restore  = false;

    if ( ! empty( $backup_sizes ) && isset( $backup_sizes['full-orig'], $meta['file'] ) ) {
        $can_restore = wp_basename( $meta['file'] ) !== $backup_sizes['full-orig']['file'];
    }

    if ( $msg ) {
        if ( isset( $msg->error ) ) {
            $note = "$msg->error";
        } elseif ( isset( $msg->msg ) ) {
            $note = "$msg->msg";
        }
    }

    $edit_thumbnails_separately = (bool) apply_filters( 'image_edit_thumbnails_separately', false );
}

注意事项

  • 函数依赖于 JavaScript(如 imageEdit 对象)处理前端交互,确保相关脚本已加载。
  • 图像数据不存在时会终止执行并显示错误消息,需确保附件 ID 有效。
  • 使用非标准 HTML 属性(如 onblur)进行事件绑定,建议在主题或插件中保持兼容性。
  • 支持通过 Hook 自定义功能,如 image_edit_thumbnails_separately 过滤缩略图编辑设置。

📄 原文内容

Loads the WP image-editing interface.

Parameters

$post_idintrequired
Attachment post ID.
$msgfalse|objectoptional
Message to display for image editor updates or errors.

Default:false

Source

function wp_image_editor( $post_id, $msg = false ) {
$nonce = wp_create_nonce( "image_editor-$post_id" );
$meta = wp_get_attachment_metadata( $post_id );
$thumb = image_get_intermediate_size( $post_id, 'thumbnail' );
$sub_sizes = isset( $meta['sizes'] ) && is_array( $meta['sizes'] );
$note = '';

if ( isset( $meta['width'], $meta['height'] ) ) {
$big = max( $meta['width'], $meta['height'] );
} else {
die( __( 'Image data does not exist. Please re-upload the image.' ) );
}

$sizer = $big > 600 ? 600 / $big : 1;

$backup_sizes = get_post_meta( $post_id, '_wp_attachment_backup_sizes', true );
$can_restore = false;

if ( ! empty( $backup_sizes ) && isset( $backup_sizes['full-orig'], $meta['file'] ) ) {
$can_restore = wp_basename( $meta['file'] ) !== $backup_sizes['full-orig']['file'];
}

if ( $msg ) {
if ( isset( $msg->error ) ) {
$note = "<div class='notice notice-error' role='alert'><p>$msg->error</p></div>";
} elseif ( isset( $msg->msg ) ) {
$note = "<div class='notice notice-success' role='alert'><p>$msg->msg</p></div>";
}
}

/**
* Shows the settings in the Image Editor that allow selecting to edit only the thumbnail of an image.
*
* @since 6.3.0
*
* @param bool $show Whether to show the settings in the Image Editor. Default false.
*/
$edit_thumbnails_separately = (bool) apply_filters( 'image_edit_thumbnails_separately', false );

?>
<div class="imgedit-wrap wp-clearfix">
<div id="imgedit-panel-<?php echo $post_id; ?>">

<div class="imgedit-panel-content imgedit-panel-tools wp-clearfix">
<div class="imgedit-menu wp-clearfix">
<button type="button" onclick="imageEdit.toggleCropTool( <?php echo "$post_id, '$nonce'"; ?>, this );" aria-expanded="false" aria-controls="imgedit-crop" class="imgedit-crop button disabled" disabled></button>
<button type="button" class="imgedit-scale button" onclick="imageEdit.toggleControls(this);" aria-expanded="false" aria-controls="imgedit-scale"></button>
<div class="imgedit-rotate-menu-container">
<button type="button" aria-controls="imgedit-rotate-menu" class="imgedit-rotate button" aria-expanded="false" onclick="imageEdit.togglePopup(this)" onblur="imageEdit.monitorPopup()"></button>
<div id="imgedit-rotate-menu" class="imgedit-popup-menu">
get_post_mime_type( $post_id ),
'methods' => array( 'rotate' ),
)
) ) {
$note_no_rotate = '';
?>
<button type="button" class="imgedit-rleft button" onkeydown="imageEdit.browsePopup(event, this)" onclick="imageEdit.rotate( 90, <?php echo "$post_id, '$nonce'"; ?>, this)" onblur="imageEdit.monitorPopup()"></button>
<button type="button" class="imgedit-rright button" onkeydown="imageEdit.browsePopup(event, this)" onclick="imageEdit.rotate(-90, <?php echo "$post_id, '$nonce'"; ?>, this)" onblur="imageEdit.monitorPopup()"></button>
<button type="button" class="imgedit-rfull button" onkeydown="imageEdit.browsePopup(event, this)" onclick="imageEdit.rotate(180, <?php echo "$post_id, '$nonce'"; ?>, this)" onblur="imageEdit.monitorPopup()"></button>
<em>' . __( 'Image rotation is not supported by your web host.' ) . '</em></p>';
?>
<button type="button" class="imgedit-rleft button disabled" disabled></button>
<button type="button" class="imgedit-rright button disabled" disabled></button>

<hr />
<button type="button" onkeydown="imageEdit.browsePopup(event, this)" onclick="imageEdit.flip(1, <?php echo "$post_id, '$nonce'"; ?>, this)" onblur="imageEdit.monitorPopup()" class="imgedit-flipv button"></button>
<button type="button" onkeydown="imageEdit.browsePopup(event, this)" onclick="imageEdit.flip(2, <?php echo "$post_id, '$nonce'"; ?>, this)" onblur="imageEdit.monitorPopup()" class="imgedit-fliph button"></button>

</div>
</div>
</div>
<div class="imgedit-submit imgedit-menu">
<button type="button" id="image-undo-<?php echo $post_id; ?>" onclick="imageEdit.undo(<?php echo "$post_id, '$nonce'"; ?>, this)" class="imgedit-undo button disabled" disabled></button>
<button type="button" id="image-redo-<?php echo $post_id; ?>" onclick="imageEdit.redo(<?php echo "$post_id, '$nonce'"; ?>, this)" class="imgedit-redo button disabled" disabled></button>
<button type="button" onclick="imageEdit.close(<?php echo $post_id; ?>, 1)" class="button imgedit-cancel-btn"></button>
<button type="button" onclick="imageEdit.save(<?php echo "$post_id, '$nonce'"; ?>)" disabled="disabled" class="button button-primary imgedit-submit-btn"></button>
</div>
</div>

<div class="imgedit-panel-content wp-clearfix">
<div class="imgedit-tools">
<input type="hidden" id="imgedit-nonce-<?php echo $post_id; ?>" value="<?php echo $nonce; ?>" />
<input type="hidden" id="imgedit-sizer-<?php echo $post_id; ?>" value="<?php echo $sizer; ?>" />
<input type="hidden" id="imgedit-history-<?php echo $post_id; ?>" value="" />
<input type="hidden" id="imgedit-undone-<?php echo $post_id; ?>" value="0" />
<input type="hidden" id="imgedit-selection-<?php echo $post_id; ?>" value="" />
<input type="hidden" id="imgedit-x-<?php echo $post_id; ?>" value="<?php echo isset( $meta['width'] ) ? $meta['width'] : 0; ?>" />
<input type="hidden" id="imgedit-y-<?php echo $post_id; ?>" value="<?php echo isset( $meta['height'] ) ? $meta['height'] : 0; ?>" />

<div id="imgedit-crop-<?php echo $post_id; ?>" class="imgedit-crop-wrap">
<div class="imgedit-crop-grid"></div>
<img id="image-preview-<?php echo $post_id; ?>" onload="imageEdit.imgLoaded('<?php echo $post_id; ?>')"
src="<?php echo esc_url( admin_url( 'admin-ajax.php', 'relative' ) ) . '?action=imgedit-preview&_ajax_nonce=' . $nonce . '&postid=' . $post_id . '&rand=' . rand( 1, 99999 ); ?>" alt="" />

</div>
</div>
<div class="imgedit-settings">
<div class="imgedit-tool-active">
<div class="imgedit-group">
<div id="imgedit-scale" tabindex="-1" class="imgedit-group-controls">
<div class="imgedit-group-top">
<h2></h2>
<button type="button" class="dashicons dashicons-editor-help imgedit-help-toggle" onclick="imageEdit.toggleHelp(this);" aria-expanded="false"><span class="screen-reader-text">

</span></button>
<div class="imgedit-help">
<p></p>
</div>

<p>
' . $meta['width'] . ' × ' . $meta['height'] . '</span>'
);
?>
</p>

<div class="imgedit-submit">
<fieldset class="imgedit-scale-controls">
<legend></legend>
<div class="nowrap">
<label for="imgedit-scale-width-<?php echo $post_id; ?>" class="screen-reader-text">

</label>
<input type="number" step="1" min="0" max="<?php echo isset( $meta['width'] ) ? $meta['width'] : ''; ?>" aria-describedby="imgedit-scale-warn-<?php echo $post_id; ?>" id="imgedit-scale-width-<?php echo $post_id; ?>" onkeyup="imageEdit.scaleChanged(<?php echo $post_id; ?>, 1, this)" onblur="imageEdit.scaleChanged(<?php echo $post_id; ?>, 1, this)" value="<?php echo isset( $meta['width'] ) ? $meta['width'] : 0; ?>" />
<span class="imgedit-separator" aria-hidden="true">×</span>
<label for="imgedit-scale-height-<?php echo $post_id; ?>" class="screen-reader-text"></label>
<input type="number" step="1" min="0" max="<?php echo isset( $meta['height'] ) ? $meta['height'] : ''; ?>" aria-describedby="imgedit-scale-warn-<?php echo $post_id; ?>" id="imgedit-scale-height-<?php echo $post_id; ?>" onkeyup="imageEdit.scaleChanged(<?php echo $post_id; ?>, 0, this)" onblur="imageEdit.scaleChanged(<?php echo $post_id; ?>, 0, this)" value="<?php echo isset( $meta['height'] ) ? $meta['height'] : 0; ?>" />
<button id="imgedit-scale-button" type="button" onclick="imageEdit.action(<?php echo "$post_id, '$nonce'"; ?>, 'scale')" class="button button-primary"></button>
</div>
<span class="imgedit-scale-warn" id="imgedit-scale-warn-<?php echo $post_id; ?>"><span class="dashicons dashicons-warning" aria-hidden="true"></span></span>
</fieldset>
</div>
</div>
</div>
</div>

<div class="imgedit-group">
<div class="imgedit-group-top">
<h2><button type="button" onclick="imageEdit.toggleHelp(this);" class="button-link" aria-expanded="false"> <span class="dashicons dashicons-arrow-down imgedit-help-toggle"></span></button></h2>
<div class="imgedit-help imgedit-restore">
<p>

</p>
<div class="imgedit-submit">
<input type="button" onclick="imageEdit.action(<?php echo "$post_id, '$nonce'"; ?>, 'restore')" class="button button-primary" value="" />
</div>
</div>
</div>
</div>

<div class="imgedit-group">
<div id="imgedit-crop" tabindex="-1" class="imgedit-group-controls">
<div class="imgedit-group-top">
<h2></h2>
<button type="button" class="dashicons dashicons-editor-help imgedit-help-toggle" onclick="imageEdit.toggleHelp(this);" aria-expanded="false"><span class="screen-reader-text">

</span></button>
<div class="imgedit-help">
<p></p>
<p><strong></strong><br />
</p>

<p><strong></strong><br />
</p>
</div>
</div>
<fieldset class="imgedit-crop-ratio">
<legend></legend>
<div class="nowrap">
<label for="imgedit-crop-width-<?php echo $post_id; ?>" class="screen-reader-text">

</label>
<input type="number" step="1" min="1" id="imgedit-crop-width-<?php echo $post_id; ?>" onkeyup="imageEdit.setRatioSelection(<?php echo $post_id; ?>, 0, this)" onblur="imageEdit.setRatioSelection(<?php echo $post_id; ?>, 0, this)" />
<span class="imgedit-separator" aria-hidden="true">:</span>
<label for="imgedit-crop-height-<?php echo $post_id; ?>" class="screen-reader-text">

</label>
<input type="number" step="1" min="0" id="imgedit-crop-height-<?php echo $post_id; ?>" onkeyup="imageEdit.setRatioSelection(<?php echo $post_id; ?>, 1, this)" onblur="imageEdit.setRatioSelection(<?php echo $post_id; ?>, 1, this)" />
</div>
</fieldset>
<fieldset id="imgedit-crop-sel-<?php echo $post_id; ?>" class="imgedit-crop-sel">
<legend></legend>
<div class="nowrap">
<label for="imgedit-sel-width-<?php echo $post_id; ?>" class="screen-reader-text">

</label>
<input type="number" step="1" min="0" id="imgedit-sel-width-<?php echo $post_id; ?>" onkeyup="imageEdit.setNumSelection(<?php echo $post_id; ?>, this)" onblur="imageEdit.setNumSelection(<?php echo $post_id; ?>, this)" />
<span class="imgedit-separator" aria-hidden="true">×</span>
<label for="imgedit-sel-height-<?php echo $post_id; ?>" class="screen-reader-text">

</label>
<input type="number" step="1" min="0" id="imgedit-sel-height-<?php echo $post_id; ?>" onkeyup="imageEdit.setNumSelection(<?php echo $post_id; ?>, this)" onblur="imageEdit.setNumSelection(<?php echo $post_id; ?>, this)" />
</div>
</fieldset>
<fieldset id="imgedit-crop-sel-<?php echo $post_id; ?>" class="imgedit-crop-sel">
<legend></legend>
<div class="nowrap">
<label for="imgedit-start-x-<?php echo $post_id; ?>" class="screen-reader-text">

</label>
<input type="number" step="1" min="0" id="imgedit-start-x-<?php echo $post_id; ?>" onkeyup="imageEdit.setNumSelection(<?php echo $post_id; ?>, this)" onblur="imageEdit.setNumSelection(<?php echo $post_id; ?>, this)" value="0" />
<span class="imgedit-separator" aria-hidden="true">×</span>
<label for="imgedit-start-y-<?php echo $post_id; ?>" class="screen-reader-text">

</label>
<input type="number" step="1" min="0" id="imgedit-start-y-<?php echo $post_id; ?>" onkeyup="imageEdit.setNumSelection(<?php echo $post_id; ?>, this)" onblur="imageEdit.setNumSelection(<?php echo $post_id; ?>, this)" value="0" />
</div>
</fieldset>
<div class="imgedit-crop-apply imgedit-menu container">
<button class="button button-primary" type="button" onclick="imageEdit.handleCropToolClick( <?php echo "$post_id, '$nonce'"; ?>, this );" class="imgedit-crop-apply button"></button> <button type="button" onclick="imageEdit.handleCropToolClick( <?php echo "$post_id, '$nonce'"; ?>, this );" class="imgedit-crop-clear button" disabled="disabled"></button>
</div>
</div>
</div>
</div>

<div class="imgedit-group imgedit-applyto">
<div class="imgedit-group-top">
<h2></h2>
<button type="button" class="dashicons dashicons-editor-help imgedit-help-toggle" onclick="imageEdit.toggleHelp(this);" aria-expanded="false"><span class="screen-reader-text">

</span></button>
<div class="imgedit-help">
<p></p>
</div>
</div>
<div class="imgedit-thumbnail-preview-group">
<figure class="imgedit-thumbnail-preview">
<img src="<?php echo esc_url( $thumb['url'] ); ?>" width="<?php echo esc_attr( $thumb_img[0] ); ?>" height="<?php echo esc_attr( $thumb_img[1] ); ?>" class="imgedit-size-preview" alt="" draggable="false" />
<figcaption class="imgedit-thumbnail-preview-caption"></figcaption>
</figure>
<div id="imgedit-save-target-<?php echo $post_id; ?>" class="imgedit-save-target">
<fieldset>
<legend></legend>

<span class="imgedit-label">
<input type="radio" id="imgedit-target-all" name="imgedit-target-<?php echo $post_id; ?>" value="all" checked="checked" />
<label for="imgedit-target-all"></label>
</span>

<span class="imgedit-label">
<input type="radio" id="imgedit-target-thumbnail" name="imgedit-target-<?php echo $post_id; ?>" value="thumbnail" />
<label for="imgedit-target-thumbnail"></label>
</span>

<span class="imgedit-label">
<input type="radio" id="imgedit-target-nothumb" name="imgedit-target-<?php echo $post_id; ?>" value="nothumb" />
<label for="imgedit-target-nothumb"></label>
</span>

</fieldset>
</div>
</div>
</div>

</div>
</div>

</div>

<div class="imgedit-wait" id="imgedit-wait-<?php echo $post_id; ?>"></div>
<div class="hidden" id="imgedit-leaving-<?php echo $post_id; ?>"></div>
</div>
</pre><p class="wporg-dot-link-list"><a href="https://developer.wordpress.org/reference/files/wp-admin/includes/image-edit.php/">View all references</a> <a href="https://core.trac.wordpress.org/browser/tags/6.9.4/src/wp-admin/includes/image-edit.php#L18">View on Trac</a> <a href="https://github.com/WordPress/wordpress-develop/blob/6.9.4/src/wp-admin/includes/image-edit.php#L18-L332">View on GitHub</a></p></section>
<section class="wp-block-wporg-code-reference-hooks"><h2 id="hooks" class="is-toc-heading wp-block-heading has-heading-5-font-size" tabindex="-1" ><a href="#hooks">Hooks</a></h2> <dl><dt class="wp-block-wporg-code-reference-title has-normal-font-size"><a href="https://developer.wordpress.org/reference/hooks/image_edit_thumbnails_separately/"><span class="hook-func">apply_filters</span>( ‘image_edit_thumbnails_separately’, <nobr><span class="arg-type">bool</span> <span class="arg-name">$show</span></nobr> )</a></dt><dd><p>Shows the settings in the Image Editor that allow selecting to edit only the thumbnail of an image.</p>
</dd></dl></section>
<section class="wp-block-wporg-code-reference-related" data-nosnippet="true"><h2 id="related" class="is-toc-heading wp-block-heading has-heading-5-font-size" tabindex="-1" ><a href="#related">Related</a></h2> <section style="margin-top:var(--wp--preset--spacing--20)" class="wp-block-wporg-code-table" id="uses"><figure class="wp-block-table "><table><thead><tr><th scope="col">Uses</th><th scope="col">Description</th></tr></thead><tbody><tr class=""><td><a href="https://developer.wordpress.org/reference/functions/esc_html_e/">esc_html_e()</a><code>wp-includes/l10n.php

Displays translated text that has been escaped for safe use in HTML output.

esc_attr_e()wp-includes/l10n.php

Displays translated text that has been escaped for safe use in an attribute.

wp_image_editor_supports()wp-includes/media.php

Tests whether there is an editor that supports a given mime type or methods.

image_get_intermediate_size()wp-includes/media.php

Retrieves the image’s intermediate size (resized) path, width, and height.

wp_constrain_dimensions()wp-includes/media.php

Calculates the new dimensions for a down-sampled image.

wp_get_attachment_metadata()wp-includes/post.php

Retrieves attachment metadata for attachment ID.

get_post_mime_type()wp-includes/post.php

Retrieves the mime type of an attachment based on the ID.

__()wp-includes/l10n.php

Retrieves the translation of $text.

_e()wp-includes/l10n.php

Displays translated text.

wp_basename()wp-includes/formatting.php

i18n-friendly version of basename().

esc_url()wp-includes/formatting.php

Checks and cleans a URL.

esc_attr()wp-includes/formatting.php

Escaping for HTML attributes.

wp_create_nonce()wp-includes/pluggable.php

Creates a cryptographic token tied to a specific action, user, user session, and window of time.

admin_url()wp-includes/link-template.php

Retrieves the URL to the admin area for the current site.

apply_filters()wp-includes/plugin.php

Calls the callback functions that have been added to a filter hook.

get_post_meta()wp-includes/post.php

Retrieves a post meta field for the given post ID.

Show 11 moreShow less

Used by Description
edit_form_image_editor()wp-admin/includes/media.php

Displays the image and editor in the post editor

wp_ajax_image_editor()wp-admin/includes/ajax-actions.php

Handles image editing via AJAX.

Changelog

Version Description
2.9.0 Introduced.