Görüntü boyutuna göre görüntü kalitesi


15

Görüntü kalitesini görüntü boyutuna göre ayarlamak mümkün müdür? Daha büyük görüntüler için daha iyi görüntü kalitesine sahip olmak istiyorum (80) - küçük resimler için daha kötüdür (30).

Bunu add_sizekontrol etmek için bir parametre bekliyordum - ama hiç yok.

Önemli olursa: ImageMagick kullanıyorum.

Yanıtlar:


15

Kaliteyi gerçekten ayarlayan tek zaman, görüntü kaydedilmeden veya akıştan hemen önce (editör için). Bunların her ikisinde de "image_editor_save_pre" filtresi var ve bu görüntü editörü örneğini iletiyor. Kaliteyi ayarlamak da dahil olmak üzere görüntüyü istediğiniz şekilde değiştirmek için bunu kullanabilirsiniz.

Yani, böyle bir şey işi basit ve kolay bir şekilde yapmalıdır:

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;
}

Bu yüzden (+1) kadar düz bir şey kullanmamamın nedeni, bazı görüntüleri düzenlerken (döndürme, kırpma vb.), Her eylemin iki kez çağrıldığını ve kalitenin iki kez azaltıldığını hatırlıyorum. Yine de "bir örneğidir WP_Image_Editor" kısmı yazdığımdan çok daha fazla bir çözümdür.
kaiser

1
Kalite tam bir değerdir, yüzde değil. Kaydetene kadar istediğiniz gibi ayarlayabilir ve sıfırlayabilirsiniz. 10 yüze ayarlamak 10'da
Otto

Arada tasarruf edeceğini varsaydım. Söylediğin için teşekkürler.
kaiser

Bana öyle image_editor_save_pregeliyor ki çağrılmıyor. error_log(Bu kesinlikle işe yarıyor) kullanarak şeyler çıktı çalıştığımda herhangi bir çıktı elde edemiyorum. : /
Nils Riedemann

1
Yeniden oluşturma, görüntüyü yeniden kaydederse de işe yarayabilir. Hiçbir kod, onları yeniden yüklemek ve yeniden kaydetmek için harekete geçmeden sistemdeki mevcut dosyaları değiştirmeyecektir.
Otto

5

Açık not: Aşağıdaki cevap bitmedi ve test edilmedi, ancak yeterli zamanım kalmadı, bu yüzden bunu taslak olarak burada bırakacağım. Muhtemelen ikinci bir çift göze ihtiyaç duyan şey kalite yöntemi ve yorumudur version_compare().

Öncelikle bir giriş noktasına ihtiyacımız var. Make post'u tekrar okuduktan sonra , Image Editor'ın yeni oluşturulan görüntüyü kaydetmeden önce en iyi şekilde atlamak olacağını düşündüm. Burada, bir çağrının bağlandığı image_editor_save_preve daha sonra geri çağrının içinde tanımladığınız ayarlarda yürüyen bir sınıfı yükleyen bir mikro denetleyici wpse_jpeg_quality. jpeg_qualityGörüntü Düzenleyicide çalışan filtre için farklı sıkıştırma oranları döndürür .

<?php

namespace WPSE;

/**
 * Plugin Name: (#138751) JPEG Quality Router
 * Author:      Franz Josef Kaiser
 * Author URI:  http://unserkaiser.com
 * License:     CC-BY-SA 2.5
 */

add_filter( 'image_editor_save_pre', 'WPSE\JPEGQualityController', 20, 2 );
/**
 * @param string $image
 * @param int $post_id
 * @return string
 */
function JPEGQualityController( $image, $post_id )
{
    $config = apply_filters( 'wpse_jpeg_quality', array(
        # Valid: <, lt, <=, le, >, gt, >=, ge, ==, =, eq
        'limit'      => 'gt',
        # Valid: h, w
        'reference'  => 'w',
        'breakpoint' => 50,

        'low'        => 80,
        'high'       => 100,
    ) );
    include_once plugin_dir_path( __FILE__ ).'worker.php';
    new \WPSE\JPEGQualityWorker( $image, $config );

    return $image;
}

Asıl işçi JPEGQualityWorkersınıftır. Yukarıdaki ana eklenti dosyasıyla aynı dizinde bulunur ve adlandırılır worker.php(veya yukarıdaki denetleyiciyi değiştirirsiniz).

Görüntüyü ve ayarlarınızı alır ve ardından jpeg_qualityfiltreye geri aramalar ekler . Ne yapar

  • görüntü referansınızı alma (genişlik veya yükseklik)
  • Düşük ve yüksek kalite / sıkıştırma oranı arasında nerede geçiş yapılacağına karar veren kırılma noktanızın sorgulanması
  • orijinal görüntü boyutunu alma
  • hangi kalitenin geri döneceğine karar verme

Kırılma noktası ve sınır, yüksek ve düşük arasında karar veren şeydir ve yukarıda belirtildiği gibi, bunun daha fazla sevgiye ihtiyacı olabilir.

<?php

namespace WPSE;

/**
 * Class JPEGQualityWorker
 * @package WPSE
 */
class JPEGQualityWorker
{
    protected $config, $image;
    /**
     * @param string $image
     * @param array $config
     */
    public function __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
     */
    public function setQuality( $compression, $context )
    {
        if ( in_array( $context, array(
            'edit_image',
            'wp_crop_image',
        ) ) )
            return 100;

        $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
     */
    public function 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
     */
    protected function 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
     */
    protected function 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
     */
    protected function 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.php

        return ! $size
            ? new \WP_Error(
                'image-failure',
                sprintf( 'Resource failed in %s', get_class( $this ) )
            )
            : $size;
    }
}

Hala üzerinde çalışıyor? Ben endişeliyim kadarıyla bunu bir eklenti olarak görmek isterim.
Nils Riedemann

Üzgünüm, ama hayır. Bunu eklenti olarak görmek istiyorum, ama şu anda ihtiyacım yok ve zamanım yok, şimdiye kadar olmayacak. Belki bir şans verin, ne kadar ilerlediğinizi görün ve bir düzenleme veya ayrı bir cevap dosyalayın? :)
Kaiser

kaiser: Aşırı karmaşıklaştın sanırım. İmage_editor_save_pre dosyasına gönderilen $ görüntüsü, WP_Image_Editor sınıfının bir örneğidir. Boyutu almak ve kalitesini ve zaten içindeki her şeyi ayarlamak için fonksiyonları vardır. Tek yapmanız gereken onları aramak.
Otto
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.