You are here

class GDToolkitWebP in Picture 8

Defines the GD2 toolkit for image manipulation within Drupal.

Plugin annotation


@ImageToolkit(
  id = "gd_webp",
  title = @Translation("GD2 image manipulation toolkit with WebP support")
)

Hierarchy

Expanded class hierarchy of GDToolkitWebP

File

src/Plugin/ImageToolkit/GDToolkitWebP.php, line 22
Contains \Drupal\system\Plugin\ImageToolkit\GDToolkit.

Namespace

Drupal\picture\Plugin\ImageToolkit
View source
class GDToolkitWebP extends GDToolkit {
  const IMAGETYPE_WEBP = 'WEBP';

  /**
   * {@inheritdoc}
   */
  protected function load() {

    // Return immediately if the image file is not valid.
    if (!$this
      ->isValid()) {
      return FALSE;
    }
    switch ($this
      ->getType()) {
      case GDToolkitWebP::IMAGETYPE_WEBP:
        $function = 'imagecreatefromwebp';
        break;
      default:
        $function = 'imagecreatefrom' . image_type_to_extension($this
          ->getType(), FALSE);
    }
    if (function_exists($function) && ($resource = $function($this
      ->getImage()
      ->getSource()))) {
      $this
        ->setResource($resource);
      if (imageistruecolor($resource)) {
        return TRUE;
      }
      else {

        // Convert indexed images to true color, so that filters work
        // correctly and don't result in unnecessary dither.
        $new_image = $this
          ->createTmp($this
          ->getType(), imagesx($resource), imagesy($resource));
        if ($ret = (bool) $new_image) {
          imagecopy($new_image, $resource, 0, 0, 0, 0, imagesx($resource), imagesy($resource));
          imagedestroy($resource);
          $this
            ->setResource($new_image);
        }
        return $ret;
      }
    }
    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
  public function save($destination) {
    $scheme = file_uri_scheme($destination);

    // Work around lack of stream wrapper support in imagejpeg() and imagepng().
    if ($scheme && file_stream_wrapper_valid_scheme($scheme)) {

      // If destination is not local, save image to temporary local file.
      $local_wrappers = file_get_stream_wrappers(STREAM_WRAPPERS_LOCAL);
      if (!isset($local_wrappers[$scheme])) {
        $permanent_destination = $destination;
        $destination = drupal_tempnam('temporary://', 'gd_');
      }

      // Convert stream wrapper URI to normal path.
      $destination = drupal_realpath($destination);
    }
    switch ($this
      ->getType()) {
      case GDToolkitWebP::IMAGETYPE_WEBP:
        $function = 'imagewebp';
        break;
      default:
        $function = 'image' . image_type_to_extension($this
          ->getType(), FALSE);
        break;
    }
    if (!function_exists($function)) {
      return FALSE;
    }
    if ($this
      ->getType() == IMAGETYPE_JPEG) {
      $success = $function($this
        ->getResource(), $destination, $this->configFactory
        ->get('system.image.gd')
        ->get('jpeg_quality'));
    }
    else {

      // Always save PNG images with full transparency.
      if ($this
        ->getType() == IMAGETYPE_PNG) {
        imagealphablending($this
          ->getResource(), FALSE);
        imagesavealpha($this
          ->getResource(), TRUE);
      }
      $success = $function($this
        ->getResource(), $destination);
    }

    // Move temporary local file to remote destination.
    if (isset($permanent_destination) && $success) {
      return (bool) file_unmanaged_move($destination, $permanent_destination, FILE_EXISTS_REPLACE);
    }
    return $success;
  }

  /**
   * {@inheritdoc}
   */
  public function parseFile() {
    $data = @getimagesize($this
      ->getImage()
      ->getSource());
    if ($data && in_array($data[2], static::supportedTypes())) {
      $this
        ->setType($data[2]);
      $this->preLoadInfo = $data;
      return TRUE;
    }
    else {

      // Determine if this is a WebP image.
      $handle = fopen($this
        ->getImage()
        ->getSource(), 'rb');
      $header = fread($handle, 12);
      if (Unicode::substr($header, 0, 4) === 'RIFF' && Unicode::substr($header, -4) === 'WEBP') {
        switch (fread($handle, 4)) {
          case 'VP8 ':
            fseek($handle, 26);
            $dimensions = fread($handle, 4);
            $width = unpack('V', $dimensions);
            $this->preLoadInfo[0] = $width[1] & 0x3fff;
            $this->preLoadInfo[1] = $width[1] >> 16 & 0x3fff;
            break;
          case 'VP8L':
            fseek($handle, 21);
            $dimensions = fread($handle, 4);
            $width = unpack('V', $dimensions);
            $this->preLoadInfo[0] = ($width[1] & 0x3fff) + 1;
            $this->preLoadInfo[1] = ($width[1] >> 14 & 0x3fff) + 1;
            break;
        }
        $this
          ->setType(GDToolkitWebP::IMAGETYPE_WEBP);
        $this->preLoadInfo[2] = GDToolkitWebP::IMAGETYPE_WEBP;
        $this->preLoadInfo[3] = 'height="' . $this->preLoadInfo[1] . '" width="' . $this->preLoadInfo[1] . '"';
        $this->preLoadInfo['mime'] = 'image/webp';

        // The 'channels' and 'bits' elements are not required, so omit them.
        fclose($handle);
        return TRUE;
      }
      fclose($handle);
    }
    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
  public function getMimeType() {
    switch ($this
      ->getType()) {
      case GDToolkitWebP::IMAGETYPE_WEBP:
        return 'image/webp';
      default:
        return $this
          ->getType() ? image_type_to_mime_type($this
          ->getType()) : '';
    }
  }

  /**
   * {@inheritdoc}
   */
  public function getRequirements() {
    $requirements = array();
    $info = gd_info();
    $requirements['version'] = array(
      'title' => t('GD library'),
      'value' => $info['GD Version'],
    );

    // Check for filter and rotate support.
    if (!function_exists('imagefilter') || !function_exists('imagerotate')) {
      $requirements['version']['severity'] = REQUIREMENT_WARNING;
      $requirements['version']['description'] = t('The GD Library for PHP is enabled, but was compiled without support for functions used by the rotate and desaturate effects. It was probably compiled using the official GD libraries from http://www.libgd.org instead of the GD library bundled with PHP. You should recompile PHP --with-gd using the bundled GD library. See <a href="@url">the PHP manual</a>.', array(
        '@url' => 'http://www.php.net/manual/book.image.php',
      ));
    }
    elseif (version_compare(PHP_VERSION, '5.5.0') < 0) {
      $requirements['version']['severity'] = REQUIREMENT_ERROR;
      $requirements['version']['description'] = t('You need at least PHP version 5.5.0 to support WebP with the GD library. Your current PHP version is @version', array(
        '@version' => PHP_VERSION,
      ));
    }
    return $requirements;
  }

  /**
   * {@inheritdoc}
   */
  public static function isAvailable() {

    // GD2 support is available.
    return version_compare(PHP_VERSION, '5.5.0') > 0 && function_exists('imagegd2');
  }

  /**
   * {@inheritdoc}
   */
  public static function getSupportedExtensions() {
    $extensions = array();
    foreach (static::supportedTypes() as $image_type) {
      if ($image_type == GDToolkitWebP::IMAGETYPE_WEBP) {
        $extensions[] = 'webp';
      }
      else {
        $extensions[] = Unicode::strtolower(image_type_to_extension($image_type, FALSE));
      }
    }
    return $extensions;
  }

  /**
   * {@inheritdoc}
   */
  public function extensionToImageType($extension) {
    if ($extension === 'webp') {
      return GDToolkitWebP::IMAGETYPE_WEBP;
    }
    foreach ($this
      ->supportedTypes() as $type) {
      if (image_type_to_extension($type, FALSE) === $extension) {
        return $type;
      }
    }
    return IMAGETYPE_UNKNOWN;
  }

  /**
   * {@inheritdoc}
   */
  protected static function supportedTypes() {
    return array(
      IMAGETYPE_PNG,
      IMAGETYPE_JPEG,
      IMAGETYPE_GIF,
      GDToolkitWebP::IMAGETYPE_WEBP,
    );
  }

}

Members

Namesort descending Modifiers Type Description Overrides
DependencySerializationTrait::$_entityStorages protected property An array of entity type IDs keyed by the property name of their storages.
DependencySerializationTrait::$_serviceIds protected property An array of service IDs keyed by property name used for serialization.
DependencySerializationTrait::__sleep public function 1
DependencySerializationTrait::__wakeup public function 2
GDToolkit::$fileSystem protected property The file system.
GDToolkit::$preLoadInfo protected property Image information from a file, available prior to loading the GD resource.
GDToolkit::$resource protected property A GD image resource.
GDToolkit::$streamWrapperManager protected property The StreamWrapper manager.
GDToolkit::$type protected property Image type represented by a PHP IMAGETYPE_* constant (e.g. IMAGETYPE_JPEG).
GDToolkit::buildConfigurationForm public function Form constructor. Overrides PluginFormInterface::buildConfigurationForm
GDToolkit::create public static function Creates an instance of the plugin. Overrides ContainerFactoryPluginInterface::create
GDToolkit::getHeight public function Returns the height of the image. Overrides ImageToolkitInterface::getHeight
GDToolkit::getResource public function Retrieves the GD image resource.
GDToolkit::getTransparentColor public function Gets the color set for transparency in GIF images.
GDToolkit::getType public function Gets the PHP type of the image.
GDToolkit::getWidth public function Returns the width of the image. Overrides ImageToolkitInterface::getWidth
GDToolkit::isValid public function Checks if the image is valid. Overrides ImageToolkitInterface::isValid
GDToolkit::setResource public function Sets the GD image resource.
GDToolkit::setType public function Sets the PHP type of the image.
GDToolkit::submitConfigurationForm public function Form submission handler. Overrides PluginFormInterface::submitConfigurationForm
GDToolkit::__construct public function Constructs a GDToolkit object. Overrides ImageToolkitBase::__construct
GDToolkit::__destruct public function Destructs a GDToolkit object.
GDToolkitWebP::extensionToImageType public function Returns the IMAGETYPE_xxx constant for the given extension. Overrides GDToolkit::extensionToImageType
GDToolkitWebP::getMimeType public function Returns the MIME type of the image file. Overrides GDToolkit::getMimeType
GDToolkitWebP::getRequirements public function Gets toolkit requirements in a format suitable for hook_requirements(). Overrides GDToolkit::getRequirements
GDToolkitWebP::getSupportedExtensions public static function Returns a list of image file extensions supported by the toolkit. Overrides GDToolkit::getSupportedExtensions
GDToolkitWebP::IMAGETYPE_WEBP constant
GDToolkitWebP::isAvailable public static function Verifies that the Image Toolkit is set up correctly. Overrides GDToolkit::isAvailable
GDToolkitWebP::load protected function Loads a GD resource from a file. Overrides GDToolkit::load
GDToolkitWebP::parseFile public function Determines if a file contains a valid image. Overrides GDToolkit::parseFile
GDToolkitWebP::save public function Writes an image resource to a destination file. Overrides GDToolkit::save
GDToolkitWebP::supportedTypes protected static function Returns a list of image types supported by the toolkit. Overrides GDToolkit::supportedTypes
ImageToolkitBase::$configFactory protected property The config factory.
ImageToolkitBase::$logger protected property A logger instance.
ImageToolkitBase::$operationManager protected property The image toolkit operation manager.
ImageToolkitBase::$source protected property Path of the image file.
ImageToolkitBase::apply public function Applies a toolkit operation to an image. Overrides ImageToolkitInterface::apply 1
ImageToolkitBase::getSource public function Gets the source path of the image file. Overrides ImageToolkitInterface::getSource
ImageToolkitBase::getToolkitOperation protected function Gets a toolkit operation plugin instance.
ImageToolkitBase::setSource public function Sets the source path of the image file. Overrides ImageToolkitInterface::setSource
ImageToolkitBase::validateConfigurationForm public function Form validation handler. Overrides PluginFormInterface::validateConfigurationForm 1
MessengerTrait::$messenger protected property The messenger. 29
MessengerTrait::messenger public function Gets the messenger. 29
MessengerTrait::setMessenger public function Sets the messenger.
PluginBase::$configuration protected property Configuration information passed into the plugin. 1
PluginBase::$pluginDefinition protected property The plugin implementation definition. 1
PluginBase::$pluginId protected property The plugin_id.
PluginBase::DERIVATIVE_SEPARATOR constant A string which is used to separate base plugin IDs from the derivative ID.
PluginBase::getBaseId public function Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface::getBaseId
PluginBase::getDerivativeId public function Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface::getDerivativeId
PluginBase::getPluginDefinition public function Gets the definition of the plugin implementation. Overrides PluginInspectionInterface::getPluginDefinition 3
PluginBase::getPluginId public function Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface::getPluginId
PluginBase::isConfigurable public function Determines if the plugin is configurable.
StringTranslationTrait::$stringTranslation protected property The string translation service. 1
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language.