rebbit

WordPress无法上传avif图片 Web 服务器无法处理该图片,请在上传前将其转换为 JPEG 或 PNG 格式。

今天突然遇到一个问题,媒体库无法上传avif格式图片。

Web 服务器无法处理该图片,请在上传前将其转换为 JPEG 或 PNG 格式。

但是如果切换至浏览器上传工具或者在文章页里却可以上传成功。

我寻思不可能呀,WordPress 6.5 已经支持 AVIF 图片格式,我的版本正是最新的 6.5.2。

难道因为之前更新了1Panel面板导致的?

排查思路

网络检查

先从页面开始,在 上传新媒体文件 页面上传avif格式图片发现并为发生任何网络请求,却直接提示失败:

Web 服务器无法处理该图片,请在上传前将其转换为 JPEG 或 PNG 格式。

怀疑,页面js做了校验,非 WAF防火墙 问题。

尝试验证,上传 exe 文件测试,收到:

从服务器收到预料之外的响应。此文件可能已被成功上传。请检查媒体库或刷新本页。

网络请求报 403,上传的 exe文件 被防火墙拦截。

确认为本地页面问题

页面检查

页面内尝试搜索 avif ,发现这样一串js代码

<script type="text/javascript">
	var resize_height = 1024, resize_width = 1024,
	wpUploaderInit = {"browse_button":"plupload-browse-button","container":"plupload-upload-ui","drop_element":"drag-drop-area","file_data_name":"async-upload","url":"https:\/\/www.krjojo.com\/wp-admin\/async-upload.php","filters":{"max_file_size":"52428800b"},"multipart_params":{"post_id":0,"_wpnonce":"9eacda1f04","type":"","tab":"","short":"1"},"avif_upload_error":true,"heic_upload_error":true};
</script>

其中发现 "avif_upload_error":true, 不太寻常

难道是 WordPress 代码自己写死不允许上传 avif图片

不会是插件搞得鬼吧

代码检查

尝试在 WordPress 全局文件中搜索 avif_upload_error 代码

发现在 /wp-admin/includes/media.php 文件下有一串关于avif格式的检查

// Check if AVIF images can be edited.
if ( ! wp_image_editor_supports( array( 'mime_type' => 'image/avif' ) ) ) {
	$plupload_init['avif_upload_error'] = true;
}

每次上传前,wordpress 都会对服务器所支持编辑的图片格式进行检查

这段检查就是在 _wp_image_editor_choose() 函数中

不知道为什么avif没通过检查,而webp通过了,返回的是 WP_Image_Editor_GD

最后,在 WP_Image_Editor_GD class文件找到这么一串

/**
 * Checks to see if editor supports the mime-type specified.
 *
 * @since 3.5.0
 *
 * @param string $mime_type
 * @return bool
 */
public static function supports_mime_type( $mime_type ) {
	$image_types = imagetypes();
	switch ( $mime_type ) {
		case 'image/jpeg':
			return ( $image_types & IMG_JPG ) != 0;
		case 'image/png':
			return ( $image_types & IMG_PNG ) != 0;
		case 'image/gif':
			return ( $image_types & IMG_GIF ) != 0;
		case 'image/webp':
			return ( $image_types & IMG_WEBP ) != 0;
		case 'image/avif':
			return ( $image_types & IMG_AVIF ) != 0;
	}
	return false;
}

尝试打印 imagetypes()

返回

echo IMG_AVIF;
// 256
echo imagetypes();
// 239

这个函数以比特字段方式返回与当前 PHP 版本关联的 GD 库所支持的图像格式。

看来就是GD库不支持 avif 。

1Panel 进入php8.2.15容器终端,执行以下命令

php -i | grep AVIF

返回为空,1Panel 的GD库并没用使用avif支持进行编译。

此外,还有两个新函数,imagecreatefromavif 和 imageavif,它们只有在 GD 扩展使用 AVIF 支持编译时可用。

if (function_exists('imageavif')) {
    // AVIF support available.
}

解决办法

重新构建PHP GD扩展

可以参考这篇文章:1Panel面板修改PHP构建扩展,GD扩展增加avif支持

临时解决办法

加入以下代码,取消 avif 格式环境检查

add_filter('plupload_init', function($plupload_init) {
	$plupload_init['avif_upload_error'] = false;
	return $plupload_init;
}, 10, 1);

add_filter('plupload_default_settings', function($defaults) {
	$defaults['avif_upload_error'] = false;
	return $defaults;
}, 10, 1);

缺点

站内图片的编辑模式失效

© 版权声明
分享是一种美德,转载请保留原链接
THE END

文章不错?点个赞呗
点赞 0 分享

发表评论

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

滚动至顶部