Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion config/default.php
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@
'enabled' => true, // adds `loading="lazy"` attribute (`true` by default)
],
'resize' => [
'enabled' => false, // enables image resizing by using the `width` extra attribute (`false` by default)
'enabled' => false, // enables image resizing by using the `width` or 'height' extra attribute (`false` by default)
],
'responsive' => [
'enabled' => false, // creates responsive images and add them to the `srcset` attribute (`false` by default)
Expand Down Expand Up @@ -266,6 +266,9 @@
'webp' => [
'enabled' => false, // creates a WebP version of images with `html` filter (`false` by default)
],
'thumbnails' => [
'dir' => 'thumbnails', // where thumbnails are stored (in the assets target directory)
],
],
],
'postprocess' => [
Expand Down
4 changes: 3 additions & 1 deletion docs/4-Configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -709,7 +709,7 @@ assets:
variables: [] # list of preset variables (empty by default)
minify:
enabled: true # enables asset minification (`true` by default)
target: assets # where remote and resized assets are saved
target: assets # where handled assets are stored
images:
optimize:
enabled: false # enables images optimization with JpegOptim, Optipng, Pngquant 2, SVGO 1, Gifsicle, cwebp (`false` by default)
Expand All @@ -721,6 +721,8 @@ assets:
default: '100vw' # `sizes` attribute (`100vw` by default)
webp:
enabled: false # creates a WebP version of images with `html` filter (`false` by default)
thumbnails:
dir: thumbnails # where thumbnails are stored (in the assets target directory)
```

:::
Expand Down
26 changes: 15 additions & 11 deletions src/Assets/Asset.php
Original file line number Diff line number Diff line change
Expand Up @@ -401,43 +401,47 @@ public function optimize(string $filepath): self
*
* @throws RuntimeException
*/
public function resize(int $width): self
public function resize(?int $width = null, ?int $height = null): self
{
if ($this->data['type'] != 'image') {
throw new RuntimeException(\sprintf('Not able to resize "%s": it\'s not an image', $this->data['path']));
if ($width === null && $height === null) {
return $this;
}

if ($width >= $this->getWidth()) {
if ($width >= $this->getWidth() && $height >= $this->getHeight()) {
return $this;
}

$assetResized = clone $this;
$assetResized->data['width'] = $width;

$cache = new Cache($this->builder, 'assets');
$cacheKey = $cache->createKeyFromAsset($assetResized, ["{$width}x"]);
$cacheKey = $cache->createKeyFromAsset($assetResized, ["{$width}x{$height}"]);
if (!$cache->has($cacheKey)) {
if ($assetResized->data['type'] !== 'image') {
throw new RuntimeException(\sprintf('Not able to resize "%s"', $assetResized->data['path']));
throw new RuntimeException(\sprintf('Not able to resize "%s": it\'s not an image', $assetResized->data['path']));
}
if (!extension_loaded('gd')) {
throw new RuntimeException('GD extension is required to use images resize.');
}

try {
$img = ImageManager::make($assetResized->data['content_source']);
$img->resize($width, null, function (\Intervention\Image\Constraint $constraint) {
$img->resize($width, $height, function (\Intervention\Image\Constraint $constraint) {
$constraint->aspectRatio();
$constraint->upsize();
});
} catch (\Exception $e) {
throw new RuntimeException(\sprintf('Not able to resize image "%s": %s', $assetResized->data['path'], $e->getMessage()));
}
$assetResized->data['path'] = '/'.Util::joinPath((string) $this->config->get('assets.target'), 'thumbnails', (string) $width, $assetResized->data['path']);
$assetResized->data['width'] = $assetResized->getWidth();
$assetResized->data['height'] = $assetResized->getHeight();
$assetResized->data['path'] = '/'.Util::joinPath(
(string) $this->config->get('assets.target'),
(string) $this->config->get('assets.images.thumbnails.dir'),
"{$width}x{$height}",
$assetResized->data['path']
);

try {
$assetResized->data['content'] = (string) $img->encode($assetResized->data['ext'], $this->config->get('assets.images.quality'));
$assetResized->data['height'] = $assetResized->getHeight();
} catch (\Exception $e) {
throw new RuntimeException(\sprintf('Not able to encode image "%s": %s', $assetResized->data['path'], $e->getMessage()));
}
Expand Down
24 changes: 16 additions & 8 deletions src/Converter/Parsedown.php
Original file line number Diff line number Diff line change
Expand Up @@ -104,20 +104,28 @@ protected function inlineImage($Excerpt)
// create asset
$asset = new Asset($this->builder, $image['element']['attributes']['src'], ['force_slash' => false]);
$image['element']['attributes']['src'] = $asset;
$width = $asset->getWidth();
$width = null;
$height = null;

/**
* Should be resized?
*/
$assetResized = null;
if (isset($image['element']['attributes']['width'])
&& (int) $image['element']['attributes']['width'] < $width
&& $this->builder->getConfig()->get('body.images.resize.enabled')
if ($this->builder->getConfig()->get('body.images.resize.enabled')
&& (
(isset($image['element']['attributes']['width']) && (int) $image['element']['attributes']['width'] < $asset->getWidth())
|| (isset($image['element']['attributes']['height']) && (int) $image['element']['attributes']['height'] < $asset->getHeight())
)
) {
$width = (int) $image['element']['attributes']['width'];
if (isset($image['element']['attributes']['width'])) {
$width = (int) $image['element']['attributes']['width'];
}
if (isset($image['element']['attributes']['height'])) {
$height = (int) $image['element']['attributes']['height'];
}

try {
$assetResized = $asset->resize($width);
$assetResized = $asset->resize($width, $height);
$image['element']['attributes']['src'] = $assetResized;
} catch (\Exception $e) {
$this->builder->getLogger()->debug($e->getMessage());
Expand All @@ -128,7 +136,7 @@ protected function inlineImage($Excerpt)

// set width
if (!isset($image['element']['attributes']['width']) && $asset['type'] == 'image') {
$image['element']['attributes']['width'] = $width;
$image['element']['attributes']['width'] = ($assetResized ?? $asset)->getWidth();
}
// set height
if (!isset($image['element']['attributes']['height']) && $asset['type'] == 'image') {
Expand All @@ -138,7 +146,7 @@ protected function inlineImage($Excerpt)
/**
* Should be responsive?
*/
if ($this->builder->getConfig()->get('body.images.responsive.enabled')) {
if ($this->builder->getConfig()->get('body.images.responsive.enabled') && false === false) {
if ($srcset = Image::buildSrcset(
$assetResized ?? $asset,
$this->builder->getConfig()->get('assets.images.responsive.widths') ?? [480, 640, 768, 1024, 1366, 1600, 1920]
Expand Down
4 changes: 2 additions & 2 deletions src/Renderer/Twig/Extension.php
Original file line number Diff line number Diff line change
Expand Up @@ -371,13 +371,13 @@ public function fingerprint($asset): Asset
*
* @return Asset
*/
public function resize($asset, int $size): Asset
public function resize($asset, ?int $width = null, ?int $height = null): Asset
{
if (!$asset instanceof Asset) {
$asset = new Asset($this->builder, $asset);
}

return $asset->resize($size);
return $asset->resize($width, $height);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion tests/fixtures/website/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@
'enabled' => true,
],
'remote' => [
'enabled' => false,
'enabled' => true,
],
'resize' => [
'enabled' => true,
Expand Down
12 changes: 10 additions & 2 deletions tests/fixtures/website/pages/Assets/images.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,23 @@ typora-root-url: ../../static

## Resize

### Image resized to 100px
### Image resized to 100px width

```markdown
![Alt text](/images/cecil-logo.png){width=100}
```

![Alt text](/images/cecil-logo.png){width=100}

### External image resized to 250px
### Image resized to 100px height

```markdown
![Alt text](/images/cecil-logo.png){height=150}
```

![Alt text](/images/cecil-logo.png){height=150}

### External image resized to 250px width

```markdown
![Jamstatic](https://jamstatic.fr/assets/images/twitter-card.png){width=250}
Expand Down