VariantRenderer
in package
The single place where raster bytes are expanded into variants (resize and watermark) and where the on-disk file layout is known (`<absBase><variant>/<name>.<extension>`).
Shared by RasterImageProcessor (upload bytes directly),
VideoProcessor (poster from the first frame) and
VectorImageProcessor (via copyToVariants(), without GD).
Do not reimplement it elsewhere: a second copy drifts (for example it ignores resizeFlags).
Table of Contents
Constants
- WATERMARK_PADDING : int = 10
Properties
- $watermarkPath : array<string|int, mixed>
Methods
- __construct() : mixed
- Path to the watermark taken directly from `%watermarkPath%`, not through `AssetVariantProvider`: the provider reads the plan from the DB through `AssetVariantManager`, into which the decorator injects `assets.formatRegistry`, hence the processors and this renderer. A renderer to provider dependency would close a cycle in the DI container.
- copyToVariants() : array<string, array{width: int, height: int}>
- Stores the same bytes in all variants without any transformation, for formats GD cannot handle (vector). The copy is required, not optional: `Asset::getFullPath()` builds the variant URL from the variant plan, which is always stored in the DB, so `thumb/<name>.svg` will be referenced in templates and the file must exist there.
- renderVariants() : array<string, array{width: int, height: int}>
- Renders every variant from the raster bytes and returns its real dimensions (for `Asset.meta`; the variant config may not match reality because of the resize modes).
-
toVariantMap()
: array<string, array{maxWidth?: int, maxHeight?: int, resizeFlags?: array
, useWatermark?: bool}> - Converts the variant plan stored in `asset.variants` (a list with `name` inside) to the map taken by {@see renderVariants()}. Used by the catch-up cron, which reads the plan from the entity, not from config.
- applyWatermark() : void
- Places the watermark in the bottom right corner; where it does not fit, it goes to (0, 0).
- loadWatermarkIfNeeded() : Image|null
- Loads the watermark if at least one variant wants it. Returns null when nobody uses it or when the file is missing; a missing watermark does not block the upload.
- needsDecoding() : bool
- Whether GD decodes at least one variant. Variants without resize and watermark are plain byte copies.
- resizes() : bool
- The variant changes the size: width > 0 (height 0 = no height limit). 0x0 = original, raw copy.
- resolveResizeMode() : int<0, 15>
- Converts `resizeFlags` from the variant config to the mode for {@see NetteImage::resize()}.
Constants
WATERMARK_PADDING
private
int
WATERMARK_PADDING
= 10
Properties
$watermarkPath read-only
private
array<string|int, mixed>
$watermarkPath
Methods
__construct()
Path to the watermark taken directly from `%watermarkPath%`, not through `AssetVariantProvider`: the provider reads the plan from the DB through `AssetVariantManager`, into which the decorator injects `assets.formatRegistry`, hence the processors and this renderer. A renderer to provider dependency would close a cycle in the DI container.
public
__construct(array{rel: string, abs: string} $watermarkPath) : mixed
Parameters
- $watermarkPath : array{rel: string, abs: string}
copyToVariants()
Stores the same bytes in all variants without any transformation, for formats GD cannot handle (vector). The copy is required, not optional: `Asset::getFullPath()` builds the variant URL from the variant plan, which is always stored in the DB, so `thumb/<name>.svg` will be referenced in templates and the file must exist there.
public
copyToVariants(string $rawData, string $fileName, string $extension, string $absBase, array<string, array{maxWidth: int, maxHeight: int, resizeFlags: array, useWatermark: bool}> $variantConfigs[, array{width: int, height: int}|null $dims = null ]) : array<string, array{width: int, height: int}>
Parameters
- $rawData : string
- $fileName : string
- $extension : string
- $absBase : string
-
$variantConfigs
: array<string, array{maxWidth: int, maxHeight: int, resizeFlags: array
, useWatermark: bool}> - $dims : array{width: int, height: int}|null = null
-
dimensions written to the meta of every variant
Return values
array<string, array{width: int, height: int}>renderVariants()
Renders every variant from the raster bytes and returns its real dimensions (for `Asset.meta`; the variant config may not match reality because of the resize modes).
public
renderVariants(string $rawData, string $fileName, string $extension, string $absBase, array<string, array{maxWidth?: int, maxHeight?: int, resizeFlags?: array, useWatermark?: bool}> $variantConfigs) : array<string, array{width: int, height: int}>
A variant without a transformation (maxWidth/maxHeight = 0 and no watermark) is written as
a raw copy, not through GD, which keeps the original quality and file profile.
Parameters
- $rawData : string
- $fileName : string
- $extension : string
- $absBase : string
-
$variantConfigs
: array<string, array{maxWidth?: int, maxHeight?: int, resizeFlags?: array
, useWatermark?: bool}>
Tags
Return values
array<string, array{width: int, height: int}>toVariantMap()
Converts the variant plan stored in `asset.variants` (a list with `name` inside) to the map taken by {@see renderVariants()}. Used by the catch-up cron, which reads the plan from the entity, not from config.
public
static toVariantMap(array<int, array{name?: string, maxWidth?: int, maxHeight?: int, resizeFlags?: array, useWatermark?: bool}> $variants) : array<string, array{maxWidth?: int, maxHeight?: int, resizeFlags?: array, useWatermark?: bool}>
Parameters
-
$variants
: array<int, array{name?: string, maxWidth?: int, maxHeight?: int, resizeFlags?: array
, useWatermark?: bool}>
Return values
array<string, array{maxWidth?: int, maxHeight?: int, resizeFlags?: arrayapplyWatermark()
Places the watermark in the bottom right corner; where it does not fit, it goes to (0, 0).
private
applyWatermark(Image $img, Image $watermark) : void
Parameters
- $img : Image
- $watermark : Image
loadWatermarkIfNeeded()
Loads the watermark if at least one variant wants it. Returns null when nobody uses it or when the file is missing; a missing watermark does not block the upload.
private
loadWatermarkIfNeeded(array<string, array{useWatermark?: bool}> $variantConfigs) : Image|null
Parameters
- $variantConfigs : array<string, array{useWatermark?: bool}>
Return values
Image|nullneedsDecoding()
Whether GD decodes at least one variant. Variants without resize and watermark are plain byte copies.
private
needsDecoding(array<string, array{maxWidth?: int, maxHeight?: int, useWatermark?: bool}> $variantConfigs, Image|null $watermark) : bool
Parameters
- $variantConfigs : array<string, array{maxWidth?: int, maxHeight?: int, useWatermark?: bool}>
- $watermark : Image|null
Return values
boolresizes()
The variant changes the size: width > 0 (height 0 = no height limit). 0x0 = original, raw copy.
private
static resizes(int $maxW, int $maxH) : bool
Parameters
- $maxW : int
- $maxH : int
Return values
boolresolveResizeMode()
Converts `resizeFlags` from the variant config to the mode for {@see NetteImage::resize()}.
private
resolveResizeMode(array<int|string, mixed> $flags) : int<0, 15>
Values are OR-ed (a bit mask of Nette flags: ShrinkOnly/Stretch/OrBigger/Cover).
Empty or 0 means ShrinkOnly (proportional, no enlarging), so types with resizeFlags: []
stay proportional. Cover alone resizes and center-crops to the exact WxH.
Parameters
- $flags : array<int|string, mixed>