WordPress - изображение Blur при загрузке

Итак, я следую примеру приведенному здесь (который я изменил, чтобы размыть, без водяного знака), чтобы сделать размытое изображение в WordPress при загрузке. Проблема заключается в том, что если загруженный файл имеет тот же размер или меньше, чем установленный размер, тогда WordPress не будет генерировать изображение, и, следовательно, не будет размытого изображения.

Я попытался использовать isst($meta['sizes']['background-image-blurred']['file']), чтобы определить, был ли он создан, а если нет, то copy() исходный файл, но тогда для изображения не будет создано метаданных WordPress (для людей, не являющихся членами WordPress, метаданные отличается от того, что вы думаете), поэтому при отображении с помощью wp_get_attachment_image проблемы будут задаваться проблемы с высотой/шириной undefined.

Итак, я убежден, что использование wp_get_attachment_image hook, как показано ниже, возможно, неверный способ сделать это. Вероятно, это должно произойти раньше в процессе загрузки изображений.

Любые идеи о том, как лучше всего это сделать?

/**
 * Several functions relatting to blurring images on uploaded.
 * @see https://codeable.io/community/how-to-watermark-wordpress-images-with-imagemagick/
 */ 
    add_image_size( 'background-image-blurred', 1920, 1080, true );

    function generate_blurred_image( $meta ) {

      $time = substr( $meta['file'], 0, 7); // Extract the date in form "2015/04"
      $upload_dir = wp_upload_dir( $time ); // Get the "proper" upload dir

      $filename = $meta['sizes']['background-image-blurred']['file'];
      $meta['sizes']['background-image-blurred']['file'] = blur_image( $filename, $upload_dir );

      return $meta;

    }
    add_filter( 'wp_generate_attachment_metadata', 'generate_blurred_image' );    

    function blur_image( $filename, $upload_dir ) {

      $original_image_path = trailingslashit( $upload_dir['path'] ) . $filename;

      $image_resource = new Imagick( $original_image_path );
      $image_resource->gaussianBlurImage( 10, 100 ); // See: http://phpimagick.com/Imagick/gaussianBlurImage

      return save_blurred_image( $image_resource, $original_image_path );

    }    

    function save_blurred_image( $image_resource, $original_image_path ) {

      $image_data = pathinfo( $original_image_path );

      $new_filename = $image_data['filename'] . '-blurred.' . $image_data['extension'];

      // Build path to new blurred image
      $blurred_image_path = str_replace($image_data['basename'], $new_filename, $original_image_path);

      if ( ! $image_resource->writeImage( $blurred_image_path ) ) {
        return $image_data['basename'];          
      }

      // Delete the placeholder image WordPress made now that it been blurred
      unlink( $original_image_path );

      return $new_filename;

    }    

Ответ 1

К сожалению, у wp нет фильтра, чтобы заставить размер, так что вы можете сделать это после и изменить размер вашего изображения, если его не создать, и поместить его в метаданные.

У меня нет воображения, поэтому вам придется самим попробовать эти функции, но у вас есть правильный процесс выше, вам просто нужно обновить имя файла и ввести его в массив ниже. PS ничего не выводит в фильтр!

function custom_img_size(){
    add_image_size( 'background-image-blurred', 1920, 1080, true );
}

add_action( 'after_setup_theme', 'custom_img_size' );


add_filter('wp_generate_attachment_metadata', 'force_add_size', 100);
function force_add_size( $metadata ) {

   if(!isset($metadata['sizes']['background-image-blurred'])){
        //not set so initiate our custom size...
        //I dont have imagick installed so just use your functions here to duplicate
        //note original file = $filename update the $newfilename below...
        //sample resize code ...
        $upload_dir = wp_upload_dir();
        $filename= $upload_dir['basedir'].'/'.$metadata['file'];
        $extension = strtolower(strrchr($metadata['file'], '.'));
        $newfilename= str_replace($extension, '-1200x1080', $filename).$extension;

        copy($filename, $newfilename );
        //end sample resize code.....



        $filetype= 'image/jpeg';
        $metadata['sizes']['background-image-blurred']= array(
            "file"=> $newfilename,
            "width"=> 1920, 
            "height"=> 1080,
            "mime-type"=> $filetype 
        );

   }


   return $metadata;

}

Обновление

  • Это предназначено только для обнаружения, когда существующий фильтр не смог создать ваш размытый пользовательский размер, иначе он ничего не сделает. Вы должны по-прежнему включать свои исходные фильтры. У вас может быть проблема с исходным кодом: вы удаляете исходный файл в своих фильтрах, и это вызовет проблемы, так как есть поле postmeta с именем "_wp_attached_file", которое потребуется обновить. Я включил здесь примечание.

  • Фильтр ловит метаданные перед сохранением, поэтому любые изменения также будут сохранены после возврата метаданных $. Если вы посмотрите на исходный код: https://core.trac.wordpress.org/browser/tags/3.8.1/src/wp-admin/includes/image.php#L72 здесь вы можете точно увидеть, как это работает. Я также подтвердил использование wp4.3

  • Я попытался вставить функции imagick, которые вам нужны ниже. Я не тестировал, поскольку я вообще не устанавливал его нигде. (imagemagick на самом деле замечательная программа с открытым исходным кодом, но очень насыщенная сервером). Попробуйте использовать эту функцию вместо одного выше:

    add_filter('wp_generate_attachment_metadata', 'force_add_size', 100, 2);
    
    function force_add_size( $metadata, $id ){
    
        $upload_dir = wp_upload_dir();
        $filename= $upload_dir['basedir'].'/'.$metadata['file'];
        $extension = strtolower(strrchr($metadata['file'], '.'));
        $newfilename= str_replace($extension, '-blurred', $filename).$extension;
    
        $image_resource = new Imagick( $filename);
        $image_resource->resizeImage(1920,1080,Imagick::FILTER_LANCZOS,.3);
        $image_resource->writeImage( $newfilename );
        //http://www.dylanbeattie.net/magick/filters/result.html
    
        unlink( $filename );//delete original image altogether ---> you might want to update the post meta on this '_wp_attached_file' , you can actually get the attachment id from the filter, i have added it above. It would be best to have a actual image url in there! something like $sfile= str_replace($upload_dir['basedir'],'', $newfilename); update_post_meta($id, '_wp_attached_file', $sfile );
    
    
    
        switch($extension){
            case '.jpg':
            case '.jpeg':
                $type = 'image/jpeg';
                break;
            case '.gif':
                $type = 'image/gif';
                break;
            case '.png':
                $type = 'image/png';
                break;
            default:
                $type = 'image/jpeg'; // you might want a conditional to check its actually a image...imagick will do this for you as well....it shouldnt get this far if not a image.
                break;
        } 
    
        $metadata['sizes']['background-image-blurred']= array(
            "file"=> $newfilename,
            "width"=> 1920,//your custom image size, has to be this! you could get the global var and check for sizes but its this size in particular we want? 
            "height"=> 1080,
            "mime-type"=> $type 
        );
    
        return $metadata;
    }
    

Обновление чтобы предотвратить растяжение изображения меньшими изображениями, замените код imagick на это.

$upload_dir = wp_upload_dir();
$filename= $upload_dir['basedir'].'/'.$metadata['file'];
$extension = strtolower(strrchr($metadata['file'], '.'));
$newfilename= str_replace($extension, '-blurred', $filename).$extension;

$image_resource = new Imagick( $filename);


if($image_resource->getImageWidth() <= 1920 || $image_resource->getImageHeight() > <= 1020) {
    return $metadata;
}

$image_resource->resizeImage(1920,1080,Imagick::FILTER_LANCZOS,.3);
$image_resource->writeImage( $newfilename );
//http://www.dylanbeattie.net/magick/filters/result.html

Ответ 2

Когда я впервые прочитал ваш вопрос, я был не уверен, возникли ли у вас проблемы с настройкой изображения или созданием изображения или и того, и другого. Я думал, что проблема с настройкой изображения может заключаться в том, что вам нужно обновить сообщение после wp_update_attachment_metadata после использования wp_generate_attachment_metadata, чтобы вместо этого использовать пост вместо этого.

Когда я перечитал ваш вопрос, я понял, что это проблема с add_image_size(), потому что это происходит с изображением того же размера или меньше, чем тот, который был загружен. Я как-то столкнулся с этой проблемой, а также с (re) созданием изображения альтернативного размера для новой темы. В моем случае это было то, что параметр ширины или высоты не выполнялся на add_image_size().

Я хотел проверить это в Wordpress Code Reference и нашел комментарий от вкладчика внизу, это точно такая же проблема, с которой вы сталкиваетесь, хотя и без решения.

Если вы загружаете изображение, размеры которого соответствуют add_image_size() когда для урожая установлено значение true, в объекте $meta, доступ к которому wp_generate_attachment_metadata, соответствующий размер изображения будет не будут доступны. Кроме того, размеры изображений, которые имеют большие размеры, чем загруженная фотография также не будет доступна.

(Таким образом, если вы используете технику для создания чего-то вроде изображение монохромной производной, вы не сможете заставить его работать, если загруженное изображение точно такого же размера, как размер изображения youre используя для черно-белой версии).

Я думаю, что в вашем случае есть обходное решение, так как вы используете Imagick, в том, что вы можете сделать некоторую графическую математику. Используя функцию borderImage, просто добавьте границу к каждому изображению на 1 пиксель больше, чем загруженное изображение. Поскольку add_image_size() посевы из центра по умолчанию должны вызывать изменение размера до необходимого вам размера и решить проблему.

Например, вы хотите размеры 1920 x 1080. Используя Imagick getSize, вы можете проверить размер изображения. Допустим, это ровно 1920 x 1080, но, как мы знаем, это не вызовет размытие. Таким образом, используя borderImage, мы добавляем к изображению 1 пиксельную белую рамку. Это должно вызвать wordpress для изменения размера изображения до 1920 x 1080, если растение установлено в true.

Если изображение меньше, но относительно близко к нужному размеру, мы просто делаем границу, чтобы сказать 10 пикселей и т.д., чтобы заполнить размер, и позволить Wordpress обрезать из центра. Это будет работать только с пропорциональными изображениями.

Если изображение будет немного меньше, скажем, 200 х 800, мы должны рассмотреть возможность добавления другой опции add_image_size() для обработки меньших изображений. Если вам нужно продвигаться вперед, мы можем либо использовать Imagick, чтобы "расширить" наш образ до необходимых пропорций, либо мы можем создать новый белый холст Imagick, который нам нужен, и наложить изображение вверху слева, чтобы у нас были пробелы ниже и право на наш новый образ. Затем вы должны использовать параметр обрезки add_image_size для обрезания лишнего белого. Например, add_image_size('background-image-blurred', 1920, 1080, array('left','top')), чтобы установить обрезку, начиная с левого верхнего угла изображения.

Ответ 3

Я думаю, вам нужно немного обмануть, почему вы не пытаетесь создать изображение размером 1 x 1 или 5 X 5, поэтому каждый раз, независимо от того, изображение должно было бы генерировать Thumbnail для этого изображения.

и на 'wp_generate_attachment_metadata' взломать материал и сгенерировать изображение с исходного изображения и заменить изображение 1 x 1 изображением Blured, которое вы хотите от него вам нужно обмануть фильтр, если вы используете "background-image-blurred" в любых местах для отображения или других целей расчета.

Надеюсь, у вас есть идея, я думаю, что это немного взломать, но должно работать правильно.

Ответ 5

Повседневное предложение: поскольку вы только размываете изображение и не делаете никаких других изменений изображения, почему бы не позволить CSS выполнять работу без создания другого изображения на сервере?

.heroBackgroundImage {
    background: url('uploadedimage.jpg'); 
    -webkit-filter: blur(8px);
    -moz-filter: blur(8px); 
    -o-filter: blur(8px); 
    -ms-filter: blur(8px); 
    filter: blur(8px);
    -webkit-transform: translate3d(0,0,0);
}

Сохранить усилия сервера; пусть это будет обрабатываться на стороне клиента.

РЕДАКТИРОВАТЬ: Просто видел, что ваш комментарий об этом не может быть CSS. Добавлен webkit-transform для перемещения эффекта на GPU, что делает его более эффективным. В противном случае, все еще сохраняя для потомства.