mirror of
https://github.com/usetrmnl/byos_laravel.git
synced 2026-01-13 23:18:10 +00:00
feat: support for additional devices
This commit is contained in:
parent
aa1e02d184
commit
75012ba5b1
4 changed files with 96 additions and 16 deletions
21
app/Enums/ImageFormat.php
Normal file
21
app/Enums/ImageFormat.php
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
enum ImageFormat: string
|
||||
{
|
||||
case AUTO = 'auto';
|
||||
case PNG_8BIT_GRAYSCALE = 'png_8bit_grayscale';
|
||||
case BMP3_1BIT_SRGB = 'bmp3_1bit_srgb';
|
||||
case PNG_8BIT_256C = 'png_8bit_256c';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::AUTO => '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',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('devices', function (Blueprint $table) {
|
||||
$table->string('image_format')->default('auto')->after('rotate');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('devices', function (Blueprint $table) {
|
||||
$table->dropColumn('image_format');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
@ -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 {
|
|||
<flux:input label="Height (px)" wire:model="height" type="number"/>
|
||||
<flux:input label="Rotate °" wire:model="rotate" type="number"/>
|
||||
</div>
|
||||
<flux:select label="Image Format" wire:model="image_format">
|
||||
@foreach(\App\Enums\ImageFormat::cases() as $format)
|
||||
<flux:select.option value="{{ $format->value }}">{{$format->label()}}</flux:select.option>
|
||||
@endforeach
|
||||
</flux:select>
|
||||
<flux:input label="Default Refresh Interval (seconds)" wire:model="default_refresh_interval"
|
||||
type="number"/>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue