Cum să generezi miniaturi doar când sunt necesare?
Am 1000 de imagini. Cum pot face WordPress să genereze miniaturi doar când sunt necesare? De exemplu, sliderul din prima pagină va folosi doar 10 imagini și nu vreau ca celelalte 1000 de imagini să aibă acea miniatură generată deoarece este o risipă de spațiu și resurse.
Există o modalitate de a declanșa add_image_size doar când este necesar?
Mulțumesc
ACTUALIZARE După cum menționați, nu este chiar add_image_size ceea ce trebuie declanșat. Ar fi grozav să declanșăm redimensionarea imaginii când folosesc the_post_thumbnail('slider-thumb'); Poate că acest lucru va încetini prima vizualizare a imaginii, dar acea vizualizare este de obicei generată de mine când revizuiesc efectiv articolul, așa că nu mă deranjează.
Deci, între articolele mele, slider, miniaturile blogului, miniaturile portofoliului etc. am 1000 de imagini și vreau ca doar 10 imagini să fie redimensionate pentru slider. Văd multe resurse irosite pentru generarea dimensiunii miniaturii pentru celelalte 990 de imagini.
Sper că este clar acum, îmi cer scuze pentru engleza mea
Aruncă un ochi la plugin-ul Dynamic Image Resizer al lui Otto
Acest plugin modifică modul în care WordPress creează imaginile, astfel încât acestea sunt generate doar atunci când sunt efectiv folosite undeva, din mers. Imaginile create în acest fel vor fi salvate în directoarele normale de încărcare, pentru a fi trimise rapid ulterior de către serverul web. Rezultatul este că se economisește spațiu (deoarece imaginile sunt create doar atunci când sunt necesare), iar încărcarea imaginilor este mult mai rapidă (deoarece nu mai generează imaginile la încărcare).

Rețineți că acel plugin are o problemă cu adăugarea imaginilor în postările vechi. Contribuțiile sunt binevenite.

Exact asta căutam. O să încerc. Deci funcționează doar pe postări noi?

Pentru cei care ajung acum la această postare, iată un plugin similar care pare să fie în continuă dezvoltare: https://wordpress.org/plugins/fly-dynamic-image-resizer/

Pune acest cod în fișierul de funcții al temei tale. Acesta va opri WordPress din crearea altor dimensiuni în afară de cele 3 implicite atunci când încarci o imagine.
Când o imagine este solicitată într-o anumită dimensiune care nu a fost încă generată, aceasta va fi creată doar o singură dată.
add_filter('image_downsize', 'ml_media_downsize', 10, 3);
function ml_media_downsize($out, $id, $size) {
// Dacă dimensiunea imaginii există, lasă WordPress să o servească normal
$imagedata = wp_get_attachment_metadata($id);
if (is_array($imagedata) && isset($imagedata['sizes'][$size]))
return false;
// Verifică dacă dimensiunea solicitată există, altfel întrerupe
global $_wp_additional_image_sizes;
if (!isset($_wp_additional_image_sizes[$size]))
return false;
// Crează noua miniatură
if (!$resized = image_make_intermediate_size(
get_attached_file($id),
$_wp_additional_image_sizes[$size]['width'],
$_wp_additional_image_sizes[$size]['height'],
$_wp_additional_image_sizes[$size]['crop']
))
return false;
// Salvează metadatele imaginii, altfel WordPress nu va vedea că miniatura există acum
$imagedata['sizes'][$size] = $resized;
wp_update_attachment_metadata($id, $imagedata);
// Returnează array-ul pentru afișarea imaginii redimensionate
$att_url = wp_get_attachment_url($id);
return array(dirname($att_url) . '/' . $resized['file'], $resized['width'], $resized['height'], true);
}
add_filter('intermediate_image_sizes_advanced', 'ml_media_prevent_resize_on_upload');
function ml_media_prevent_resize_on_upload($sizes) {
// Eliminarea acestor dimensiuni implicite ar putea cauza probleme, așa că le păstrăm
return array(
'thumbnail' => $sizes['thumbnail'],
'medium' => $sizes['medium'],
'large' => $sizes['large']
);
}

Acest filtru ar trebui să fie standard în WordPress. De ce să generezi fiecare dimensiune pentru fiecare imagine? Adaug acest cod în temele mele personalizate. Mulțumesc

Drăguț, dar acum tot va genera toate imaginile dacă am nevoie doar de o singură dimensiune personalizată..

Nu funcționează DACA add_image_size a fost definit anterior cu dimensiunile imaginii doar schimbate

@Michaelkay există o penalizare de performanță în această abordare. Când imaginile sunt încărcate și apoi generate pentru fiecare dimensiune, înseamnă că cel care încarcă este cel care are răbdare. Acest cod face ca vizitatorii tăi să aibă nevoie de mai multă răbdare, iar Google a demonstrat că site-urile care se încarcă în mai mult de 2 secunde pierd 50% din vizitatori. De asemenea, dacă site-ul tău are sute de vizite simultane, acest lucru poate suprasolicita serverele tale.

Din păcate, răspunsul lui @Patrick întrerupe funcțiile srcset introduse în WordPress 4.4. Din fericire, trebuie doar să adăugăm două funcții suplimentare!
Mai întâi, trebuie să reintroducem temporar toate dimensiunile înregistrate ale miniaturilor în metadatele imaginii, astfel încât acestea să poată fi luate în considerare:
function bi_wp_calculate_image_srcset_meta($image_meta, $size_array, $image_src, $attachment_id){
// toate dimensiunile înregistrate
global $_wp_additional_image_sizes;
// câteva detalii despre fișierul sursă pe care le vom folosi des
$src_path = get_attached_file($attachment_id);
$src_info = pathinfo($src_path);
$src_root = trailingslashit($src_info['dirname']);
$src_ext = $src_info['extension'];
$src_mime = wp_check_filetype($src_path);
$src_mime = $src_mime['type'];
$src_base = wp_basename($src_path, ".$src_ext");
// găsim ce lipsește
foreach($_wp_additional_image_sizes AS $k=>$v)
{
if(!isset($image_meta['sizes'][$k]))
{
// mai întâi, să aflăm cum ar arăta dimensional
$new_size = image_resize_dimensions($image_meta['width'], $image_meta['height'], $v['width'], $v['height'], $v['crop']);
if(!$new_size)
continue;
$new_w = (int) $new_size[4];
$new_h = (int) $new_size[5];
// valori incorecte
if(!$new_h || !$new_w)
continue;
// generăm un nume de fișier în același mod ca WP_Image_Editor
$new_f = wp_basename("{$src_root}{$src_base}-{$new_w}x{$new_h}." . strtolower($src_ext));
// în final, îl adăugăm!
$image_meta['sizes'][$k] = array(
'file' => $new_f,
'width' => $new_w,
'height' => $new_h,
'mime-type' => $src_mime
);
}
}
return $image_meta;
}
add_filter('wp_calculate_image_srcset_meta', 'bi_wp_calculate_image_srcset_meta', 10, 4);
Apoi trebuie să parcurgem potrivirile și să generăm orice miniatură lipsă:
function bi_wp_calculate_image_srcset($sources, $size_array, $image_src, $image_meta, $attachment_id){
// obținem câteva informații despre sursă
$src_path = get_attached_file($attachment_id);
$src_root = trailingslashit(pathinfo($src_path, PATHINFO_DIRNAME));
// metadatele reale ale imaginii (care ar putea fi modificate aici)
$src_meta = wp_get_attachment_metadata($attachment_id);
// un array de dimensiuni posibile prin care să căutăm
$sizes = $image_meta['sizes'];
unset($sizes['thumbnail']);
unset($sizes['medium']);
unset($sizes['large']);
$new = false;
// parcurgem sursele
foreach($sources AS $k=>$v)
{
$name = wp_basename($v['url']);
if(!file_exists("{$src_root}{$name}"))
{
// găsim dimensiunea corespunzătoare
foreach($sizes AS $k2=>$v2)
{
// am găsit o potrivire!
if($v2['file'] === $name)
{
// o generăm
if(!$resized = image_make_intermediate_size(
$src_path,
$v2['width'],
$v2['height'],
$v2['crop']
)){
// eliminăm din surse în caz de eșec
unset($sources[$k]);
}
else
{
// adăugăm noua miniatură la metadatele reale
$new = true;
$src_meta['sizes'][$k2] = $resized;
}
// eliminăm din array-ul de dimensiuni pentru a avea
// mai puține de căutat data viitoare
unset($sizes[$k2]);
break;
}//potrivire
}//fiecare dimensiune
}//fiecare 404
}//fiecare sursă
// dacă am generat ceva, actualizăm metadatele atașamentului
if($new)
wp_update_attachment_metadata($attachment_id, $src_meta);
return $sources;
}
add_filter('wp_calculate_image_srcset', 'bi_wp_calculate_image_srcset', 10, 5);

De fapt, add_image_size()
nu generează thumbnail-ul, ci doar înregistrează o dimensiune de imagine ca fiind disponibilă în WordPress.
De obicei, thumbnail-urile sunt generate atunci când imaginea este încărcată pentru prima dată. Este un proces automat, așa că nu trebuie să vă faceți griji cu privire la generarea lor ulterioară. Gândiți-vă în felul următor - dacă durează 1-2 secunde să generezi un thumbnail pe un server lent și aștepți până când este solicitat, forțezi vizitatorul să aștepte încă 1-2 secunde pe imagine pentru a vedea conținutul. Este mult mai ușor să faci asta din timp - adică atunci când imaginea este încărcată.
În același timp, dacă trebuie neapărat să procesați thumbnail-urile într-un moment diferit, ați putea să aruncați o privire la plugin-ul Viper's Regenerate Thumbnails. Acesta folosește o acțiune la cerere pentru a regenera toate thumbnail-urile imaginilor tale... dar ai putea folosi un cod similar pentru a genera thumbnail-uri doar atunci când este necesar.

Cred că nu ai înțeles ideea. El vrea să controleze pentru care imagini este nevoie de miniaturi. Deci unele imagini nu trebuie redimensionate deloc.

Cei mai mulți oameni testează paginile când introduc fotografii (simt că pot spune cu încredere că toți). Aceștia vor provoca generarea fișierelor necesare o singură dată și ai terminat. În cazul meu, am o dimensiune de imagine pentru antet înregistrată. Aproximativ 1 din 20 de imagini pe care le încarc sunt de fapt pentru antet. Deci 19 din 20 de imagini din biblioteca mea reprezintă un risipă de spațiu.

Există vreo modalitate de a declanșa add_image_size doar atunci când este necesar?
Nu exact. Dar poți filtra lista de dimensiuni înregistrate chiar înainte ca thumbnail-urile să fie generate. Funcția wp_generate_attachment_metadata() (care apelează funcția care generează thumbnail-urile) are un filtru numit "intermediate_image_sizes_advanced", care îți permite să manipulezi array-ul de dimensiuni chiar înainte ca fișierele să fie generate. Ai putea folosi acest filtru ori de câte ori adaugi o imagine de un anumit "tip", apoi să-l elimini imediat după aceea.
Presupun că cea mai mare provocare ar fi să descoperi cum să diferențiezi între imaginile care necesită dimensiuni suplimentare și cele care nu.

Puteți folosi pluginul meu (nu al lui Ottos) "Dynamic Image Resize" 1).
„Dynamic Image Resize” este un plugin WordPress (MU-) care oferă un shortcode și o etichetă de șablon pentru a redimensiona imagini „on the fly” fără a fi nevoie de TimThumb, ci folosind funcțiile de bază ale WordPress.
Pluginul vine cu o etichetă de șablon și un shortcode.
1) Tocmai am aflat despre pluginul lui Otto. Coincidența de denumire nu a fost intenționată.

Puteți încerca acest plugin: https://wordpress.org/plugins/optimize-images-resizing
Redimensionează imaginile în funcție de dimensiunile de imagine înregistrate, dar doar atunci când este necesar. De asemenea, poate curăța dimensiunile existente ale imaginilor, astfel încât acestea să poată fi regenerate.

Plugin-ul WP Performance Pack oferă „gestionare îmbunătățită a imaginilor”, care se bazează pe Ottos Dynamic Image Resizer, dar include multe îmbunătățiri, de exemplu: În primul rând este compatibil cu cea mai recentă versiune de WordPress (3.9.1), folosește WP_Image_Editor, salvarea thumbnail-urilor poate fi dezactivată (dar acestea pot fi stocate în cache și suportul CDN este în curs de implementare), integrare cu Regenerate Thumbnails (pentru a șterge thumbnail-urile existente) și multe altele.

Iată încă o abordare: Se conectează la gestionarea erorilor HTTP 404. Adică, atunci când o miniatură nu este disponibilă, găsește imaginea originală și creează miniatura. Reține că aceasta nu rezolvă cu adevărat problema ta, deoarece nu împiedică generarea miniaturilor în timpul încărcării.
De asemenea, reține că acest plugin ar putea fi folosit de utilizatori rău intenționați pentru a crea oricâte miniaturi și astfel să consume spațiul de stocare.
Notă: Acest plugin poate fi instalat cu ușurință folosind Pluginception.
<?php
/*
Plugin Name: Creare miniaturi la cerere
Plugin URI:
Description: Creează miniaturi în loc să afișeze eroarea 404. Folosește în combinație cu "Broken Link Checker" pentru a crea toate miniaturile lipsă.
Version: 0.1
Author: Jack Miller
Author URI:
License:
License URI:
*/
add_filter('status_header', 'createThumbIf404');
function createThumbIf404($httpCodeString) //ex. HTTP/1.1 200 OK
{
global $wp_query;
error_reporting(E_ALL);
ini_set('display_errors', 1);
$httpCode = explode(" ", $httpCodeString);
$httpCode = $httpCode[1];
if ($httpCode == "404") {
$requestUri = $_SERVER["REQUEST_URI"];
$regex = '/^\/(wp-content\/uploads\/(?:[a-zA-Z0-9]*\/){2})(.*)-(.*)x(.*)\.jpg$/';
preg_match($regex, $requestUri, $groups);
if (sizeof($groups) === 5) {
$baseDir = $groups[1];
$baseName = $groups[2];
$sizeX = $groups[3];
$sizeY = $groups[4];
$oriImg = ctod_checkFile($baseDir, $baseName);
if ($oriImg != null) {
$image = wp_get_image_editor($baseDir . $oriImg);
if (!is_wp_error($image)) {
$image->resize($sizeX, $sizeY, true);
$thumb = $baseDir . $baseName . '-' . $sizeX . 'x' . $sizeY . '.jpg';
$image->save($thumb);
ctod_sendImageAndExit($thumb);
}
}
}
}
}
//găsește imaginea originală în $baseDir cu $baseName.
//Returnează numele fișierului inclusiv extensia imaginii originale sau null.
function ctod_checkFile($baseDir, $baseName)
{
$arr = array(
".jpg",
".JPG",
".jpeg",
".JPEG"
);
foreach ($arr as &$ext) {
if (file_exists($baseDir . $baseName . $ext)) {
return $baseName . $ext;
}
}
return null;
}
//Citește fișierul de la $path de pe disc și îl returnează ca cerere HTTP de imagine JPG.
function ctod_sendImageAndExit($path)
{
$fp = fopen($path, 'rb');
header("Content-Type: image/jpeg");
header("Content-Length: " . filesize($path));
fpassthru($fp);
exit();
}

În alte locuri toate dimensiunile create vor funcționa, dar doar la încărcarea media dacă doriți ca o dimensiune specifică să fie încărcată, atunci mai jos este codul pentru aceasta. Iată linkul pentru mai multe detalii - https://developer.wordpress.org/reference/hooks/wp_handle_upload_prefilter/
add_filter('wp_handle_upload_prefilter', 'custom_upload_filter' );
function custom_upload_filter( $file ) {
foreach ( get_intermediate_image_sizes() as $size ) {
if ( !in_array( $size, array( 'thumbnail', 'medium', 'medium_large', 'large' ) ) {
remove_image_size( $size );
}
}
return $file;
}

Puteți încerca și Aqua Resizer - https://github.com/syamilmj/Aqua-Resizer/
Este doar un singur fișier.
Puteți să-l utilizați astfel:
$img_src = aq_resize( $img_src, $width = null, $height = null, $crop = null, $single = true, $upscale = false );
$img_src = aq_resize( $img_src, 150, 150); // redimensionat
$img_src = aq_resize( $img_src, 150, 150, true); // decupat
$img_src = aq_resize( $img_src, 150, 150, null, null, true); // imaginea cu dimensiunile 120x120, de exemplu, va fi mărită la 150x150
