当前位置:首页教程中心网站教程纯代码实现图片转换webp格式并优化图片大小

纯代码实现图片转换webp格式并优化图片大小

站长在管理网站过程中发现在发布文章上传图片会占用大量的储存空间,在使用了多款转webp插件之后都有这样那样的问题

如:JPG格式转换后正常,但是png格式转换后就显示白图一片,有或者某插件 使用转换功能没问题,但是在媒体文件中无法预览等问题

纯代码实现图片转换webp格式并优化图片大小

所以站长研究了一下,直接通过纯代码的方式来实现该功能,代码放在主题文件-functions.php 文件中即可

代码如下:


/**
 * WordPress 自动将上传图片转为WebP并删除原文件
 * 支持格式:JPG、PNG、JPEG
 * 转换后自动删除原文件,只保留WebP格式
 */

// 检查服务器是否支持WebP格式
function webp_converter_support_check() {
    return wp_image_editor_supports( array( 'mime_type' => 'image/webp' ) );
}

// 上传文件后自动转换为WebP并删除原文件
add_filter( 'wp_handle_upload', 'auto_convert_to_webp_and_remove_original', 10, 2 );
function auto_convert_to_webp_and_remove_original( $upload, $context ) {
    // 仅处理图片上传场景
    if ( $context !== 'upload' ) {
        return $upload;
    }

    // 检查服务器是否支持WebP
    if ( ! webp_converter_support_check() ) {
        error_log( 'WebP转换失败:服务器不支持WebP格式' );
        return $upload;
    }

    $file_path = $upload['file']; // 上传后的临时文件路径
    $file_type = $upload['type']; // 文件MIME类型
    $allowed_types = array( 'image/jpeg', 'image/png', 'image/jpg' ); // 支持的原格式

    // 仅处理允许的图片类型
    if ( ! in_array( $file_type, $allowed_types, true ) ) {
        return $upload;
    }

    // 生成WebP文件路径(替换原扩展名)
    $webp_path = pathinfo( $file_path, PATHINFO_DIRNAME ) . '/' . pathinfo( $file_path, PATHINFO_FILENAME ) . '.webp';

    // 使用WordPress图片编辑器处理转换和压缩
    $image_editor = wp_get_image_editor( $file_path );
    if ( is_wp_error( $image_editor ) ) {
        error_log( 'WebP转换失败:' . $image_editor->get_error_message() );
        return $upload;
    }

    // 设置压缩质量(1-100,数值越高质量越好但体积越大)
    $compression_quality = apply_filters( 'webp_compression_quality', 80 );
    $image_editor->set_quality( $compression_quality );

    // 保存为WebP格式
    $save_result = $image_editor->save( $webp_path, 'image/webp' );
    if ( is_wp_error( $save_result ) ) {
        error_log( 'WebP保存失败:' . $save_result->get_error_message() );
        return $upload;
    }

    // 验证WebP文件是否生成成功且完整
    if ( ! file_exists( $webp_path ) || filesize( $webp_path ) === 0 ) {
        error_log( 'WebP转换失败:文件未生成或为空 - ' . $webp_path );
        return $upload;
    }

    // 确保原文件存在后删除(关键步骤:不保留原文件)
    if ( file_exists( $file_path ) ) {
        // 先尝试修改权限再删除,避免权限问题导致删除失败
        @chmod( $file_path, 0644 );
        if ( ! @unlink( $file_path ) ) {
            error_log( '无法删除原文件:' . $file_path );
            // 如果删除失败,删除生成的WebP文件并返回原文件,确保数据一致性
            @unlink( $webp_path );
            return $upload;
        }
    }

    // 更新上传结果为WebP文件信息
    $upload['file'] = $webp_path;
    $upload['url'] = str_replace( basename( $upload['url'] ), basename( $webp_path ), $upload['url'] );
    $upload['type'] = 'image/webp';

    return $upload;
}

// 更新媒体库元数据,确保附件指向WebP文件
add_filter( 'wp_generate_attachment_metadata', 'update_webp_attachment_metadata', 10, 2 );
function update_webp_attachment_metadata( $metadata, $attachment_id ) {
    $file_path = get_attached_file( $attachment_id );

    // 检查文件是否为WebP
    if ( pathinfo( $file_path, PATHINFO_EXTENSION ) !== 'webp' ) {
        return $metadata;
    }

    // 更新缩略图信息为WebP格式
    if ( ! empty( $metadata['sizes'] ) ) {
        foreach ( $metadata['sizes'] as $size => $size_data ) {
            $original_thumb_path = pathinfo( $size_data['file'], PATHINFO_DIRNAME ) . '/' . pathinfo( $size_data['file'], PATHINFO_FILENAME );
            $metadata['sizes'][ $size ]['file'] = $original_thumb_path . '.webp';
        }
    }

    return $metadata;
}

// 允许WordPress媒体库识别WebP文件
add_filter( 'upload_mimes', 'allow_webp_upload_mime_type' );
function allow_webp_upload_mime_type( $mimes ) {
    $mimes['webp'] = 'image/webp';
    return $mimes;
}

// 批量转换历史图片并删除原文件
add_action( 'admin_post_convert_existing_images', 'batch_convert_existing_images' );
function batch_convert_existing_images() {
    // 安全验证
    check_admin_referrer( 'webp_batch_convert_nonce', 'nonce' );

    // 仅管理员可执行
    if ( ! current_user_can( 'manage_options' ) ) {
        wp_die( '无权限执行此操作' );
    }

    // 检查WebP支持
    if ( ! webp_converter_support_check() ) {
        wp_die( '服务器不支持WebP格式' );
    }

    // 查询所有未转换的图片附件
    $args = array(
        'post_type'      => 'attachment',
        'post_mime_type' => array( 'image/jpeg', 'image/png', 'image/jpg' ),
        'posts_per_page' => -1,
        'post_status'    => 'inherit',
    );
    $attachments = get_posts( $args );

    foreach ( $attachments as $attachment ) {
        $original_path = get_attached_file( $attachment->ID );
        if ( ! $original_path || pathinfo( $original_path, PATHINFO_EXTENSION ) === 'webp' ) {
            continue;
        }

        // 生成WebP路径
        $webp_path = pathinfo( $original_path, PATHINFO_DIRNAME ) . '/' . pathinfo( $original_path, PATHINFO_FILENAME ) . '.webp';

        // 转换图片
        $image_editor = wp_get_image_editor( $original_path );
        if ( is_wp_error( $image_editor ) ) {
            error_log( '转换失败(' . $original_path . '):' . $image_editor->get_error_message() );
            continue;
        }
        
        $image_editor->set_quality( 85 );
        $save_result = $image_editor->save( $webp_path, 'image/webp' );

        // 转换成功后更新附件并删除原文件
        if ( ! is_wp_error( $save_result ) && file_exists( $webp_path ) && filesize( $webp_path ) > 0 ) {
            // 更新附件路径
            update_post_meta( $attachment->ID, '_wp_attached_file', str_replace( wp_upload_dir()['basedir'], '', $webp_path ) );
            
            // 删除原文件
            if ( file_exists( $original_path ) ) {
                @chmod( $original_path, 0644 );
                @unlink( $original_path );
            }
            
            // 更新缩略图
            $metadata = wp_generate_attachment_metadata( $attachment->ID, $webp_path );
            wp_update_attachment_metadata( $attachment->ID, $metadata );
        } else {
            // 转换失败则清理可能生成的空文件
            if ( file_exists( $webp_path ) ) {
                @unlink( $webp_path );
            }
        }
    }

    wp_redirect( admin_url( 'upload.php?webp_convert=success' ) );
    exit;
}

// 在媒体库添加批量转换按钮
add_action( 'admin_notices', 'add_webp_batch_convert_button' );
function add_webp_batch_convert_button() {
    // 只在媒体库页面显示
    if ( ! current_user_can( 'manage_options' ) || get_current_screen()->id !== 'upload' ) {
        return;
    }
    
    // 显示转换成功提示
    if ( isset( $_GET['webp_convert'] ) && $_GET['webp_convert'] === 'success' ) {
        echo '<div class="notice notice-success"><p>历史图片批量转换完成!</p></div>';
    }
    ?>
    <div class="notice notice-info">
        <p>
            <form action="<?php echo admin_url( 'admin-post.php' ); ?>" method="post" onsubmit="return confirm('此操作将把所有历史图片转换为WebP格式并删除原文件,建议先备份!是否继续?');">
                <input type="hidden" name="action" value="convert_existing_images">
                <?php wp_nonce_field( 'webp_batch_convert_nonce', 'nonce' ); ?>
                <input type="submit" class="button button-primary" value="批量将历史图片转为WebP(删除原文件)">
            </form>
        </p>
    </div>
    <?php
}



 

 

 

温馨提示:

文章标题:纯代码实现图片转换webp格式并优化图片大小

文章链接:https://www.muooy.cn/3522.html

更新时间:2025年08月13日

1.本站大部分内容均收集于网络!若内容若侵犯到您的权益,请发送邮件至:305582964@qq.com,我们将第一时间处理!

2.资源所需价格并非资源售卖价格,是收集、整理、编辑详情以及本站运营的适当补贴,并且本站不提供任何免费技术支持。

3.所有资源仅限于参考和学习,版权归原作者所有,更多请阅读用户协议免责声明

给TA打赏
共{{data.count}}人
人已打赏
网站教程

2025 域名防红,微信跳转,QQ跳转防红 简单解决办法

2025-8-11 0:00:52

网站教程

轻松实现 WordPress 分类目录总浏览量统计

2025-7-17 22:54:42

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
购物车
优惠劵
今日签到
搜索