You are here

MediaThumbnailSVG.php in Media Thumbnails SVG 8

File

src/Plugin/MediaThumbnail/MediaThumbnailSVG.php
View source
<?php

namespace Drupal\media_thumbnails_svg\Plugin\MediaThumbnail;

use Drupal\Core\File\FileSystemInterface;
use Drupal\media_thumbnails\Plugin\MediaThumbnailBase;
use SVG\SVG;

/**
 * Media thumbnail plugin for svg documents.
 *
 * @MediaThumbnail(
 *   id = "media_thumbnail_svg",
 *   label = @Translation("Media Thumbnail SVG"),
 *   mime = {
 *     "image/svg",
 *     "image/svg+xml",
 *   }
 * )
 */
class MediaThumbnailSVG extends MediaThumbnailBase {
  protected $width;
  protected $bg_color;

  /**
   * Creates a managed thumbnail file using the passed source file uri.
   *
   * {@inheritdoc}
   */
  public function createThumbnail($sourceUri) {

    // Not all rasterizers support stream wrappers, use absolute paths.
    $path = $this->fileSystem
      ->realpath($sourceUri);

    // Get width and background color, if any.
    $this->bg_color = $this->configuration['bgcolor_active'] ? $this->configuration['bgcolor_value'] : 'transparent';
    $this->width = $this->configuration['width'] ?? 500;

    // Create a thumbnail image blob using the best rasterizer available.
    switch (TRUE) {
      case strpos(shell_exec('gm'), 'GraphicsMagick') !== FALSE:
        $image = $this
          ->createThumbnailGM($path);
        break;
      case strpos(shell_exec('convert'), 'ImageMagick') !== FALSE:
        $image = $this
          ->createThumbnailIM($path);
        break;
      default:
        $image = $this
          ->createThumbnailGD($path);
    }

    // Return a new managed file object using the generated thumbnail.
    return $image ? file_save_data($image, $sourceUri . '.png', FileSystemInterface::EXISTS_REPLACE) : NULL;
  }
  protected function createThumbnailGM($path) {
    $source = escapeshellarg($path);
    $target = $source . '.png';
    shell_exec("gm convert -background '{$this->bg_color}' -size {$this->width} -quality 100 -strip {$source} {$target}");
    $data = file_get_contents($path . '.png');
    if (!$data) {
      $this->logger
        ->warning($this
        ->t('Could not create png from svg using GM.'));
    }
    return $data;
  }
  protected function createThumbnailIM($path) {
    $source = escapeshellarg($path);
    $target = $source . '.png';
    shell_exec("convert -background '{$this->bg_color}' -density {$this->width} -thumbnail {$this->width} -quality 100 -strip {$source} {$target}");
    $data = file_get_contents($path . '.png');
    if (!$data) {
      $this->logger
        ->warning($this
        ->t('Could not create png from svg using IM.'));
    }
    return $data;
  }
  protected function createThumbnailGD($path) {
    $image = SVG::fromFile($path);
    if (!$image) {
      $this->logger
        ->warning($this
        ->t('Media entity source file (svg) not found.'));
      return NULL;
    }

    // Create a raster image using the target width, keeping the aspect ratio.
    $width = $image
      ->getDocument()
      ->getWidth() ?: $image
      ->getDocument()
      ->getViewBox()[2];
    $height = $image
      ->getDocument()
      ->getHeight() ?: $image
      ->getDocument()
      ->getViewBox()[3];
    $ratio = $width && $height ? $height / $width : 1;
    $height = (int) ($this->width * $ratio);
    $raster_image = $image
      ->toRasterImage($this->width, $height, $this->bg_color);

    // Create a new image thumbnail blob.
    ob_start();
    if (!imagepng($raster_image, NULL, 9)) {
      $this->logger
        ->warning($this
        ->t('Could not create png from svg using GD.'));
      ob_end_clean();
      return NULL;
    }
    return ob_get_clean();
  }

}

Classes

Namesort descending Description
MediaThumbnailSVG Media thumbnail plugin for svg documents.