Changeset 3662711
- Timestamp:
- 08/24/2026 06:19:47 AM (2 months ago)
- Location:
- mits-image-optimizer
- Files:
-
- 4 edited
- 1 copied
-
tags/1.2.74 (copied) (copied from mits-image-optimizer/trunk )
-
tags/1.2.74/mits-image-optimizer.php (modified) (8 diffs)
-
tags/1.2.74/readme.txt (modified) (2 diffs)
-
trunk/mits-image-optimizer.php (modified) (8 diffs)
-
trunk/readme.txt (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
mits-image-optimizer/tags/1.2.74/mits-image-optimizer.php
r3654055 r3662711 3 3 * Plugin Name: MITS Image Optimizer 4 4 * Description: Auto-compress images on upload, bulk convert to WebP & AVIF, configure .htaccess for next-gen serving, scan for oversized images, and audit your site. 5 * Version: 1.2.7 25 * Version: 1.2.74 6 6 * Requires at least: 6.0 7 7 * Requires PHP: 8.0 … … 15 15 if ( ! defined( 'ABSPATH' ) ) exit; 16 16 17 define( 'MITS_OPT_VERSION', '1.2.7 2' );17 define( 'MITS_OPT_VERSION', '1.2.74' ); 18 18 define( 'MITS_OPT_FILE', __FILE__ ); 19 19 define( 'MITS_OPT_DIR', plugin_dir_path( __FILE__ ) ); … … 656 656 "</FilesMatch>\n" . 657 657 "</IfModule>\n" . 658 // WAZNE (wyuczone na produkcji): nie polegamy na tym, ze reszta .htaccess 659 // strony ma juz wpis ExpiresByType dla image/avif. Wiele gotowych configow 660 // WP ma go dla image/webp, ale nie dla avif (bo avif jest nowszy) - taki 661 // plik wtedy dostawal domyslny czas cache serwera (bywa to zaledwie 7 dni) 662 // zamiast miesiecy jak reszta obrazkow. Wlasny, samodzielny wpis w bloku 663 // wtyczki gwarantuje poprawny cache niezaleznie od reszty konfiguracji. 664 "<IfModule mod_expires.c>\n" . 665 "ExpiresActive On\n" . 666 "ExpiresByType image/avif \"access plus 1 year\"\n" . 667 "ExpiresByType image/webp \"access plus 1 year\"\n" . 668 "</IfModule>\n" . 669 "<IfModule mod_headers.c>\n" . 670 "<FilesMatch \"(?i)\\.(avif|webp)$\">\n" . 671 "Header set Cache-Control \"public, max-age=31536000, immutable\"\n" . 672 "</FilesMatch>\n" . 673 "</IfModule>\n" . 658 674 self::HTA_MARKER_END . "\n"; 659 675 } … … 1637 1653 /* ── WebP convert ────────────────────────────────────────────── */ 1638 1654 1655 /** 1656 * Derywat (WebP/AVIF) NIGDY nie moze byc wiekszy niz oryginal. Stare zdjecia 1657 * z aparatu bywaja w pelnej rozdzielczosci (8000px+), a nikt tak duzych nie 1658 * wyswietla w przegladarce - kodowanie ich 1:1 daje plik WIEKSZY od oryginalu 1659 * zamiast oszczednosci. Ograniczamy dluzszy bok do max_dimension z ustawien, 1660 * tak samo jak juz robi compress_imagick()/compress_gd() dla kompresji originalu. 1661 * NIE dotyka $src - operuje wylacznie na obiekcie/zasobie w pamieci. 1662 */ 1663 private function resize_for_derivative_imagick( Imagick $img, int $max ): void { 1664 if ( $img->getImageWidth() > $max || $img->getImageHeight() > $max ) { 1665 $img->resizeImage( $max, $max, Imagick::FILTER_LANCZOS, 1, true ); 1666 } 1667 } 1668 1669 private function resize_for_derivative_gd( $img, int $max ) { 1670 $w = imagesx( $img ); $h = imagesy( $img ); 1671 if ( $w <= $max && $h <= $max ) return $img; 1672 $ratio = min( $max / $w, $max / $h ); 1673 $nw = (int) round( $w * $ratio ); $nh = (int) round( $h * $ratio ); 1674 $res = imagecreatetruecolor( $nw, $nh ); 1675 imagealphablending( $res, false ); imagesavealpha( $res, true ); 1676 imagefill( $res, 0, 0, imagecolorallocatealpha( $res, 0, 0, 0, 127 ) ); 1677 imagecopyresampled( $res, $img, 0, 0, 0, 0, $nw, $nh, $w, $h ); 1678 imagedestroy( $img ); 1679 return $res; 1680 } 1681 1639 1682 private function convert_to_webp( string $src ): array { 1640 1683 $ext = strtolower( pathinfo( $src, PATHINFO_EXTENSION ) ); 1641 1684 $dest = preg_replace( '/\.(jpg|jpeg|png|gif)$/i', '.webp', $src ); 1685 $max = (int) $this->get_settings()['max_dimension']; 1642 1686 try { 1687 $imagick_failed = false; 1643 1688 if ( extension_loaded( 'imagick' ) ) { 1644 $img = new Imagick( $src );1645 1689 try { 1646 $img->setImageFormat( 'webp' ); 1647 $img->setImageCompressionQuality( self::WEBP_QUALITY ); 1648 $img->writeImage( $dest ); 1649 } finally { 1650 $img->destroy(); 1690 $img = new Imagick( $src ); 1691 try { 1692 $this->resize_for_derivative_imagick( $img, $max ); 1693 $img->setImageFormat( 'webp' ); 1694 $img->setImageCompressionQuality( self::WEBP_QUALITY ); 1695 $img->writeImage( $dest ); 1696 } finally { 1697 $img->destroy(); 1698 } 1699 } catch ( Throwable $e ) { 1700 // Np. limit policy.xml (szerokosc/wysokosc/area) na bardzo duzych 1701 // zdjeciach z aparatu - Imagick odmawia otwarcia pliku. GD tego 1702 // limitu nie ma, wiec probujemy nim zamiast od razu zglaszac blad. 1703 $imagick_failed = true; 1651 1704 } 1652 } elseif ( extension_loaded( 'gd' ) && function_exists( 'imagewebp' ) ) { 1705 } 1706 if ( ! extension_loaded( 'imagick' ) || $imagick_failed ) { 1707 if ( ! ( extension_loaded( 'gd' ) && function_exists( 'imagewebp' ) ) ) { 1708 return [ 'status' => 'error', 'reason' => $imagick_failed ? 'imagick_failed_no_gd_fallback' : 'no_gd_imagick' ]; 1709 } 1653 1710 $img = match ( $ext ) { 1654 1711 'jpg', 'jpeg' => imagecreatefromjpeg( $src ), … … 1659 1716 if ( ! $img ) return [ 'status' => 'error', 'reason' => 'cannot_load' ]; 1660 1717 if ( $ext === 'png' ) { imagepalettetotruecolor( $img ); imagealphablending( $img, true ); imagesavealpha( $img, true ); } 1718 $img = $this->resize_for_derivative_gd( $img, $max ); 1661 1719 imagewebp( $img, $dest, self::WEBP_QUALITY ); 1662 1720 imagedestroy( $img ); 1663 } else {1664 return [ 'status' => 'error', 'reason' => 'no_gd_imagick' ];1665 1721 } 1666 1722 $os = @filesize( $src ) ?: 0; … … 2412 2468 try { 2413 2469 $sup = $this->avif_supported(); 2470 $max = (int) $this->get_settings()['max_dimension']; 2471 $imagick_failed = false; 2414 2472 if ( $sup['imagick'] ) { 2415 $img = new Imagick( $src );2416 2473 try { 2417 if ( $img->getNumberImages() > 1 ) $img->setFirstIterator(); 2418 $img = $img->mergeImageLayers( Imagick::LAYERMETHOD_FLATTEN ); 2419 $img->setImageFormat( 'avif' ); 2420 $img->setImageCompressionQuality( self::AVIF_QUALITY ); 2421 $img->writeImage( $dest ); 2422 } finally { 2423 $img->destroy(); 2474 $img = new Imagick( $src ); 2475 try { 2476 if ( $img->getNumberImages() > 1 ) $img->setFirstIterator(); 2477 $img = $img->mergeImageLayers( Imagick::LAYERMETHOD_FLATTEN ); 2478 $this->resize_for_derivative_imagick( $img, $max ); 2479 $img->setImageFormat( 'avif' ); 2480 $img->setImageCompressionQuality( self::AVIF_QUALITY ); 2481 $img->writeImage( $dest ); 2482 } finally { 2483 $img->destroy(); 2484 } 2485 } catch ( Throwable $e ) { 2486 // Tak samo jak w convert_to_webp(): bardzo duze zdjecia potrafia 2487 // przekroczyc limit policy.xml Imagicka (szerokosc/wysokosc/area). 2488 // GD tego limitu nie ma - probujemy nim zamiast od razu zglaszac blad. 2489 if ( ! $sup['gd'] ) return [ 'status' => 'error', 'reason' => 'imagick: ' . $e->getMessage() ]; 2490 $imagick_failed = true; 2424 2491 } 2425 } elseif ( $sup['gd'] ) { 2492 } 2493 if ( $imagick_failed || ( ! $sup['imagick'] && $sup['gd'] ) ) { 2426 2494 $img = match ( $ext ) { 2427 2495 'jpg', 'jpeg' => imagecreatefromjpeg( $src ), … … 2436 2504 imagesavealpha( $img, true ); 2437 2505 } 2506 $img = $this->resize_for_derivative_gd( $img, $max ); 2438 2507 imageavif( $img, $dest, self::AVIF_QUALITY ); 2439 2508 imagedestroy( $img ); 2440 } elseif ( $sup['cli'] ) {2509 } elseif ( ! $sup['imagick'] && ! $sup['gd'] && $sup['cli'] ) { 2441 2510 // avifenc nie czyta WebP — dekodujemy najpierw do PNG (dwebp albo GD). 2511 // Ta sama okazja sluzy do przeskalowania - avifenc nie ma wlasnej opcji 2512 // zmiany rozmiaru, wiec bardzo duze zdjecia trzeba zmniejszyc PRZED 2513 // podaniem mu pliku (inaczej ten sam problem co bez skalowania: derywat 2514 // wiekszy od oryginalu). 2442 2515 $tmp_png = ''; 2443 2516 $input = $src; 2517 if ( function_exists( 'getimagesize' ) && $ext !== 'webp' ) { 2518 $info = @getimagesize( $src ); 2519 if ( $info && ( $info[0] > $max || $info[1] > $max ) && function_exists( 'imagecreatefromjpeg' ) ) { 2520 $im = $ext === 'png' ? @imagecreatefrompng( $src ) : @imagecreatefromjpeg( $src ); 2521 if ( $im ) { 2522 $im = $this->resize_for_derivative_gd( $im, $max ); 2523 $tmp_png = $src . '.mits-tmp-' . wp_generate_password( 6, false ) . '.png'; 2524 imagepng( $im, $tmp_png ); 2525 imagedestroy( $im ); 2526 $input = $tmp_png; 2527 } 2528 } 2529 } 2444 2530 if ( $ext === 'webp' ) { 2445 2531 $tmp_png = preg_replace( '/\.webp$/i', '', $src ) . '.mits-tmp-' . wp_generate_password( 6, false ) . '.png'; … … 2447 2533 if ( function_exists( 'imagecreatefromwebp' ) ) { 2448 2534 $im = @imagecreatefromwebp( $src ); 2449 if ( $im ) { $ ok = imagepng( $im, $tmp_png ); imagedestroy( $im ); }2535 if ( $im ) { $im = $this->resize_for_derivative_gd( $im, $max ); $ok = imagepng( $im, $tmp_png ); imagedestroy( $im ); } 2450 2536 } 2451 2537 if ( ! $ok ) { -
mits-image-optimizer/tags/1.2.74/readme.txt
r3654055 r3662711 5 5 Tested up to: 7.0 6 6 Requires PHP: 8.0 7 Stable tag: 1.2.7 27 Stable tag: 1.2.74 8 8 License: GPL-2.0-or-later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 94 94 95 95 == Changelog == 96 97 = 1.2.74 = 98 * .htaccess: blok wtyczki dostaje teraz WŁASNE reguły ExpiresByType/Cache-Control dla 99 .avif i .webp (1 rok, immutable), zamiast polegać na tym, że reszta .htaccess strony 100 już ma wpis dla image/avif. Ustalone na produkcji: wiele gotowych configów WP ma 101 ExpiresByType image/webp, ale nie ma image/avif (bo avif jest nowszy format) - taki 102 plik dostawał wtedy domyślny czas cache serwera (bywa to zaledwie 7 dni) zamiast 103 miesięcy jak reszta obrazków, mimo że sam plik był już poprawnie skompresowany. 104 105 = 1.2.73 = 106 * WebP/AVIF: derywat jest teraz skalowany do max_dimension PRZED kodowaniem (tak jak 107 od dawna robi to funkcja kompresji oryginału). Wcześniej convert_to_webp()/ 108 convert_to_avif() kodowały w pełnej rozdzielczości źródła - dla zdjęć prosto 109 z aparatu (8000px+) dawało to plik .webp/.avif WIĘKSZY od oryginału, bo próg 110 15% oszczędności i tak go kasował, marnując czas konwersji. Ustalone na 111 produkcji: zdjęcie 2560x1706 (7 MB) dawało 4,8 MB "avif" zamiast ~300 KB. 112 * AVIF/WebP: jeśli Imagick odmówi otwarcia bardzo dużego pliku (limit width/height/area 113 w policy.xml serwera - poza naszą kontrolą na hostingu współdzielonym), konwersja 114 teraz automatycznie próbuje przez GD zamiast od razu zgłaszać błąd. GD tego limitu 115 nie ma. Wcześniej taki plik kończył się błędem i nigdy nie dostawał derywatu. 116 * AVIF (ścieżka CLI/avifenc): to samo skalowanie zastosowane też tutaj - avifenc nie ma 117 własnej opcji resize, więc dla dużych zdjęć trzeba je zmniejszyć przed podaniem mu pliku. 96 118 97 119 = 1.2.72 = -
mits-image-optimizer/trunk/mits-image-optimizer.php
r3654055 r3662711 3 3 * Plugin Name: MITS Image Optimizer 4 4 * Description: Auto-compress images on upload, bulk convert to WebP & AVIF, configure .htaccess for next-gen serving, scan for oversized images, and audit your site. 5 * Version: 1.2.7 25 * Version: 1.2.74 6 6 * Requires at least: 6.0 7 7 * Requires PHP: 8.0 … … 15 15 if ( ! defined( 'ABSPATH' ) ) exit; 16 16 17 define( 'MITS_OPT_VERSION', '1.2.7 2' );17 define( 'MITS_OPT_VERSION', '1.2.74' ); 18 18 define( 'MITS_OPT_FILE', __FILE__ ); 19 19 define( 'MITS_OPT_DIR', plugin_dir_path( __FILE__ ) ); … … 656 656 "</FilesMatch>\n" . 657 657 "</IfModule>\n" . 658 // WAZNE (wyuczone na produkcji): nie polegamy na tym, ze reszta .htaccess 659 // strony ma juz wpis ExpiresByType dla image/avif. Wiele gotowych configow 660 // WP ma go dla image/webp, ale nie dla avif (bo avif jest nowszy) - taki 661 // plik wtedy dostawal domyslny czas cache serwera (bywa to zaledwie 7 dni) 662 // zamiast miesiecy jak reszta obrazkow. Wlasny, samodzielny wpis w bloku 663 // wtyczki gwarantuje poprawny cache niezaleznie od reszty konfiguracji. 664 "<IfModule mod_expires.c>\n" . 665 "ExpiresActive On\n" . 666 "ExpiresByType image/avif \"access plus 1 year\"\n" . 667 "ExpiresByType image/webp \"access plus 1 year\"\n" . 668 "</IfModule>\n" . 669 "<IfModule mod_headers.c>\n" . 670 "<FilesMatch \"(?i)\\.(avif|webp)$\">\n" . 671 "Header set Cache-Control \"public, max-age=31536000, immutable\"\n" . 672 "</FilesMatch>\n" . 673 "</IfModule>\n" . 658 674 self::HTA_MARKER_END . "\n"; 659 675 } … … 1637 1653 /* ── WebP convert ────────────────────────────────────────────── */ 1638 1654 1655 /** 1656 * Derywat (WebP/AVIF) NIGDY nie moze byc wiekszy niz oryginal. Stare zdjecia 1657 * z aparatu bywaja w pelnej rozdzielczosci (8000px+), a nikt tak duzych nie 1658 * wyswietla w przegladarce - kodowanie ich 1:1 daje plik WIEKSZY od oryginalu 1659 * zamiast oszczednosci. Ograniczamy dluzszy bok do max_dimension z ustawien, 1660 * tak samo jak juz robi compress_imagick()/compress_gd() dla kompresji originalu. 1661 * NIE dotyka $src - operuje wylacznie na obiekcie/zasobie w pamieci. 1662 */ 1663 private function resize_for_derivative_imagick( Imagick $img, int $max ): void { 1664 if ( $img->getImageWidth() > $max || $img->getImageHeight() > $max ) { 1665 $img->resizeImage( $max, $max, Imagick::FILTER_LANCZOS, 1, true ); 1666 } 1667 } 1668 1669 private function resize_for_derivative_gd( $img, int $max ) { 1670 $w = imagesx( $img ); $h = imagesy( $img ); 1671 if ( $w <= $max && $h <= $max ) return $img; 1672 $ratio = min( $max / $w, $max / $h ); 1673 $nw = (int) round( $w * $ratio ); $nh = (int) round( $h * $ratio ); 1674 $res = imagecreatetruecolor( $nw, $nh ); 1675 imagealphablending( $res, false ); imagesavealpha( $res, true ); 1676 imagefill( $res, 0, 0, imagecolorallocatealpha( $res, 0, 0, 0, 127 ) ); 1677 imagecopyresampled( $res, $img, 0, 0, 0, 0, $nw, $nh, $w, $h ); 1678 imagedestroy( $img ); 1679 return $res; 1680 } 1681 1639 1682 private function convert_to_webp( string $src ): array { 1640 1683 $ext = strtolower( pathinfo( $src, PATHINFO_EXTENSION ) ); 1641 1684 $dest = preg_replace( '/\.(jpg|jpeg|png|gif)$/i', '.webp', $src ); 1685 $max = (int) $this->get_settings()['max_dimension']; 1642 1686 try { 1687 $imagick_failed = false; 1643 1688 if ( extension_loaded( 'imagick' ) ) { 1644 $img = new Imagick( $src );1645 1689 try { 1646 $img->setImageFormat( 'webp' ); 1647 $img->setImageCompressionQuality( self::WEBP_QUALITY ); 1648 $img->writeImage( $dest ); 1649 } finally { 1650 $img->destroy(); 1690 $img = new Imagick( $src ); 1691 try { 1692 $this->resize_for_derivative_imagick( $img, $max ); 1693 $img->setImageFormat( 'webp' ); 1694 $img->setImageCompressionQuality( self::WEBP_QUALITY ); 1695 $img->writeImage( $dest ); 1696 } finally { 1697 $img->destroy(); 1698 } 1699 } catch ( Throwable $e ) { 1700 // Np. limit policy.xml (szerokosc/wysokosc/area) na bardzo duzych 1701 // zdjeciach z aparatu - Imagick odmawia otwarcia pliku. GD tego 1702 // limitu nie ma, wiec probujemy nim zamiast od razu zglaszac blad. 1703 $imagick_failed = true; 1651 1704 } 1652 } elseif ( extension_loaded( 'gd' ) && function_exists( 'imagewebp' ) ) { 1705 } 1706 if ( ! extension_loaded( 'imagick' ) || $imagick_failed ) { 1707 if ( ! ( extension_loaded( 'gd' ) && function_exists( 'imagewebp' ) ) ) { 1708 return [ 'status' => 'error', 'reason' => $imagick_failed ? 'imagick_failed_no_gd_fallback' : 'no_gd_imagick' ]; 1709 } 1653 1710 $img = match ( $ext ) { 1654 1711 'jpg', 'jpeg' => imagecreatefromjpeg( $src ), … … 1659 1716 if ( ! $img ) return [ 'status' => 'error', 'reason' => 'cannot_load' ]; 1660 1717 if ( $ext === 'png' ) { imagepalettetotruecolor( $img ); imagealphablending( $img, true ); imagesavealpha( $img, true ); } 1718 $img = $this->resize_for_derivative_gd( $img, $max ); 1661 1719 imagewebp( $img, $dest, self::WEBP_QUALITY ); 1662 1720 imagedestroy( $img ); 1663 } else {1664 return [ 'status' => 'error', 'reason' => 'no_gd_imagick' ];1665 1721 } 1666 1722 $os = @filesize( $src ) ?: 0; … … 2412 2468 try { 2413 2469 $sup = $this->avif_supported(); 2470 $max = (int) $this->get_settings()['max_dimension']; 2471 $imagick_failed = false; 2414 2472 if ( $sup['imagick'] ) { 2415 $img = new Imagick( $src );2416 2473 try { 2417 if ( $img->getNumberImages() > 1 ) $img->setFirstIterator(); 2418 $img = $img->mergeImageLayers( Imagick::LAYERMETHOD_FLATTEN ); 2419 $img->setImageFormat( 'avif' ); 2420 $img->setImageCompressionQuality( self::AVIF_QUALITY ); 2421 $img->writeImage( $dest ); 2422 } finally { 2423 $img->destroy(); 2474 $img = new Imagick( $src ); 2475 try { 2476 if ( $img->getNumberImages() > 1 ) $img->setFirstIterator(); 2477 $img = $img->mergeImageLayers( Imagick::LAYERMETHOD_FLATTEN ); 2478 $this->resize_for_derivative_imagick( $img, $max ); 2479 $img->setImageFormat( 'avif' ); 2480 $img->setImageCompressionQuality( self::AVIF_QUALITY ); 2481 $img->writeImage( $dest ); 2482 } finally { 2483 $img->destroy(); 2484 } 2485 } catch ( Throwable $e ) { 2486 // Tak samo jak w convert_to_webp(): bardzo duze zdjecia potrafia 2487 // przekroczyc limit policy.xml Imagicka (szerokosc/wysokosc/area). 2488 // GD tego limitu nie ma - probujemy nim zamiast od razu zglaszac blad. 2489 if ( ! $sup['gd'] ) return [ 'status' => 'error', 'reason' => 'imagick: ' . $e->getMessage() ]; 2490 $imagick_failed = true; 2424 2491 } 2425 } elseif ( $sup['gd'] ) { 2492 } 2493 if ( $imagick_failed || ( ! $sup['imagick'] && $sup['gd'] ) ) { 2426 2494 $img = match ( $ext ) { 2427 2495 'jpg', 'jpeg' => imagecreatefromjpeg( $src ), … … 2436 2504 imagesavealpha( $img, true ); 2437 2505 } 2506 $img = $this->resize_for_derivative_gd( $img, $max ); 2438 2507 imageavif( $img, $dest, self::AVIF_QUALITY ); 2439 2508 imagedestroy( $img ); 2440 } elseif ( $sup['cli'] ) {2509 } elseif ( ! $sup['imagick'] && ! $sup['gd'] && $sup['cli'] ) { 2441 2510 // avifenc nie czyta WebP — dekodujemy najpierw do PNG (dwebp albo GD). 2511 // Ta sama okazja sluzy do przeskalowania - avifenc nie ma wlasnej opcji 2512 // zmiany rozmiaru, wiec bardzo duze zdjecia trzeba zmniejszyc PRZED 2513 // podaniem mu pliku (inaczej ten sam problem co bez skalowania: derywat 2514 // wiekszy od oryginalu). 2442 2515 $tmp_png = ''; 2443 2516 $input = $src; 2517 if ( function_exists( 'getimagesize' ) && $ext !== 'webp' ) { 2518 $info = @getimagesize( $src ); 2519 if ( $info && ( $info[0] > $max || $info[1] > $max ) && function_exists( 'imagecreatefromjpeg' ) ) { 2520 $im = $ext === 'png' ? @imagecreatefrompng( $src ) : @imagecreatefromjpeg( $src ); 2521 if ( $im ) { 2522 $im = $this->resize_for_derivative_gd( $im, $max ); 2523 $tmp_png = $src . '.mits-tmp-' . wp_generate_password( 6, false ) . '.png'; 2524 imagepng( $im, $tmp_png ); 2525 imagedestroy( $im ); 2526 $input = $tmp_png; 2527 } 2528 } 2529 } 2444 2530 if ( $ext === 'webp' ) { 2445 2531 $tmp_png = preg_replace( '/\.webp$/i', '', $src ) . '.mits-tmp-' . wp_generate_password( 6, false ) . '.png'; … … 2447 2533 if ( function_exists( 'imagecreatefromwebp' ) ) { 2448 2534 $im = @imagecreatefromwebp( $src ); 2449 if ( $im ) { $ ok = imagepng( $im, $tmp_png ); imagedestroy( $im ); }2535 if ( $im ) { $im = $this->resize_for_derivative_gd( $im, $max ); $ok = imagepng( $im, $tmp_png ); imagedestroy( $im ); } 2450 2536 } 2451 2537 if ( ! $ok ) { -
mits-image-optimizer/trunk/readme.txt
r3654055 r3662711 5 5 Tested up to: 7.0 6 6 Requires PHP: 8.0 7 Stable tag: 1.2.7 27 Stable tag: 1.2.74 8 8 License: GPL-2.0-or-later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 94 94 95 95 == Changelog == 96 97 = 1.2.74 = 98 * .htaccess: blok wtyczki dostaje teraz WŁASNE reguły ExpiresByType/Cache-Control dla 99 .avif i .webp (1 rok, immutable), zamiast polegać na tym, że reszta .htaccess strony 100 już ma wpis dla image/avif. Ustalone na produkcji: wiele gotowych configów WP ma 101 ExpiresByType image/webp, ale nie ma image/avif (bo avif jest nowszy format) - taki 102 plik dostawał wtedy domyślny czas cache serwera (bywa to zaledwie 7 dni) zamiast 103 miesięcy jak reszta obrazków, mimo że sam plik był już poprawnie skompresowany. 104 105 = 1.2.73 = 106 * WebP/AVIF: derywat jest teraz skalowany do max_dimension PRZED kodowaniem (tak jak 107 od dawna robi to funkcja kompresji oryginału). Wcześniej convert_to_webp()/ 108 convert_to_avif() kodowały w pełnej rozdzielczości źródła - dla zdjęć prosto 109 z aparatu (8000px+) dawało to plik .webp/.avif WIĘKSZY od oryginału, bo próg 110 15% oszczędności i tak go kasował, marnując czas konwersji. Ustalone na 111 produkcji: zdjęcie 2560x1706 (7 MB) dawało 4,8 MB "avif" zamiast ~300 KB. 112 * AVIF/WebP: jeśli Imagick odmówi otwarcia bardzo dużego pliku (limit width/height/area 113 w policy.xml serwera - poza naszą kontrolą na hostingu współdzielonym), konwersja 114 teraz automatycznie próbuje przez GD zamiast od razu zgłaszać błąd. GD tego limitu 115 nie ma. Wcześniej taki plik kończył się błędem i nigdy nie dostawał derywatu. 116 * AVIF (ścieżka CLI/avifenc): to samo skalowanie zastosowane też tutaj - avifenc nie ma 117 własnej opcji resize, więc dla dużych zdjęć trzeba je zmniejszyć przed podaniem mu pliku. 96 118 97 119 = 1.2.72 =
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)