From 75012ba5b19c42928202bbbd7f85120ed3fa1ae1 Mon Sep 17 00:00:00 2001 From: Benjamin Nussbaum Date: Tue, 13 May 2025 16:14:01 +0200 Subject: [PATCH] feat: support for additional devices --- app/Enums/ImageFormat.php | 21 ++++++++ app/Services/ImageGenerationService.php | 54 +++++++++++++------ ...4942_add_image_format_to_devices_table.php | 28 ++++++++++ .../livewire/devices/configure.blade.php | 9 ++++ 4 files changed, 96 insertions(+), 16 deletions(-) create mode 100644 app/Enums/ImageFormat.php create mode 100644 database/migrations/2025_05_13_154942_add_image_format_to_devices_table.php diff --git a/app/Enums/ImageFormat.php b/app/Enums/ImageFormat.php new file mode 100644 index 0000000..75a7307 --- /dev/null +++ b/app/Enums/ImageFormat.php @@ -0,0 +1,21 @@ + 'Auto', + self::PNG_8BIT_GRAYSCALE => 'PNG 8-bit Grayscale Gray 2c', + self::BMP3_1BIT_SRGB => 'BMP3 1-bit sRGB 2c', + self::PNG_8BIT_256C => 'PNG 8-bit Grayscale Gray 256c', + }; + } +} diff --git a/app/Services/ImageGenerationService.php b/app/Services/ImageGenerationService.php index 79f1a37..7211d8a 100644 --- a/app/Services/ImageGenerationService.php +++ b/app/Services/ImageGenerationService.php @@ -2,6 +2,7 @@ namespace App\Services; +use App\Enums\ImageFormat; use App\Models\Device; use App\Models\Plugin; use Illuminate\Support\Facades\Storage; @@ -38,21 +39,40 @@ class ImageGenerationService throw new \RuntimeException('Failed to generate PNG: '.$e->getMessage(), 0, $e); } } - - if (isset($device->last_firmware_version) - && version_compare($device->last_firmware_version, '1.5.2', '<')) { - try { - ImageGenerationService::convertToBmpImageMagick($pngPath, $bmpPath); - } catch (\ImagickException $e) { - throw new \RuntimeException('Failed to convert image to BMP: '.$e->getMessage(), 0, $e); - } - } else { - try { - ImageGenerationService::convertToPngImageMagick($pngPath, $device->width, $device->height, $device->rotate); - } catch (\ImagickException $e) { - throw new \RuntimeException('Failed to convert image to PNG: '.$e->getMessage(), 0, $e); - } + switch ($device->image_format) { + case ImageFormat::BMP3_1BIT_SRGB->value: + try { + ImageGenerationService::convertToBmpImageMagick($pngPath, $bmpPath); + } catch (\ImagickException $e) { + throw new \RuntimeException('Failed to convert image to BMP: '.$e->getMessage(), 0, $e); + } + break; + case ImageFormat::PNG_8BIT_GRAYSCALE->value: + case ImageFormat::PNG_8BIT_256C->value: + try { + ImageGenerationService::convertToPngImageMagick($pngPath, $device->width, $device->height, $device->rotate, quantize: $device->image_format === ImageFormat::PNG_8BIT_GRAYSCALE); + } catch (\ImagickException $e) { + throw new \RuntimeException('Failed to convert image to PNG: '.$e->getMessage(), 0, $e); + } + break; + case ImageFormat::AUTO->value: + default: + if (isset($device->last_firmware_version) + && version_compare($device->last_firmware_version, '1.5.2', '<')) { + try { + ImageGenerationService::convertToBmpImageMagick($pngPath, $bmpPath); + } catch (\ImagickException $e) { + throw new \RuntimeException('Failed to convert image to BMP: '.$e->getMessage(), 0, $e); + } + } else { + try { + ImageGenerationService::convertToPngImageMagick($pngPath, $device->width, $device->height, $device->rotate); + } catch (\ImagickException $e) { + throw new \RuntimeException('Failed to convert image to PNG: '.$e->getMessage(), 0, $e); + } + } } + $device->update(['current_screen_image' => $uuid]); \Log::info("Device $device->id: updated with new image: $uuid"); @@ -77,7 +97,7 @@ class ImageGenerationService /** * @throws \ImagickException */ - private static function convertToPngImageMagick(string $pngPath, ?int $width, ?int $height, ?int $rotate): void + private static function convertToPngImageMagick(string $pngPath, ?int $width, ?int $height, ?int $rotate, $quantize = true): void { $imagick = new \Imagick($pngPath); if ($width !== 800 || $height !== 480) { @@ -87,7 +107,9 @@ class ImageGenerationService $imagick->rotateImage(new ImagickPixel('black'), $rotate); } $imagick->setImageType(\Imagick::IMGTYPE_GRAYSCALE); - $imagick->quantizeImage(2, \Imagick::COLORSPACE_GRAY, 0, true, false); + if ($quantize) { + $imagick->quantizeImage(2, \Imagick::COLORSPACE_GRAY, 0, true, false); + } $imagick->setImageDepth(8); $imagick->stripImage(); diff --git a/database/migrations/2025_05_13_154942_add_image_format_to_devices_table.php b/database/migrations/2025_05_13_154942_add_image_format_to_devices_table.php new file mode 100644 index 0000000..41dc98c --- /dev/null +++ b/database/migrations/2025_05_13_154942_add_image_format_to_devices_table.php @@ -0,0 +1,28 @@ +string('image_format')->default('auto')->after('rotate'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('devices', function (Blueprint $table) { + $table->dropColumn('image_format'); + }); + } +}; diff --git a/resources/views/livewire/devices/configure.blade.php b/resources/views/livewire/devices/configure.blade.php index ffd2ebc..84cbce5 100644 --- a/resources/views/livewire/devices/configure.blade.php +++ b/resources/views/livewire/devices/configure.blade.php @@ -16,6 +16,7 @@ new class extends Component { public $width; public $height; public $rotate; + public $image_format; // Playlist properties public $playlists; @@ -41,6 +42,7 @@ new class extends Component { $this->width = $device->width; $this->height = $device->height; $this->rotate = $device->rotate; + $this->image_format = $device->image_format; $this->playlists = $device->playlists()->with('items.plugin')->orderBy('created_at')->get(); return view('livewire.devices.configure', [ @@ -68,6 +70,7 @@ new class extends Component { 'width' => 'required|integer|min:1', 'height' => 'required|integer|min:1', 'rotate' => 'required|integer|min:0|max:359', + 'image_format' => 'required|string', ]); $this->device->update([ @@ -78,6 +81,7 @@ new class extends Component { 'width' => $this->width, 'height' => $this->height, 'rotate' => $this->rotate, + 'image_format' => $this->image_format, ]); Flux::modal('edit-device')->close(); @@ -288,6 +292,11 @@ new class extends Component { + + @foreach(\App\Enums\ImageFormat::cases() as $format) + {{$format->label()}} + @endforeach +