사용자 정의 업로드 디렉토리의 각 사용자 정의 이미지 크기는?


11

사용자 정의 이미지 크기를 사용자 정의 폴더에 업로드하고 싶습니다. 폴더는 선택한 너비의 이름을 가져야합니다. 예를 들면 다음과 같습니다.

이 맞춤 크기를 추가하면 ...

add_image_size('custom-1', 300, 9999);
add_image_size('custom-2', 400, 9999);

업로드 된 이미지가 다음과 같이 업로드되는 것이 좋습니다.

http://www.my-site.com/wp-content/uploads/300/my-image.jpg
http://www.my-site.com/wp-content/uploads/400/my-image.jpg

이게 가능해? upload_dir 필터를 사용하여 전역 업로드 폴더를 변경할 수 있다는 것만 발견했습니다 .

답변:


21

필립, 마음이 편 해지면 무엇이든 가능합니다. 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는 일반적으로 PHP의 기본 GD 엔진보다 선호되므로 PHP 확장이 필요한 ImageMagick 엔진을 먼저 사용하려고합니다. 대부분의 공유 서버에는 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우리의 엔진은 다른 엔진을 테스트하기 전에 크기를 조정 처리 할 수 있는지 워드 프레스 확인 있도록.


이미지 편집기 만들기

이제 이미지 편집기를 작성하여 파일 이름을 결정할 수 있습니다. 파일 이름 지정은 메소드에 의해 처리되므로 WP_Image_Editor::generate_filename()(두 엔진 모두이 메소드를 상속 받음 ), 커스텀 클래스에서 덮어 써야합니다.

파일 이름 변경 만 계획하고 있으므로 기존 엔진 중 하나를 확장해야 휠을 재발 명할 필요가 없습니다. WP_Image_Editor_GDImageMagick 확장 기능이 활성화되어 있지 않을 수도 있으므로 예제에서 확장하겠습니다 . 코드는 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()를 사용 mb_str_replace()하여 접미사를 접두사로 변경할 수는 있지만 더 잘못되는 경향이 있다고 생각했습니다.


메타 데이터에 대한 새로운 경로 저장

업로드 후 업로드 image.jpg폴더는 다음과 같습니다.

  • 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)보다 작 으면 생성 된 접미사 (이 경우 접두사) 및 이미지 크기는 300x300이 아니라 280x300입니다. 작은 이미지를 많이 업로드하면 다른 폴더가 많이 생깁니다.

좋은 해결책은 크기 슬러그를 폴더 이름 ( small, medium등)으로 사용하거나 코드를 확장하여 가장 가까운 선호하는 이미지 크기로 반올림하는 것입니다.

너비 만 디렉토리 이름으로 사용하고 싶다고 언급했습니다. 그러나 플러그인이나 테마는 너비는 같지만 높이가 다른 두 가지 크기를 생성 할 수 있습니다.

또한 설정> 미디어에서 '업로드를 월별 및 연도 별 폴더로 구성'을 비활성화하거나 generate_filename추가 로 조작하여 년 / 월 폴더를 제거 할 수 있습니다 .

도움이 되었기를 바랍니다. 행운을 빕니다!


3
정답입니다! : D Nice man!
Philipp Kühn

1
천만에요! 최소한 OOP 및 WP 필터 경험이 약간 있다고 가정했지만 아직 이해하지 못하는 것이 있으면 언제든지 문의하십시오. 현상금에 감사드립니다!
Robbert

2
@Robbert 솔직히, 이것은 훌륭합니다. 미디어 업로드 시스템의 동작 및 필터 후크가 부족하여 머리카락이 찢어졌습니다. 돌이켜 보면 분명해 보이지만 이미지 편집기를 완전히 무시하는 것은 결코 일어나지 않았습니다. 그렇게하면 한 번에 많은 문제가 해결됩니다.
Jonathan Fingland

1
@JonathanFingland Ha, 나는 이것에 대한 토끼 구멍으로 멀리 가야한다는 것을 인정합니다. 도움이되어 기쁘다!
Robbert

작은 참고 사항-마지막 코드에서 (public function multi_resize ($ sizes)) 키워드 "public"은 웹 사이트를 다운시킵니다. 그냥 제거하면 다시 작동합니다. 2k17 그리고 당신의 대답은 여전히 ​​굉장합니다, 감사합니다 !!
역설

3

@Robbert의 대답은 WordPress에서 생성 된 대체 크기를 별도의 디렉토리에 저장하려는 노력의 신성한 자원이었습니다. 내 코드는 업로드 디렉토리를 ./media로 변경하므로 원하지 않는 경우이 줄을 편집하십시오. 첫 번째 포스터의 질문에 대한 정확한 답변은 아니지만 동일한 문제에 대한 대안 솔루션을 제공합니다.

if ( !is_multisite() ) {
    update_option( 'upload_path', 'media' ); //to-do: add to options page
    define( 'UPLOADS', 'media' ); //define UPLOADS dir - REQUIRED
}
//don't “Organize my uploads into month- and year-based folders”
update_option( 'uploads_use_yearmonth_folders', '0' ); // to-do: add to options page

//create a custom WP_Image_Editor that handles the naming of files
function tect_image_editors($editors) {
    array_unshift( $editors, 'WP_Image_Editor_tect' );

    return $editors;
}

add_filter( 'wp_image_editors', 'tect_image_editors' );

require_once ABSPATH . WPINC . '/class-wp-image-editor.php';
require_once ABSPATH . WPINC . '/class-wp-image-editor-gd.php';

class WP_Image_Editor_tect extends WP_Image_Editor_GD {
    public function multi_resize($sizes) {
        $sizes = parent::multi_resize($sizes);

        $media_dir = trailingslashit( ABSPATH . UPLOADS );

        foreach($sizes as $slug => $data) {
            $default_name = $sizes[ $slug ]['file'];
            $new_name = $slug . '/' . preg_replace( '#-\d+x\d+\.#', '.', $data['file'] );

            if ( !is_dir( $media_dir . $slug ) ) {
                mkdir( $media_dir . $slug );
            }
            //move the thumbnail - perhaps not the smartest way to do it...
            rename ( $media_dir . $default_name, $media_dir . $new_name );

            $sizes[$slug]['file'] = $new_name;
        }

        return $sizes;
    }
}

인기있는 갤러리 / 미디어 플러그인으로 어떻게 처리되는지 확인하지는 않았지만 테스트에 따라 아무런 문제없이 작동합니다.

관련 보너스 : 모든 WordPress 생성 축소판을 삭제하는 원시 유틸리티 delete_deprecated_thumbs.php


1

WordPress 코드의 이러한 부분을 살펴 봤는데 좋은 소식이없는 것이 두렵습니다.

2 개의 수업이 있습니다 :

  • WP_Image_Editor_GD
  • WP_Image_Editor_Imagick,

둘 다 확장 추상 WP_Image_Editor클래스.

이 클래스는 multi_resize업로드 된 이미지에서 여러 이미지를 생성하는 데 사용되는 메소드 를 구현하고 있습니다.

정말 나쁜 소식은 필터 후크가 없기 때문에 새로 만든 파일의 대상 경로를 수정하는 데 사용할 수 있다는 것입니다.


부끄러운 일입니다. 멋진 Imager.js 를 구현하고 싶었지만 그렇지 않으면 작동하지 않을 것입니다.
Philipp Kühn

Imager.js는 이미지 를 봇 (Google, Facebook 등)에서 보이지 않게 하므로 noscript태그를 수동으로 추가하지 않는 한 사용하지 않는 것이 좋습니다.
fregante

흠 아니, 나는 그렇게 생각하지 않습니다. 일반적으로 이미지의 src와 함께 img-tag를 사용합니다. 그리고 다른 이미지 크기의 구문으로 데이터 태그를 추가합니다 <img src="http://placehold.it/260" data-src="http://placehold.it/{width}" />. 그런 다음 스크립트는 img의 크기를 확인하고 그에 가장 적합한 이미지 크기를로드합니다.
Philipp Kühn

@ PhilippKühn 너무 실망했습니다. 여러분의 생각은 꽤 단정하고 있었고, 난 (테마 변경이 고통이 ...에 후 삭제되지 않는 작은 이미지) 업로드 디렉토리를 정돈하는 데 사용하고 싶었
Krzysiek Dróżdż

@ KrzysiekDróżdż 이봐, 내가 알 것 같아. 아래에서 내 대답을보십시오. 이 솔루션을 사용하면 파일 이름으로 이미지를 ftp를 통해 정렬하고 사용하지 않은 이미지 크기를 쉽게 제거 할 수 있습니다.
Philipp Kühn

1

알았어, 알았어! 완벽하지는 않지만 괜찮습니다. 나에게 이미지 너비 만 중요합니다. 높이는 나에게 쓸모가 없다. 특히 Imager.js 를 구현할 때 이미지 URL의 높이가 어지럽습니다.

add_filter('image_make_intermediate_size', 'custom_rename_images');

function custom_rename_images($image) {
    // Split the $image path
    $info = pathinfo($image);
    $dir = $info['dirname'] . '/';
    $ext = '.' . $info['extension'];
    $name = wp_basename($image, '$ext');

    // New Name
    $name_prefix = substr($name, 0, strrpos($name, '-'));
    $size_extension = substr($name, strrpos($name, '-') + 1);
    $image_sizes = explode('x', $size_extension);
    $image_width = $image_sizes[0];
    $new_name = $dir . $image_width . '-' . $name_prefix . $ext;

    // Rename the intermediate size
    $did_it = rename($image, $new_name);

    // Return if successful
    if ($did_it) return $new_name;

    // Return on fail
    return $image;
}

이 코드에서 파일 이름은 다음과 같습니다.

http://www.my-site.com/wp-content/uploads/300-my-image.jpg
http://www.my-site.com/wp-content/uploads/400-my-image.jpg

그건 하지 난 항상 원본 게시물 / 페이지에 이미지를 추가 할 경우 대신 사용하기 때문에, 파일 이름에 하위 폴더를 추가 할 수 있습니다. 삭제시 이러한 이미지를 제거해도 작동하지 않습니다. 왜 그런지 잘 모르겠습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.