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
+