Skip to content

Commit

Permalink
filters in neon (#4)
Browse files Browse the repository at this point in the history
* config filters

* readme

* rename NetteConfigOperationInterface::apply to operate

* docs

* add gumlet config filters
  • Loading branch information
MartkCz committed Jun 1, 2021
1 parent fc15b8c commit 841aca8
Show file tree
Hide file tree
Showing 32 changed files with 1,010 additions and 13 deletions.
1 change: 1 addition & 0 deletions .docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
- Filters (image manipulation)
- [Imagine filters (uses imagine/imagine)](imagine.md)
- [Nette image filters (uses nette/utils)](nette-image-filters.md)
- [Nette filters via neon config](nette-filters-config.md)
- [Filters with dynamic options](filters-options.md)
- Examples
- [Gumlet + Google Storage](examples/gumlet-googleStorage.md)
Expand Down
Binary file added .docs/img/tracy-filters.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
115 changes: 115 additions & 0 deletions .docs/nette-filters-config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# Nette filters via neon config

For basic usage you can use simpler way than defining filters in classes. We use only neon config.


## Registration

```yaml
extensions:
imagist.filters: Contributte\Imagist\Bridge\Nette\DI\ImageStorageConfigFiltersExtension
```

That's all. We can use [nette/utils](nette-image-filters.md) or [imagine/imagine](imagine.md) for image operations.

Built-in operations are

**nette/utils**

```php
/**
* @param $flag one of fit, fill, exact, shrink_only, stretch
*/
resize(int|string|null $width, int|string|null $height = null, string $flag = 'fit')

crop(int|string $left, int|string $top, int|string $width, int|string $height);

/**
* @param $mode one of vertical, horizontal, both
*/
flip(string $mode);

sharpen();
```

**imagine/imagine**

```php
resize(int $width, int $height);
```

## Usage

```yaml
imagist.filters:
siteS: resize(200, 200, fill) ## Single operation
siteXS: ## Multiple operations, first resize, second flip, ...
- resize(100, 100, fill)
- flip(vertical)
- crop(20, 20, 20, 20)
- sharpen()
```

Traditional usage in latte:

```html
<img n:img="$image|filter:siteS">
```

## Custom operation in config

**nette/utils**
```php
use Contributte\Imagist\Bridge\Nette\Filter\Config\NetteConfigOperationInterface;

final class SharpenConfigOperation implements NetteConfigOperationInterface
{

public function getName(): string
{
return 'sharpen2';
}

/**
* @param mixed[] $arguments
*/
public function operate(Image $image, FilterInterface $filter, NetteImageOptions $options, array $arguments): void
{
$image->sharpen();
}

}
```

**imagine/imagine**

```php

use Contributte\Imagist\Bridge\Imagine\Config\ImagineConfigOperationInterface;

final class BlurConfigOperation implements ImagineConfigOperationInterface
{

public function getName(): string
{
return 'blur';
}

/**
* @param mixed[] $arguments
*/
public function operate(ImageInterface $image, FilterInterface $filter, NetteImageOptions $options, array $arguments): void
{
[$amount] = $arguments;

$image->effects()->blur($amount);
}

}
```

Register as service

## Tracy

![tracy](https://raw.githubusercontent.com/contributte/imagist/master/.docs/img/tracy-filters.png)
4 changes: 2 additions & 2 deletions .docs/nette-image-filters.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ For image manipulating nette image extension uses operations. Let's go define on

```php

use Contributte\Imagist\Bridge\NetteImage\NetteImageOptions;
use Contributte\Imagist\Bridge\NetteImage\NetteOperationInterface;
use Contributte\Imagist\Bridge\Nette\Filter\NetteImageOptions;
use Contributte\Imagist\Bridge\Nette\Filter\NetteOperationInterface;
use Contributte\Imagist\Filter\FilterInterface;
use Contributte\Imagist\Scope\Scope;
use Nette\Utils\Image;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php declare(strict_types = 1);

namespace Contributte\Imagist\Bridge\Gumlet\Normalizer\Config;

use Contributte\Imagist\Bridge\Gumlet\GumletBuilder;
use Contributte\Imagist\Entity\ImageInterface;
use Contributte\Imagist\Filter\FilterInterface;

interface GumletConfigNormalizerInterface
{

public function getName(): string;

/**
* @param mixed[] $options
* @param mixed[] $arguments
*/
public function normalize(
GumletBuilder $builder,
FilterInterface $filter,
ImageInterface $image,
array $options,
array $arguments
): void;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php declare(strict_types = 1);

namespace Contributte\Imagist\Bridge\Gumlet\Normalizer\Config;

use Contributte\Imagist\Bridge\Gumlet\GumletBuilder;
use Contributte\Imagist\Config\ConfigFilterStack;
use Contributte\Imagist\Entity\ImageInterface;
use Contributte\Imagist\Exceptions\UnexpectedErrorException;
use Contributte\Imagist\Filter\FilterInterface;
use Contributte\Imagist\Filter\FilterNormalizerInterface;
use InvalidArgumentException;

final class GumletConfigNormalizerRegistry implements FilterNormalizerInterface
{

/** @var ConfigFilterStack[] */
protected array $configFilterStacks = [];

/** @var GumletConfigNormalizerInterface[] */
protected array $normalizers = [];

public function addConfigFilterStack(ConfigFilterStack $configFilterStack): void
{
$this->configFilterStacks[$configFilterStack->getName()] = $configFilterStack;
}

public function addNormalizer(GumletConfigNormalizerInterface $normalizer): void
{
$this->normalizers[$normalizer->getName()] = $normalizer;
}

public function supports(FilterInterface $filter, ImageInterface $image, array $options): bool
{
return isset($options['gumlet']) && isset($this->configFilterStacks[$filter->getName()]);
}

public function normalize(FilterInterface $filter, ImageInterface $image, array $options): array
{
if (!isset($this->configFilterStacks[$filter->getName()])) {
throw new UnexpectedErrorException();
}

$builder = GumletBuilder::create();
foreach ($this->configFilterStacks[$filter->getName()]->getConfigFilters() as $configFilter) {
if (!isset($this->normalizers[$configFilter->getName()])) {
throw new InvalidArgumentException(sprintf('Config normalizer %s not exists.', $configFilter->getName()));
}

$normalizer = $this->normalizers[$configFilter->getName()];
$normalizer->normalize($builder, $filter, $image, $options, $configFilter->getArguments());
}

return $builder->build();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php declare(strict_types = 1);

namespace Contributte\Imagist\Bridge\Gumlet\Normalizer\Config\Normalizer;

use Contributte\Imagist\Bridge\Gumlet\GumletBuilder;
use Contributte\Imagist\Bridge\Gumlet\Normalizer\Config\GumletConfigNormalizerInterface;
use Contributte\Imagist\Entity\ImageInterface;
use Contributte\Imagist\Filter\FilterInterface;

final class CropConfigNormalizer implements GumletConfigNormalizerInterface
{

public function getName(): string
{
return 'crop';
}

public function normalize(
GumletBuilder $builder,
FilterInterface $filter,
ImageInterface $image,
array $options,
array $arguments
): void
{
[$mode] = $arguments;

$builder->crop($mode);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php declare(strict_types = 1);

namespace Contributte\Imagist\Bridge\Gumlet\Normalizer\Config\Normalizer;

use Contributte\Imagist\Bridge\Gumlet\GumletBuilder;
use Contributte\Imagist\Bridge\Gumlet\Normalizer\Config\GumletConfigNormalizerInterface;
use Contributte\Imagist\Entity\ImageInterface;
use Contributte\Imagist\Filter\FilterInterface;

final class ResizeConfigNormalizer implements GumletConfigNormalizerInterface
{

public function getName(): string
{
return 'resize';
}

public function normalize(
GumletBuilder $builder,
FilterInterface $filter,
ImageInterface $image,
array $options,
array $arguments
): void
{
[$width, $height, $mode] = array_replace([
null,
null,
null,
], $arguments);

$builder->resize($width, $height, $mode);
}

}
54 changes: 54 additions & 0 deletions src/Bridge/Imagine/Config/ImagineConfigFilterRegistry.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php declare(strict_types = 1);

namespace Contributte\Imagist\Bridge\Imagine\Config;

use Contributte\Imagist\Bridge\Imagine\OperationInterface;
use Contributte\Imagist\Config\ConfigFilterStack;
use Contributte\Imagist\Exceptions\UnexpectedErrorException;
use Contributte\Imagist\Filter\FilterInterface;
use Contributte\Imagist\Scope\Scope;
use Imagine\Image\ImageInterface;
use InvalidArgumentException;

final class ImagineConfigFilterRegistry implements OperationInterface
{

/** @var ImagineConfigOperationInterface[] */
protected array $operations = [];

/** @var ConfigFilterStack[] */
protected array $configFilterStacks = [];

public function addConfigFilterStack(ConfigFilterStack $configFilterStack): void
{
$this->configFilterStacks[$configFilterStack->getName()] = $configFilterStack;
}

public function addOperation(ImagineConfigOperationInterface $operation): void
{
$this->operations[$operation->getName()] = $operation;
}

public function supports(FilterInterface $filter, Scope $scope): bool
{
return isset($this->configFilterStacks[$filter->getName()]);
}

public function operate(ImageInterface $image, FilterInterface $filter): void
{
if (!isset($this->configFilterStacks[$filter->getName()])) {
throw new UnexpectedErrorException();
}

foreach ($this->configFilterStacks[$filter->getName()]->getConfigFilters() as $configFilter) {
if (!isset($this->operations[$configFilter->getName()])) {
throw new InvalidArgumentException(sprintf('Config operation %s not exists.', $configFilter->getName()));
}

$operation = $this->operations[$configFilter->getName()];

$operation->operate($image, $filter, $configFilter->getArguments());
}
}

}
18 changes: 18 additions & 0 deletions src/Bridge/Imagine/Config/ImagineConfigOperationInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php declare(strict_types = 1);

namespace Contributte\Imagist\Bridge\Imagine\Config;

use Contributte\Imagist\Filter\FilterInterface;
use Imagine\Image\ImageInterface;

interface ImagineConfigOperationInterface
{

public function getName(): string;

/**
* @param mixed[] $arguments
*/
public function operate(ImageInterface $image, FilterInterface $filter, array $arguments): void;

}
31 changes: 31 additions & 0 deletions src/Bridge/Imagine/Config/Operation/ResizeConfigOperation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php declare(strict_types = 1);

namespace Contributte\Imagist\Bridge\Imagine\Config\Operation;

use Contributte\Imagist\Bridge\Imagine\Config\ImagineConfigOperationInterface;
use Contributte\Imagist\Filter\FilterInterface;
use Imagine\Image\Box;
use Imagine\Image\ImageInterface;
use InvalidArgumentException;

final class ResizeConfigOperation implements ImagineConfigOperationInterface
{

public function getName(): string
{
return 'resize';
}

/**
* @param mixed[] $arguments
*/
public function operate(ImageInterface $image, FilterInterface $filter, array $arguments): void
{
if (count($arguments) !== 2) {
throw new InvalidArgumentException('Config filter resize must have two arguments.');
}

$image->resize(new Box(...$arguments));
}

}
Loading

0 comments on commit 841aca8

Please sign in to comment.