Philipp, bất cứ điều gì là có thể nếu bạn đặt tâm trí của bạn với nó. Bạn có thể giải quyết vấn đề của mình bằng cách mở rộng lớp trình chỉnh sửa hình ảnh WordPress.
Lưu ý Tôi đang sử dụng WordPress 3.7 - Tôi chưa kiểm tra bất kỳ mã nào dưới đây trong các phiên bản trước và trong phiên bản 3.8 mới nhất.
Khái niệm cơ bản về chỉnh sửa ảnh
WordPress có hai lớp được xây dựng để xử lý thao tác hình ảnh:
WP_Image_Editor_GD
( /wp-includes/class-wp-image-editor-gd.php
)
WP_Image_Editor_Imagick
( /wp-includes/class-wp-image-editor-imagick.php
)
Hai lớp này mở rộng WP_Image_Editor
vì cả hai đều sử dụng một công cụ hình ảnh khác nhau (tương ứng GD và ImageMagick) để tải, thay đổi kích thước, nén và lưu hình ảnh.
Theo mặc định, WordPress sẽ cố gắng sử dụng công cụ ImageMagick trước tiên, nó cần một phần mở rộng PHP, bởi vì nó thường được ưa thích hơn công cụ GD mặc định của PHP. Hầu hết các máy chủ được chia sẻ không bật tiện ích mở rộng ImageMagick.
Thêm trình chỉnh sửa hình ảnh
Để quyết định sử dụng công cụ nào, WordPress gọi một chức năng nội bộ __wp_image_editor_choose()
(nằm trong/wp-includes/media.php
). Hàm này lặp qua tất cả các động cơ để xem động cơ nào có thể xử lý yêu cầu.
Hàm này cũng có một bộ lọc được gọi là wp_image_editors
cho phép bạn thêm nhiều trình chỉnh sửa hình ảnh như vậy:
add_filter("wp_image_editors", "my_wp_image_editors");
function my_wp_image_editors($editors) {
array_unshift($editors, "WP_Image_Editor_Custom");
return $editors;
}
Lưu ý chúng ta thêm vào trước lớp biên tập hình ảnh tùy chỉnh của chúng tôi WP_Image_Editor_Custom
để WordPress sẽ kiểm tra xem động cơ của chúng tôi có thể xử lý thay đổi kích thước trước khi thử nghiệm động cơ khác.
Tạo Trình chỉnh sửa hình ảnh của chúng tôi
Bây giờ chúng tôi sẽ viết trình chỉnh sửa hình ảnh của riêng mình để chúng tôi có thể quyết định tên tệp cho chính mình. Filenaming được xử lý bằng phương thức WP_Image_Editor::generate_filename()
(cả hai công cụ đều kế thừa phương thức này), vì vậy chúng ta nên ghi đè lên nó trong lớp tùy chỉnh của chúng ta.
Vì chúng tôi chỉ có kế hoạch thay đổi tên tệp, chúng tôi nên mở rộng một trong các công cụ hiện có để chúng tôi không phải phát minh lại bánh xe. Tôi sẽ mở rộng WP_Image_Editor_GD
trong ví dụ của mình, vì có lẽ bạn không bật tiện ích mở rộng ImageMagick. Mã có thể hoán đổi cho một thiết lập ImageMagick. Bạn có thể thêm cả hai nếu bạn dự định sử dụng chủ đề trên các thiết lập khác nhau.
// 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}";
}
}
Hầu hết các mã ở trên được sao chép trực tiếp từ WP_Image_Editor
lớp và nhận xét để thuận tiện cho bạn. Thay đổi thực tế duy nhất là hậu tố bây giờ là tiền tố.
Ngoài ra, bạn chỉ có thể gọi parent::generate_filename()
và sử dụng một mb_str_replace()
để thay đổi hậu tố thành tiền tố, nhưng tôi đoán rằng sẽ có xu hướng sai hơn.
Lưu đường dẫn mới vào siêu dữ liệu
Sau khi tải lên image.jpg
, thư mục tải lên trông như thế này:
2013/12/150x150/image.jpg
2013/12/300x300/image.jpg
2013/12/image.jpg
Càng xa càng tốt. Tuy nhiên, khi gọi các chức năng cơ bản như wp_get_attachment_image_src()
, chúng tôi sẽ nhận thấy tất cả các kích thước hình ảnh được lưu trữ image.jpg
mà không có đường dẫn thư mục mới.
Chúng ta có thể giải quyết vấn đề này bằng cách lưu cấu trúc thư mục mới vào siêu dữ liệu hình ảnh (nơi tên tệp được lưu trữ). Dữ liệu chạy qua các bộ lọc khác nhau ( wp_generate_attachment_metadata
trong số các bộ lọc khác) trước khi được chèn vào cơ sở dữ liệu, nhưng vì chúng tôi đã triển khai trình chỉnh sửa hình ảnh tùy chỉnh, chúng tôi có thể quay lại nguồn siêu dữ liệu kích thước hình ảnh : WP_Image_Editor::multi_resize()
. Nó tạo ra các mảng như thế này:
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
)
)
Chúng tôi sẽ ghi đè multi_resize()
phương thức trong lớp tùy chỉnh của chúng tôi:
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;
}
Như bạn có thể thấy, tôi không buồn thay thế bất kỳ mã nào. Tôi chỉ gọi phương thức cha và để nó tạo siêu dữ liệu. Sau đó, tôi lặp qua mảng kết quả và điều chỉnh file
giá trị cho từng kích thước.
Bây giờ wp_get_attachment_image_src($att_id, array(300, 300))
trở lại 2013/12/300x300/image.jpg
. Hoan hô!
Suy nghĩ cuối cùng
Tôi hy vọng điều này cung cấp một cơ sở tốt để bạn giải thích. Tuy nhiên, xin lưu ý nếu một hình ảnh nhỏ hơn kích thước được chỉ định (ví dụ 280x300), hậu tố được tạo (tiền tố trong trường hợp của chúng tôi) và kích thước hình ảnh là 280x300, không phải 300x300. Nếu bạn tải lên nhiều hình ảnh nhỏ hơn, bạn sẽ nhận được rất nhiều thư mục khác nhau.
Một giải pháp tốt là sử dụng sên kích thước làm tên thư mục ( small
,medium
, vân vân) hoặc mở rộng mã để kích thước vòng lên đến kích thước hình ảnh ưa thích gần nhất.
Bạn lưu ý rằng bạn chỉ muốn sử dụng chiều rộng làm tên thư mục. Mặc dù được cảnh báo - các plugin hoặc chủ đề có thể tạo ra hai kích thước khác nhau với cùng chiều rộng nhưng chiều cao khác nhau.
Ngoài ra, bạn có thể xóa các thư mục năm / tháng bằng cách vô hiệu hóa 'Sắp xếp tải lên của tôi vào các thư mục dựa trên tháng và năm' trong Cài đặt> Phương tiện hoặc bằng cách thao tác generate_filename
hơn nữa.
Hi vọng điêu nay co ich. Chúc may mắn!