Czy można ustawić jakość obrazu na podstawie rozmiaru obrazu? Chciałbym mieć lepszą jakość obrazu dla większych obrazów (80) - a gorszą dla małych miniatur (30).
Spodziewałem się parametru, add_sizektóry to kontroluje - ale nie ma żadnego.
Jedyne ustawienie czasu, które naprawdę ma znaczenie, to tuż przed zapisaniem lub przesłaniem obrazu (dla edytora). Oba mają tam filtr „image_editor_save_pre”, przekazując mu instancję edytora obrazów. Dzięki temu możesz modyfikować obraz w dowolny sposób, w tym ustawić jakość.
Coś takiego powinno więc wykonać zadanie w prosty i łatwy sposób:
add_filter('image_editor_save_pre','example_adjust_quality');function example_adjust_quality($image){
$size = $image->get_size();// Values are $size['width'] and $size['height']. Based on those, do what you like. Example:if( $size['width']<=100){
$image->set_quality(30);}if( $size['width']>100&& $size['width']<=300){
$image->set_quality(70);}if( $size['width']>300){
$image->set_quality(80);}return $image;}
Powodem, dla którego nie użyłem czegoś tak prostego jak ten (+1) jest to, że niejasno pamiętam, że podczas edycji jakiegoś obrazu (obracanie, przycinanie itp.) Każda akcja była wywoływana dwukrotnie, co dwukrotnie obniżało jakość. Mimo to część „jest przykładem WP_Image_Editor” jest rozwiązaniem o wiele bardziej niż to, co napisałem.
kaiser
1
Jakość to dokładna wartość, a nie procent. Możesz ustawić i zresetować wszystko, co chcesz, dopóki nie zostanie zapisane. Ustawienie go na 10 stokroć pozostawia ją na 10.
Otto
Zakładałem, że zaoszczędzę pomiędzy. Dzięki za heads-upy.
kaiser
Wydaje mi się, że image_editor_save_prenie można się nazywać. Kiedy próbuję wyprowadzać dane za pomocą error_log(co zdecydowanie działa), nie otrzymuję żadnych danych wyjściowych. : /
Nils Riedemann
1
Regeneracja może również działać, jeśli ponownie zapisuje obraz. Żaden kod nie zmieni istniejących plików w systemie bez podjęcia działań w celu ich ponownego załadowania i ponownego zapisania.
Otto
5
Uwaga z góry: Poniższa odpowiedź nie jest ukończona i nie została przetestowana, ale nie mam wystarczająco dużo czasu, więc zostawię ją tutaj jako wersję roboczą. Druga para oczu prawdopodobnie potrzebuje metody jakości i interpretacji version_compare().
Najpierw potrzebujemy punktu wejścia. Po ponownym przeczytaniu „ make post” pomyślałem, że najlepiej będzie wskoczyć, zanim Edytor obrazów zapisze nowo utworzony obraz. Oto mikrokontroler, który przechwytuje przechwycone połączenie zwrotne image_editor_save_prei ładuje klasę, która następnie przechodzi przez ustawienia zdefiniowane w wywołaniu zwrotnym wpse_jpeg_quality. Zwraca po prostu różne współczynniki kompresji dla jpeg_qualityfiltra działającego w edytorze obrazów.
Rzeczywistym pracownikiem jest JPEGQualityWorkerklasa. Znajduje się w tym samym katalogu, co powyższy główny plik wtyczki i ma nazwę worker.php(lub zmienisz kontroler powyżej).
Pobiera obraz i twoje ustawienia, a następnie dodaje wywołania zwrotne do jpeg_qualityfiltra. To, co robi, jest
pobieranie odniesienia do obrazu (szerokość lub wysokość)
kwestionowanie punktu przerwania, który decyduje, gdzie przełączyć między niskim i wysokim współczynnikiem jakości / kompresji
pobieranie oryginalnego rozmiaru obrazu
decydowanie, jaką jakość zwrócić
Punktem granicznym i limitem jest to, co decyduje między wysokim a niskim, i jak wspomniano powyżej, może to wymagać trochę więcej miłości.
<?php
namespace WPSE;/**
* Class JPEGQualityWorker
* @package WPSE
*/classJPEGQualityWorker{protected $config, $image;/**
* @param string $image
* @param array $config
*/publicfunction __construct(Array $config, $image ){
$this->config = $config;
$this->image = $image;
add_filter('jpeg_quality', array( $this,'setQuality'),20,2);}/**
* Return the JPEG compression ratio.
*
* Avoids running in multiple context, as WP runs the function multiple
* times per resize/upload/edit task, which leads to over compressed images.
*
* @param int $compression
* @param string $context Context: edit_image/image_resize/wp_crop_image
* @return int
*/publicfunction setQuality( $compression, $context ){if( in_array( $context, array('edit_image','wp_crop_image',)))return100;
$c = $this->getCompression( $this->config, $this->image );return! is_wp_error( $c )? $c
:100;}/**
* @param array $config
* @param string $image
* @return int|string|\WP_Error
*/publicfunction getCompression(Array $config, $image ){
$reference = $this->getReference( $config );if( is_wp_error( $reference ))return $reference;
$size = $this->getOriginalSize( $image, $reference );if( is_wp_error( $size ))return $size;return $this->getQuality( $config, $size );}/**
* Returns the quality set for the current image size.
* If
* @param array $config
* @param int $size
*/protectedfunction getQuality(Array $config, $size ){
$result = version_compare( $config['breakpoint'], $size );return(0=== $result
AND in_array( $config['limit'], array('>','gt','>=','ge','==','=','eq'))||1=== $result
AND in_array( $config['limit'], array('<','lt','<=','le',)))? $config['high']: $config['low'];}/**
* Returns the reference size (width or height).
*
* @param array $config
* @return string|\WP_Error
*/protectedfunction getReference(Array $config ){
$r = $config['reference'];return! in_array( $r, array('w','h',))?new \WP_Error('wrong-arg',
sprintf('Wrong argument for "reference" in %s', __METHOD__ )): $r;}/**
* Returns the size of the original image (width or height)
* depending on the reference.
*
* @param string $image
* @param string $reference
* @return int|\WP_Error
*/protectedfunction getOriginalSize( $image, $reference ){
$size ='h'=== $reference
? imagesy( $image ): imagesx( $image );# @TODO Maybe check is_resource() to see if we got an image# @TODO Maybe check get_resource_type() for a valid image# @link http://www.php.net/manual/en/resource.phpreturn! $size
?new \WP_Error('image-failure',
sprintf('Resource failed in %s', get_class( $this ))): $size;}}
Nadal nad tym pracuję? Jeśli o mnie chodzi, chciałbym zobaczyć to jako wtyczkę.
Nils Riedemann
Przepraszam, ale nie, nie jestem. Chciałbym również zobaczyć to jako wtyczkę, ale ponieważ obecnie nie potrzebuję jej i nie mam czasu, do tej pory tak się nie stało. Może spróbujesz, zobaczysz, jak daleko się posuniesz i prześlesz edycję lub osobną odpowiedź? :)
kaiser
kaiser: Myślę, że nadmiernie to skomplikowałeś. Obraz $ wysłany do image_editor_save_pre jest instancją klasy WP_Image_Editor. Ma funkcje pozwalające uzyskać rozmiar i ustawić jakość oraz wszystko, co już w nim jest. Wszystko, co musisz zrobić, to zadzwonić do nich.
WP_Image_Editor
” jest rozwiązaniem o wiele bardziej niż to, co napisałem.image_editor_save_pre
nie można się nazywać. Kiedy próbuję wyprowadzać dane za pomocąerror_log
(co zdecydowanie działa), nie otrzymuję żadnych danych wyjściowych. : /Uwaga z góry: Poniższa odpowiedź nie jest ukończona i nie została przetestowana, ale nie mam wystarczająco dużo czasu, więc zostawię ją tutaj jako wersję roboczą. Druga para oczu prawdopodobnie potrzebuje metody jakości i interpretacji
version_compare()
.Najpierw potrzebujemy punktu wejścia. Po ponownym przeczytaniu „ make post” pomyślałem, że najlepiej będzie wskoczyć, zanim Edytor obrazów zapisze nowo utworzony obraz. Oto mikrokontroler, który przechwytuje przechwycone połączenie zwrotne
image_editor_save_pre
i ładuje klasę, która następnie przechodzi przez ustawienia zdefiniowane w wywołaniu zwrotnymwpse_jpeg_quality
. Zwraca po prostu różne współczynniki kompresji dlajpeg_quality
filtra działającego w edytorze obrazów.Rzeczywistym pracownikiem jest
JPEGQualityWorker
klasa. Znajduje się w tym samym katalogu, co powyższy główny plik wtyczki i ma nazwęworker.php
(lub zmienisz kontroler powyżej).Pobiera obraz i twoje ustawienia, a następnie dodaje wywołania zwrotne do
jpeg_quality
filtra. To, co robi, jestPunktem granicznym i limitem jest to, co decyduje między wysokim a niskim, i jak wspomniano powyżej, może to wymagać trochę więcej miłości.
źródło