Use webp in several places to save significantly on file size.

This commit is contained in:
Buster Neece 2022-11-22 02:02:19 -06:00
parent f7d2d01c73
commit 7bb7e28fa4
No known key found for this signature in database
GPG Key ID: F1D2E64A0005E80E
18 changed files with 133 additions and 90 deletions

View File

@ -1,4 +1,4 @@
// Default background of public pages
$public-page-bg: if($theme == 'light', '../img/hexbg.png', '../img/hexbg_dark.png');
$public-page-bg: if($theme == 'light', '../img/hexbg.webp', '../img/hexbg_dark.webp');
$scrollbar-color: if($theme == 'light', $material-color-grey-400, $material-color-grey-800);

View File

@ -1,5 +1,5 @@
header.navbar {
background-image: url('../img/header_bg.png'), linear-gradient(90deg, #0a6fc2 0%, #2196f3 100%);
background-image: url('../img/header_bg.webp'), linear-gradient(90deg, #0a6fc2 0%, #2196f3 100%);
background-position: top left, center;
background-repeat: no-repeat;
background-size: 500px 100px, cover;

View File

@ -10,6 +10,11 @@ use Psr\Http\Message\UriInterface;
abstract class AbstractCustomAsset implements CustomAssetInterface
{
public function __construct(
protected readonly Environment $environment
) {
}
abstract protected function getPattern(): string;
abstract protected function getDefaultUrl(): string;
@ -17,7 +22,7 @@ abstract class AbstractCustomAsset implements CustomAssetInterface
public function getPath(): string
{
$pattern = sprintf($this->getPattern(), '');
return Environment::getInstance()->getUploadsDirectory() . '/' . $pattern;
return $this->environment->getUploadsDirectory() . '/' . $pattern;
}
public function getUrl(): string
@ -27,7 +32,7 @@ abstract class AbstractCustomAsset implements CustomAssetInterface
$pattern = $this->getPattern();
$mtime = filemtime($path);
return Environment::getInstance()->getAssetUrl() . self::UPLOADS_URL_PREFIX . '/' . sprintf(
return $this->environment->getAssetUrl() . self::UPLOADS_URL_PREFIX . '/' . sprintf(
$pattern,
'.' . $mtime
);

View File

@ -0,0 +1,59 @@
<?php
declare(strict_types=1);
namespace App\Assets;
abstract class AbstractMultiPatternCustomAsset extends AbstractCustomAsset
{
abstract protected function getPatterns(): array;
protected function getPattern(): string
{
return $this->getPatterns()['default'];
}
protected function getPathForPattern(string $pattern): string
{
$pattern = sprintf($pattern, '');
return $this->environment->getUploadsDirectory() . '/' . $pattern;
}
public function getPath(): string
{
$patterns = $this->getPatterns();
foreach ($patterns as $pattern) {
$path = $this->getPathForPattern($pattern);
if (is_file($path)) {
return $path;
}
}
return $this->getPathForPattern($patterns['default']);
}
public function delete(): void
{
foreach ($this->getPatterns() as $pattern) {
@unlink($this->getPathForPattern($pattern));
}
}
public function getUrl(): string
{
foreach ($this->getPatterns() as $pattern) {
$path = $this->getPathForPattern($pattern);
if (is_file($path)) {
$mtime = filemtime($path);
return $this->environment->getAssetUrl() . self::UPLOADS_URL_PREFIX . '/' . sprintf(
$pattern,
'.' . $mtime
);
}
}
return $this->getDefaultUrl();
}
}

View File

@ -4,20 +4,22 @@ declare(strict_types=1);
namespace App\Assets;
use App\Environment;
use Intervention\Image\Constraint;
use Intervention\Image\Image;
final class AlbumArtCustomAsset extends AbstractCustomAsset
final class AlbumArtCustomAsset extends AbstractMultiPatternCustomAsset
{
protected function getPattern(): string
protected function getPatterns(): array
{
return 'album_art%s.jpg';
return [
'default' => 'album_art%s.webp',
'image/jpeg' => 'album_art%s.jpg',
];
}
protected function getDefaultUrl(): string
{
return Environment::getInstance()->getAssetUrl() . '/img/generic_song.jpg';
return $this->environment->getAssetUrl() . '/img/generic_song.webp';
}
public function upload(Image $image): void
@ -26,6 +28,14 @@ final class AlbumArtCustomAsset extends AbstractCustomAsset
$newImage->resize(1500, 1500, function (Constraint $constraint) {
$constraint->upsize();
});
$newImage->save($this->getPath());
$this->delete();
$pattern = $this->getPattern();
$mimeType = $newImage->mime();
$quality = ('image/png' === $mimeType) ? 100 : 90;
$newImage->save($this->getPathForPattern($pattern), $quality);
}
}

View File

@ -4,18 +4,20 @@ declare(strict_types=1);
namespace App\Assets;
use App\Environment;
enum AssetTypes: string
{
case AlbumArt = 'album_art';
case Background = 'background';
case BrowserIcon = 'browser_icon';
public function createObject(): CustomAssetInterface
public function createObject(Environment $environment): CustomAssetInterface
{
return match ($this) {
self::AlbumArt => new AlbumArtCustomAsset(),
self::Background => new BackgroundCustomAsset(),
self::BrowserIcon => new BrowserIconCustomAsset(),
self::AlbumArt => new AlbumArtCustomAsset($environment),
self::Background => new BackgroundCustomAsset($environment),
self::BrowserIcon => new BrowserIconCustomAsset($environment),
};
}
}

View File

@ -4,54 +4,23 @@ declare(strict_types=1);
namespace App\Assets;
use App\Environment;
use Intervention\Image\Constraint;
use Intervention\Image\Image;
final class BackgroundCustomAsset extends AbstractCustomAsset
final class BackgroundCustomAsset extends AbstractMultiPatternCustomAsset
{
protected function getPattern(): string
{
return $this->getPatterns()['default'];
}
private function getPatterns(): array
protected function getPatterns(): array
{
return [
'default' => 'background%s.webp',
'image/jpeg' => 'background%s.jpg',
'image/png' => 'background%s.png',
'default' => 'background%s.jpg',
];
}
private function getPathForPattern(string $pattern): string
{
$pattern = sprintf($pattern, '');
return Environment::getInstance()->getUploadsDirectory() . '/' . $pattern;
}
public function getPath(): string
{
$patterns = $this->getPatterns();
foreach ($patterns as $pattern) {
$path = $this->getPathForPattern($pattern);
if (is_file($path)) {
return $path;
}
}
return $patterns['default'];
}
protected function getDefaultUrl(): string
{
return Environment::getInstance()->getAssetUrl() . '/img/hexbg.png';
}
public function delete(): void
{
foreach ($this->getPatterns() as $pattern) {
@unlink($this->getPathForPattern($pattern));
}
return $this->environment->getAssetUrl() . '/img/hexbg.webp';
}
public function upload(Image $image): void
@ -63,29 +32,11 @@ final class BackgroundCustomAsset extends AbstractCustomAsset
$this->delete();
$patterns = $this->getPatterns();
$pattern = $this->getPattern();
$mimeType = $newImage->mime();
$pattern = $patterns[$mimeType] ?? $patterns['default'];
$quality = ('image/png' === $mimeType) ? 100 : 90;
$newImage->save($this->getPathForPattern($pattern), 90);
}
public function getUrl(): string
{
foreach ($this->getPatterns() as $pattern) {
$path = $this->getPathForPattern($pattern);
if (is_file($path)) {
$mtime = filemtime($path);
return Environment::getInstance()->getAssetUrl() . self::UPLOADS_URL_PREFIX . '/' . sprintf(
$pattern,
'.' . $mtime
);
}
}
return $this->getDefaultUrl();
$newImage->save($this->getPathForPattern($pattern), $quality);
}
}

View File

@ -4,7 +4,6 @@ declare(strict_types=1);
namespace App\Assets;
use App\Environment;
use Intervention\Image\Image;
use Symfony\Component\Filesystem\Filesystem;
@ -35,15 +34,13 @@ final class BrowserIconCustomAsset extends AbstractCustomAsset
protected function getDefaultUrl(): string
{
$env = Environment::getInstance();
$assetUrl = $env->getAssetUrl();
return $assetUrl . '/icons/' . $env->getAppEnvironmentEnum()->value . '/original.png';
$assetUrl = $this->environment->getAssetUrl();
return $assetUrl . '/icons/' . $this->environment->getAppEnvironmentEnum()->value . '/original.png';
}
public function upload(Image $image): void
{
$uploadsDir = Environment::getInstance()->getUploadsDirectory() . '/browser_icon';
$uploadsDir = $this->environment->getUploadsDirectory() . '/browser_icon';
(new Filesystem())->mkdir($uploadsDir);
$newImage = clone $image;
@ -59,16 +56,15 @@ final class BrowserIconCustomAsset extends AbstractCustomAsset
public function delete(): void
{
$uploadsDir = Environment::getInstance()->getUploadsDirectory() . '/browser_icon';
$uploadsDir = $this->environment->getUploadsDirectory() . '/browser_icon';
(new Filesystem())->remove($uploadsDir);
}
public function getUrlForSize(int $size): string
{
$env = Environment::getInstance();
$assetUrl = $env->getAssetUrl();
$assetUrl = $this->environment->getAssetUrl();
$uploadsDir = $env->getUploadsDirectory();
$uploadsDir = $this->environment->getUploadsDirectory();
$iconPath = $uploadsDir . '/browser_icon/' . $size . '.png';
if (is_file($iconPath)) {
@ -76,6 +72,6 @@ final class BrowserIconCustomAsset extends AbstractCustomAsset
return $assetUrl . '/uploads/browser_icon/' . $size . '.' . $mtime . '.png';
}
return $assetUrl . '/icons/' . $env->getAppEnvironmentEnum()->value . '/' . $size . '.png';
return $assetUrl . '/icons/' . $this->environment->getAppEnvironmentEnum()->value . '/' . $size . '.png';
}
}

View File

@ -6,18 +6,24 @@ namespace App\Controller\Api\Admin\CustomAssets;
use App\Assets\AssetTypes;
use App\Entity;
use App\Environment;
use App\Http\Response;
use App\Http\ServerRequest;
use Psr\Http\Message\ResponseInterface;
final class DeleteCustomAssetAction
{
public function __construct(
private readonly Environment $environment
) {
}
public function __invoke(
ServerRequest $request,
Response $response,
string $type
): ResponseInterface {
$customAsset = AssetTypes::from($type)->createObject();
$customAsset = AssetTypes::from($type)->createObject($this->environment);
$customAsset->delete();
return $response->withJson(Entity\Api\Status::success());

View File

@ -5,18 +5,24 @@ declare(strict_types=1);
namespace App\Controller\Api\Admin\CustomAssets;
use App\Assets\AssetTypes;
use App\Environment;
use App\Http\Response;
use App\Http\ServerRequest;
use Psr\Http\Message\ResponseInterface;
final class GetCustomAssetAction
{
public function __construct(
private readonly Environment $environment
) {
}
public function __invoke(
ServerRequest $request,
Response $response,
string $type
): ResponseInterface {
$customAsset = AssetTypes::from($type)->createObject();
$customAsset = AssetTypes::from($type)->createObject($this->environment);
return $response->withJson(
[

View File

@ -6,6 +6,7 @@ namespace App\Controller\Api\Admin\CustomAssets;
use App\Assets\AssetTypes;
use App\Entity;
use App\Environment;
use App\Http\Response;
use App\Http\ServerRequest;
use App\Media\AlbumArt;
@ -14,12 +15,17 @@ use Psr\Http\Message\ResponseInterface;
final class PostCustomAssetAction
{
public function __construct(
private readonly Environment $environment
) {
}
public function __invoke(
ServerRequest $request,
Response $response,
string $type
): ResponseInterface {
$customAsset = AssetTypes::from($type)->createObject();
$customAsset = AssetTypes::from($type)->createObject($this->environment);
$flowResponse = Flow::process($request, $response);
if ($flowResponse instanceof ResponseInterface) {

View File

@ -124,7 +124,7 @@ final class Customization
{
$publicCss = $this->settings->getPublicCustomCss() ?? '';
$background = new BackgroundCustomAsset();
$background = new BackgroundCustomAsset($this->environment);
if ($background->isUploaded()) {
$backgroundUrl = $background->getUrl();
@ -156,7 +156,7 @@ final class Customization
public function getBrowserIconUrl(int $size = 256): string
{
return (new BrowserIconCustomAsset())->getUrlForSize($size);
return (new BrowserIconCustomAsset($this->environment))->getUrlForSize($size);
}
/**

View File

@ -8,6 +8,7 @@ use App\Assets\AlbumArtCustomAsset;
use App\Doctrine\ReloadableEntityManagerInterface;
use App\Doctrine\Repository;
use App\Entity;
use App\Environment;
use App\Flysystem\ExtendedFilesystemInterface;
use App\Flysystem\StationFilesystems;
use App\Radio\Enums\StreamFormats;
@ -22,7 +23,8 @@ final class StationRepository extends Repository
{
public function __construct(
ReloadableEntityManagerInterface $em,
private readonly SettingsRepository $settingsRepo
private readonly SettingsRepository $settingsRepo,
private readonly Environment $environment
) {
parent::__construct($em);
}
@ -186,7 +188,7 @@ final class StationRepository extends Repository
}
$customUrl = $this->settingsRepo->readSettings()->getDefaultAlbumArtUrlAsUri();
return $customUrl ?? (new AlbumArtCustomAsset())->getUri();
return $customUrl ?? (new AlbumArtCustomAsset($this->environment))->getUri();
}
public function setFallback(

View File

@ -94,7 +94,7 @@ server {
}
location /static/uploads {
rewrite ^(.+)\.(?:\w+)\.(js|css|png|jpg)$ $1.$2 last;
rewrite ^(.+)\.(?:\w+)\.(js|css|png|jpg|webp)$ $1.$2 last;
alias /var/azuracast/uploads;
try_files $uri =404;

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

BIN
web/static/img/hexbg.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 408 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 465 KiB