Philipp,只要您下定决心,一切皆有可能。您可以通过扩展WordPress图像编辑器类来解决您的问题。
注意:我使用的是WordPress 3.7-在较早的版本和最新的3.8版本中,我没有检查以下任何代码。
图像编辑器基础
WordPress有两个内置的处理图像处理的类:
WP_Image_Editor_GD
(/wp-includes/class-wp-image-editor-gd.php
)
WP_Image_Editor_Imagick
(/wp-includes/class-wp-image-editor-imagick.php
)
扩展这两个类WP_Image_Editor
是因为它们都使用不同的图像引擎(分别为GD和ImageMagick)来加载,调整大小,压缩和保存图像。
默认情况下,WordPress将尝试首先使用ImageMagick引擎,该引擎需要PHP扩展,因为它通常比PHP的默认GD引擎更受欢迎。大多数共享服务器都没有启用ImageMagick扩展。
添加图像编辑器
为了决定使用哪个引擎,WordPress调用了一个内部函数__wp_image_editor_choose()
(位于中/wp-includes/media.php
)。此函数循环遍历所有引擎,以查看哪个引擎可以处理请求。
该函数还具有一个名为的过滤器wp_image_editors
,可让您添加更多图像编辑器,如下所示:
add_filter("wp_image_editors", "my_wp_image_editors");
function my_wp_image_editors($editors) {
array_unshift($editors, "WP_Image_Editor_Custom");
return $editors;
}
请注意,我们正在添加自定义图像编辑器类,WP_Image_Editor_Custom
因此WordPress将在测试其他引擎之前检查我们的引擎是否可以处理调整大小。
创建我们的图像编辑器
现在我们要编写自己的图像编辑器,以便我们自己决定文件名。文件命名是由方法处理的WP_Image_Editor::generate_filename()
(两个引擎都继承了此方法),因此我们应该在自定义类中覆盖它。
由于我们仅计划更改文件名,因此我们应该扩展现有的引擎之一,这样就不必重新发明轮子了。我将WP_Image_Editor_GD
在示例中进行扩展,因为您可能未启用ImageMagick扩展。该代码对于ImageMagick设置是可互换的。如果您打算在不同的设置上使用主题,则可以同时添加两者。
// Include the existing classes first in order to extend them.
require_once ABSPATH.WPINC."/class-wp-image-editor.php";
require_once ABSPATH.WPINC."/class-wp-image-editor-gd.php";
class WP_Image_Editor_Custom extends WP_Image_Editor_GD {
public function generate_filename($prefix = NULL, $dest_path = NULL, $extension = NULL) {
// If empty, generate a prefix with the parent method get_suffix().
if(!$prefix)
$prefix = $this->get_suffix();
// Determine extension and directory based on file path.
$info = pathinfo($this->file);
$dir = $info['dirname'];
$ext = $info['extension'];
// Determine image name.
$name = wp_basename($this->file, ".$ext");
// Allow extension to be changed via method argument.
$new_ext = strtolower($extension ? $extension : $ext);
// Default to $_dest_path if method argument is not set or invalid.
if(!is_null($dest_path) && $_dest_path = realpath($dest_path))
$dir = $_dest_path;
// Return our new prefixed filename.
return trailingslashit($dir)."{$prefix}/{$name}.{$new_ext}";
}
}
上面的大多数代码都是直接从WP_Image_Editor
该类复制而来,并为方便起见添加了注释。唯一实际的变化是后缀现在是前缀。
或者,您可以调用parent::generate_filename()
并使用an mb_str_replace()
来将后缀更改为前缀,但是我认为这样做更容易出错。
保存元数据的新路径
上传后image.jpg
,uploads文件夹如下所示:
2013/12/150x150/image.jpg
2013/12/300x300/image.jpg
2013/12/image.jpg
到现在为止还挺好。但是,当调用诸如之类的基本函数时wp_get_attachment_image_src()
,我们会注意到所有图像大小的存储都image.jpg
没有新的目录路径。
我们可以通过将新的文件夹结构保存到图像元数据(存储文件名)中来解决此问题。数据wp_generate_attachment_metadata
在插入数据库之前需要经过各种过滤器(其中包括),但是由于我们已经实现了自定义图像编辑器,因此可以返回到图像大小元数据的来源:WP_Image_Editor::multi_resize()
。它生成像这样的数组:
Array (
[thumbnail] => Array (
[file] => image.jpg
[width] => 150
[height] => 150
[mime-type] => image/jpeg
)
[medium] => Array (
[file] => image.jpg
[width] => 300
[height] => 300
[mime-type] => image/jpeg
)
)
我们将multi_resize()
在自定义类中覆盖该方法:
function multi_resize($sizes) {
$sizes = parent::multi_resize($sizes);
foreach($sizes as $slug => $data)
$sizes[$slug]['file'] = $data['width']."x".$data['height']."/".$data['file'];
return $sizes;
}
如您所见,我没有费心替换任何代码。我只是调用父方法,并让它生成元数据。然后,我遍历结果数组并调整file
每种大小的值。
现在wp_get_attachment_image_src($att_id, array(300, 300))
返回2013/12/300x300/image.jpg
。万岁!
最后的想法
希望这为您详细阐述奠定了良好的基础。但是,请注意,如果图像小于指定的大小(例如280x300),则生成的后缀(在我们的示例中为前缀)和图像大小为280x300,而不是300x300。如果您上传了很多较小的图片,则会得到很多不同的文件夹。
一个好的解决办法是要么使用大小蛞蝓作为文件夹名(small
,medium
,等等)或扩展代码来圆尺寸到最接近的首选的图像尺寸。
您注意到您只想使用宽度作为目录名。不过请注意-插件或主题可能会生成两个大小相同但宽度相同但高度不同的大小。
另外,您可以通过在“设置”>“媒体”下禁用“将我的上传内容整理到基于月和年的文件夹中”或generate_filename
进一步进行操作来删除年/月文件夹。
希望这可以帮助。祝好运!