WordPress — размытое изображение при загрузке

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

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

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

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

/**
* 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's been blurred
unlink( $original_image_path );

return $new_filename;

}

10

Решение

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

У меня нет imagick, поэтому вам придется попробовать эти функции самостоятельно, но у вас есть правильный процесс выше, вам просто нужно обновить имя файла и ввести в массив ниже. 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;

}

Обновления

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

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

  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
3

Другие решения

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

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

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

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

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

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

Например, вы хотите размеры 1920 х 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')) установить обрезку, начиная с верхнего левого края изображения.

1

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

и на ‘Wp_generate_attachment_metadata’ Взломать материал и сгенерировать изображение из исходного изображения и заменить 1 х 1 изображение с изображением Blured, которое вы хотите там, конечно, вам нужно обмануть фильтр, если вы используете «Фоновое изображение размыта» в любых местах для отображения или других вычислительных целей.

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

0

Как насчет того, чтобы сосредоточиться на wp_handle_upload () функционировать?

Вот примеро том, как это было использовано для размытия изображений.

0

Нестандартное предложение: поскольку вы только размыли изображение и не вносите никаких других изменений в изображение, почему бы не позволить 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 для перемещения эффекта в графический процессор, что делает его более эффективным. В противном случае все еще коплю на потомство.

0