Skip to content
Snippets Groups Projects
Commit ad5e8109 authored by Erik Seifert's avatar Erik Seifert
Browse files

Fix: add new render element and correct generate image size command

parent 0351f2a9
No related branches found
No related tags found
No related merge requests found
...@@ -70,14 +70,28 @@ class GenerateImageSizeCommand extends DrushCommands { ...@@ -70,14 +70,28 @@ class GenerateImageSizeCommand extends DrushCommands {
* @option ratio * @option ratio
* Add a ratio. * Add a ratio.
* @usage image-sizes:generate 4x3 50 1600 50 --ratio=4x3 * @usage image-sizes:generate 4x3 50 1600 50 --ratio=4x3
* @usage image-sizes:generate 4x3 50 1600 50 --ratio=4x3 --generate-thumbnail
*/ */
public function generate($name, $min, $max, $steps, $options = ['ratio' => NULL]) { public function generate($name, $min, $max, $steps, $options =
[
'ratio' => NULL,
'use-focal-point' => FALSE,
'generate-thumbnail' => NULL
]) {
if ($options['use-focal-point'] && !$this->moduleHandler->moduleExists('focal_point')) {
$this->io()->error('focal_point module is missing.');
return;
}
if ($options['generate-thumbnail'] && !$this->moduleHandler->moduleExists('image_effects')) {
$this->io()->error('image_effects module is missing.');
return;
}
$this->options = [ $this->options = [
'name' => $name, 'name' => $name,
'min' => $min, 'min' => $min,
'max' => $max, 'max' => $max,
'steps' => $steps, 'steps' => $steps,
'options' => $options, 'options' => $options,
]; ];
$this->execute($this->output()); $this->execute($this->output());
} }
...@@ -91,8 +105,10 @@ class GenerateImageSizeCommand extends DrushCommands { ...@@ -91,8 +105,10 @@ class GenerateImageSizeCommand extends DrushCommands {
$min = $this->options['min']; $min = $this->options['min'];
$max = $this->options['max']; $max = $this->options['max'];
$steps = $this->options['steps']; $steps = $this->options['steps'];
$useFocalPoint = $this->options['options']['use-focal-point'];
$ratios = ['x' => 0, 'y' => 0]; $ratios = ['x' => 0, 'y' => 0];
$preloadStyle = FALSE; $preloadStyle = $this->options['options']['generate-thumbnail'];
$smallesStyle = FALSE;
$ratios = FALSE; $ratios = FALSE;
$style = ImageStyle::load($name); $style = ImageStyle::load($name);
...@@ -117,22 +133,22 @@ class GenerateImageSizeCommand extends DrushCommands { ...@@ -117,22 +133,22 @@ class GenerateImageSizeCommand extends DrushCommands {
'id' => self::machineName($name), 'id' => self::machineName($name),
]); ]);
for ($i = $min; $i < $max; $i = $i + $steps ) { for ($i = $min; $i <= $max; $i = $i + $steps ) {
$style_name = $name . '_' . $i; $style_name = $name . '_' . $i;
$x = $i; $x = $i;
$style = ImageStyle::create([ $style = ImageStyle::create([
'name' => $style_name, 'name' => $style_name,
'label' => '${name} ${x}' 'label' => "$name $x"
]); ]);
$configuration = array( $configuration = [
'uuid' => NULL, 'uuid' => NULL,
'id' => 'image_scale', 'id' => ($useFocalPoint) ? 'focal_point_scale_and_crop' : 'image_scale_and_crop',
'weight' => 0, 'weight' => 0,
'data' => array( 'data' => [
'width' => $x, 'width' => $x,
), ],
); ];
if ($ratios !== FALSE) { if ($ratios !== FALSE) {
$m = floor($i / $ratios['x']); $m = floor($i / $ratios['x']);
$x = $ratios['x'] * $m; $x = $ratios['x'] * $m;
...@@ -143,7 +159,7 @@ class GenerateImageSizeCommand extends DrushCommands { ...@@ -143,7 +159,7 @@ class GenerateImageSizeCommand extends DrushCommands {
); );
$configuration = array( $configuration = array(
'uuid' => NULL, 'uuid' => NULL,
'id' => ($this->useFocalPoint) ? 'focal_point_scale_and_crop' : 'image_scale_and_crop', 'id' => ($useFocalPoint) ? 'focal_point_scale_and_crop' : 'image_scale_and_crop',
'weight' => 0, 'weight' => 0,
'data' => array( 'data' => array(
'width' => $x, 'width' => $x,
...@@ -157,10 +173,54 @@ class GenerateImageSizeCommand extends DrushCommands { ...@@ -157,10 +173,54 @@ class GenerateImageSizeCommand extends DrushCommands {
$style->save(); $style->save();
$output->writeln("Generate Style ${style_name}"); $output->writeln("Generate Style ${style_name}");
$preset->addStyle($style->id()); $preset->addStyle($style->id());
if ($preloadStyle == FALSE) { if ($smallesStyle == FALSE) {
$preset->setPreloadStyle($style->id()); $preset->setPreloadStyle($style->id());
$preloadStyle = TRUE; $smallesStyle = TRUE;
}
}
if ($preloadStyle) {
$x = 15;
$style = ImageStyle::create([
'name' => $name . '_preload',
'label' => "$name Preload"
]);
if ($ratios !== FALSE) {
$m = floor($x / $ratios['x']);
$x = $ratios['x'] * $m;
$y = $ratios['y'] * $m;
$configuration = array(
'uuid' => NULL,
'id' => ($useFocalPoint) ? 'focal_point_scale_and_crop' : 'image_scale_and_crop',
'weight' => 0,
'data' => array(
'width' => $x,
'height' => $y,
),
);
} else {
$configuration = [
'uuid' => NULL,
'id' => ($useFocalPoint) ? 'focal_point_scale_and_crop' : 'image_scale_and_crop',
'weight' => 0,
'data' => [
'width' => $x,
],
];
} }
$effect = \Drupal::service('plugin.manager.image.effect')->createInstance($configuration['id'], $configuration);
$style->addImageEffect($effect->getConfiguration());
$effect = \Drupal::service('plugin.manager.image.effect')->createInstance('image_effects_gaussian_blur', [
'uuid' => NULL,
'id' => 'image_effects_gaussian_blur',
'weight' => 10,
'date' => [
'radius' => 5,
'sigma' => 2,
]
]);
$style->addImageEffect($effect->getConfiguration());
$style->save();
$preset->setPreloadStyle($style->id());
} }
$preset->setFallbackStyle($style->id()); $preset->setFallbackStyle($style->id());
$preset->save(); $preset->save();
...@@ -173,4 +233,4 @@ class GenerateImageSizeCommand extends DrushCommands { ...@@ -173,4 +233,4 @@ class GenerateImageSizeCommand extends DrushCommands {
return preg_replace('/_+/', '_', $new_value); return preg_replace('/_+/', '_', $new_value);
} }
} }
\ No newline at end of file
<?php
namespace Drupal\image_sizes\Element;
use Drupal\image\Entity\ImageStyle;
use Drupal\Component\Serialization\Json;
use Drupal\Core\Image\Image;
use Drupal\Core\Render\Element\RenderElement;
use Drupal\Core\Template\Attribute;
use Drupal\file\Entity\File;
use Drupal\file\FileInterface;
use Drupal\image\Plugin\Field\FieldType\ImageItem;
use Drupal\image_sizes\Entity\ImageSizesPresetEntity;
/**
* Provides a image sizes render element.
*
* @see \Drupal\Core\Render\Element\Textarea
*
* @RenderElement("image_sizes")
*/
class ImageSizes extends RenderElement {
/**
* {@inheritdoc}
*/
public function getInfo() {
$class = get_class($this);
return [
'#pre_render' => [
[
$class,
'prerenderImageSize',
],
],
'#attributes' => [],
'#style' => NULL,
'#alt' => NULL,
'#title' => NULL,
'#inline' => NULL,
'#entity' => NULL,
];
}
/**
* {@inheritDoc}
*/
public static function prerenderImageSize($element) {
$style = ImageSizesPresetEntity::load($element['#style']);
if (!$style) {
$element['#markup'] = 'Image style do not exists';
return $element;
}
if (!isset($element['#entity'])) {
$element['#markup'] = 'No image provided';
}
$uri = static::getFileUri($element['#entity']);
$styles = static::getStyles($uri, $style);
$preloadStyle = ImageStyle::load($style->getPreloadStyle());
$attributes = [
'data-src' => Json::encode($styles),
'class' => [
'image-sizes',
'pre-load',
],
'data-src-fallback' => static::getFallBackStyle($uri, $style),
];
if (isset($element['#alt'])) {
$attributes['alt'] = $element['#alt'];
}
if (isset($element['#title'])) {
$attributes['title'] = $element['#title'];
}
if ($element['#inline'] === TRUE && $preloadStyle) {
$attrs = static::getPreloadAsBase64($preloadStyle, $element['#entity']);
$attributes = array_merge($attributes, $attrs);
$attributes = new Attribute($attributes);
return [
'#type' => 'html_tag',
'#tag' => 'img',
'#attributes' => $attributes,
'#attached' => [
'library' => ['image_sizes/core'],
],
];
}
return [
'#theme' => 'image_style',
'#style_name' => $style->getPreloadStyle(),
'#uri' => $uri,
'#attributes' => $attributes,
'#attached' => [
'library' => ['image_sizes/core'],
],
];
}
/**
* Get all styles for a preset.
*
* @param string $uri
* File uri.
* @param \Drupal\image_sizes\Entity\ImageSizesPresetEntity $preset
* ImageSizesPreset entity.
*
* @return array
* Array of styles.
*/
protected static function getStyles($uri, ImageSizesPresetEntity $preset): array {
$image_styles = ImageStyle::loadMultiple($preset->getStyles());
$styles = [];
foreach ($image_styles as $style) {
$effects = $style->getEffects();
foreach ($effects as $effect) {
if (is_a($effect, 'Drupal\image\Plugin\ImageEffect\ResizeImageEffect')) {
$width = $effect->getConfiguration()['data']['width'];
if ($width !== NULL && $width > 0) {
$styles[$width] = $style->buildUrl($uri);
}
}
}
}
ksort($styles);
return $styles;
}
/**
* Get image as base 64.
*
* @param ImageStyle $imageStyle
* @return void
*/
protected static function getPreloadAsBase64(ImageStyle $image_style, FileInterface $image) {
$image_uri = $image->getFileUri();
$image_type = $image->getMimeType();
$derivative_uri = $image_style->buildUri($image_uri);
if (!file_exists($derivative_uri)) {
$image_style->createDerivative($image_uri, $derivative_uri);
}
$absolute_path = \Drupal::service('file_system')->realpath($derivative_uri);
$image_file = file_get_contents($absolute_path);
$base_64_image = base64_encode($image_file);
$imageFactory = \Drupal::service('image.factory');
$attributes = [];
$image_media = $imageFactory->get($absolute_path);
if ($image_media->isValid()) {
$attributes['width'] = $image_media->getWidth();
$attributes['height'] = $image_media->getHeight();
}
$attributes['src'] = "data:$image_type;base64,$base_64_image";
return $attributes;
}
/**
* Get fallback style.
*
* @param string $uri
* File uri.
* @param \Drupal\image_sizes\Entity\ImageSizesPresetEntity $preset
* ImageSizesPreset entity.
*
* @return string
* Get url for fallback style.
*/
protected static function getFallBackStyle($uri, ImageSizesPresetEntity $preset) {
if ($preset->getFallbackStyle() == 'original') {
return file_create_url($uri);
}
$style = ImageStyle::load($preset->getFallbackStyle());
if (!$style) {
return file_create_url($uri);
}
return $style->buildUrl($uri);
}
/**
* Get file uri.
*
* @param mixed $item
* File item.
*
* @return string
* File uri.
*/
public static function getFileUri($item) {
if ($item instanceOf File) {
return $item->getFileUri();
}
if ($item instanceOf ImageItem) {
if ($item->isEmpty()) {
return FALSE;
};
return $item->entity->getFileUri();
}
$field = $item->getSource()
->getSourceFieldDefinition($item->bundle->entity);
if ($item->get($field->getName())->isEmpty()) {
return FALSE;
}
return $item->get($field->getName())->first()->entity->getFileUri();
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment