From 99b8f1949348fee75ba8edf75dd799326776f879 Mon Sep 17 00:00:00 2001 From: Leane Schlundt Date: Thu, 25 Jan 2024 10:58:05 +0100 Subject: [PATCH] Add new svg annotation generation flags Keep SVG generation call in GenerateImage/VideoAnnotationPatch due to changes in #120. --- src/Console/Commands/GenerateMissing.php | 76 +++++++++++++++++------ src/Jobs/GenerateAnnotationPatch.php | 18 ++++-- src/Jobs/GenerateImageAnnotationPatch.php | 24 +++---- src/Jobs/GenerateVideoAnnotationPatch.php | 8 ++- 4 files changed, 90 insertions(+), 36 deletions(-) diff --git a/src/Console/Commands/GenerateMissing.php b/src/Console/Commands/GenerateMissing.php index 30083bc7..f3580f4e 100644 --- a/src/Console/Commands/GenerateMissing.php +++ b/src/Console/Commands/GenerateMissing.php @@ -19,7 +19,7 @@ class GenerateMissing extends Command * @var string */ protected $signature = 'largo:generate-missing {--dry-run} {--volume=} {--no-image-annotations} {--no-video-annotations} {--queue=} {--newer-than=} - {--older-than=}'; + {--older-than=} {--only-image-svg-annotations} {--only-video-svg-annotations}'; /** * The console command description. @@ -63,6 +63,19 @@ public function handle() $storage = Storage::disk(config('largo.patch_storage_disk')); $queue = $this->option('queue') ?: config('largo.generate_annotation_patch_queue'); + if ($this->option('only-image-svg-annotations')) { + $onlySVG = true; + $this->handleImageAnnotations($storage, $pushToQueue, $queue, $onlySVG); + return; + } + + if ($this->option('only-video-svg-annotations')) { + $onlySVG = true; + $this->handleVideoAnnotations($storage, $pushToQueue, $queue, $onlySVG); + return; + + } + if (!$this->option('no-image-annotations')) { $this->handleImageAnnotations($storage, $pushToQueue, $queue); } @@ -72,6 +85,7 @@ public function handle() if (!$this->option('no-video-annotations')) { $this->handleVideoAnnotations($storage, $pushToQueue, $queue); } + } /** @@ -81,7 +95,7 @@ public function handle() * @param bool $pushToQueue * @param string $queue */ - protected function handleImageAnnotations($storage, $pushToQueue, $queue) + protected function handleImageAnnotations($storage, $pushToQueue, $queue, $onlySVG = false) { $annotations = ImageAnnotation::join('images', 'images.id', '=', 'image_annotations.image_id') ->when($this->option('volume'), function ($query) { @@ -99,13 +113,26 @@ protected function handleImageAnnotations($storage, $pushToQueue, $queue) $progress = $this->output->createProgressBar($total); $this->info("Checking {$total} image annotations..."); - $handleAnnotation = function ($annotation) use ($progress, $pushToQueue, $storage, $queue) { + $handleAnnotation = function ($annotation) use ($progress, $pushToQueue, $storage, $queue, $onlySVG) { $prefix = fragment_uuid_path($annotation->uuid); - if (!$storage->exists("{$prefix}/{$annotation->id}.{$this->format}")) { - $this->count++; - if ($pushToQueue) { - GenerateImageAnnotationPatch::dispatch($annotation) - ->onQueue($queue); + + if($onlySVG){ + if (!$storage->exists("{$prefix}/{$annotation->id}.svg")) { + $this->count++; + if ($pushToQueue) { + $createSVG = 2; + GenerateImageAnnotationPatch::dispatch($annotation, $createSVG) + ->onQueue($queue); + } + } + } else { + if (!$storage->exists("{$prefix}/{$annotation->id}.{$this->format}")) { + $this->count++; + if ($pushToQueue) { + $createSVG = $storage->exists("{$prefix}/{$annotation->id}.svg") ? 0 : 1; + GenerateImageAnnotationPatch::dispatch($annotation, $createSVG) + ->onQueue($queue); + } } } $progress->advance(); @@ -114,13 +141,14 @@ protected function handleImageAnnotations($storage, $pushToQueue, $queue) $annotations->eachById($handleAnnotation, 10000, 'image_annotations.id', 'id'); $progress->finish(); - - if($total === 0) { + + if ($total === 0) { $this->info("\n"); return; } $percent = round($this->count / $total * 100, 2); + $this->info("\nFound {$this->count} image annotations with missing patches ({$percent} %)."); if ($pushToQueue) { $this->info("Pushed {$this->count} jobs to queue {$queue}."); @@ -134,7 +162,7 @@ protected function handleImageAnnotations($storage, $pushToQueue, $queue) * @param bool $pushToQueue * @param string $queue */ - protected function handleVideoAnnotations($storage, $pushToQueue, $queue) + protected function handleVideoAnnotations($storage, $pushToQueue, $queue, $onlySVG = false) { $annotations = VideoAnnotation::join('videos', 'videos.id', '=', 'video_annotations.video_id') ->when($this->option('volume'), function ($query) { @@ -149,13 +177,25 @@ protected function handleVideoAnnotations($storage, $pushToQueue, $queue) $progress = $this->output->createProgressBar($total); $this->info("Checking {$total} video annotations..."); - $handleAnnotation = function ($annotation) use ($progress, $pushToQueue, $storage, $queue) { + $handleAnnotation = function ($annotation) use ($progress, $pushToQueue, $storage, $queue, $onlySVG) { $prefix = fragment_uuid_path($annotation->uuid); - if (!$storage->exists("{$prefix}/v-{$annotation->id}.{$this->format}")) { - $this->count++; - if ($pushToQueue) { - GenerateVideoAnnotationPatch::dispatch($annotation) - ->onQueue($queue); + if($onlySVG){ + if (!$storage->exists("{$prefix}/v-{$annotation->id}.svg")) { + $this->count++; + if ($pushToQueue) { + $createSVG = 2; + GenerateVideoAnnotationPatch::dispatch($annotation, $createSVG) + ->onQueue($queue); + } + } + } else { + if (!$storage->exists("{$prefix}/v-{$annotation->id}.{$this->format}")) { + $this->count++; + if ($pushToQueue) { + $createSVG = $storage->exists("{$prefix}/v-{$annotation->id}.svg") ? 0 : 1; + GenerateVideoAnnotationPatch::dispatch($annotation, $createSVG) + ->onQueue($queue); + } } } $progress->advance(); @@ -165,7 +205,7 @@ protected function handleVideoAnnotations($storage, $pushToQueue, $queue) $progress->finish(); - if($total === 0) { + if ($total === 0) { $this->info("\n"); return; } diff --git a/src/Jobs/GenerateAnnotationPatch.php b/src/Jobs/GenerateAnnotationPatch.php index f8753768..197a9cdb 100644 --- a/src/Jobs/GenerateAnnotationPatch.php +++ b/src/Jobs/GenerateAnnotationPatch.php @@ -3,6 +3,7 @@ namespace Biigle\Modules\Largo\Jobs; use Str; +use SVG\Nodes\Shapes\SVGPolyline; use SVG\SVG; use Exception; use FileCache; @@ -11,13 +12,11 @@ use Biigle\VolumeFile; use Jcupitt\Vips\Image; use Biigle\VideoAnnotation; -use SVG\Nodes\Shapes\SVGLine; use SVG\Nodes\Shapes\SVGRect; use SVG\Nodes\Shapes\SVGCircle; use Biigle\Contracts\Annotation; use SVG\Nodes\Shapes\SVGEllipse; use SVG\Nodes\Shapes\SVGPolygon; -use SVG\Nodes\Shapes\SVGPolyline; use Illuminate\Support\Facades\Log; use Illuminate\Queue\SerializesModels; use Illuminate\Queue\InteractsWithQueue; @@ -57,6 +56,16 @@ abstract class GenerateAnnotationPatch extends Job implements ShouldQueue */ protected $deleteWhenMissingModels = true; + /** + * Bool to create SVG + * + * 0 = Create no SVG + * 1 = Create SVG + * 2 = Create SVG only + * + * **/ + protected $createSVG = 1; + /** * Create a new job instance. @@ -66,12 +75,13 @@ abstract class GenerateAnnotationPatch extends Job implements ShouldQueue * * @return void */ - public function __construct(Annotation $annotation, $targetDisk = null) + public function __construct(Annotation $annotation, $createSVG = 1, $targetDisk = null) { $this->annotation = $annotation; $this->targetDisk = $targetDisk !== null ? $targetDisk : config('largo.patch_storage_disk'); + $this->createSVG = $createSVG; } /** @@ -342,7 +352,7 @@ protected function getSVGAnnotationPatch($width, $height, $points, $shape) if ($shape->id == Shape::lineId()) { $annotation->setAttribute('stroke-linecap', 'round'); } - + $doc->addChild($annotation); return $image; diff --git a/src/Jobs/GenerateImageAnnotationPatch.php b/src/Jobs/GenerateImageAnnotationPatch.php index 6fe70e5c..20b4b269 100644 --- a/src/Jobs/GenerateImageAnnotationPatch.php +++ b/src/Jobs/GenerateImageAnnotationPatch.php @@ -2,12 +2,12 @@ namespace Biigle\Modules\Largo\Jobs; -use Biigle\Shape; -use Biigle\VolumeFile; +use Storage; use Exception; use FileCache; -use Storage; use VipsImage; +use Biigle\Shape; +use Biigle\VolumeFile; class GenerateImageAnnotationPatch extends GenerateAnnotationPatch { @@ -25,15 +25,17 @@ public function handleFile(VolumeFile $file, $path) $targetPath = $this->getTargetPath($this->annotation); $image = $this->getVipsImage($path); - $buffer = $this->getAnnotationPatch($image, $this->annotation->getPoints(), $this->annotation->getShape()); + if ($this->createSVG !== 2) { + $buffer = $this->getAnnotationPatch($image, $this->annotation->getPoints(), $this->annotation->getShape()); + Storage::disk($this->targetDisk)->put($targetPath, $buffer); + } - $svgTargetPath = str_replace(config('largo.patch_format'),'svg',$targetPath); - $svgAnnotation = $this->getSVGAnnotationPatch($image->width,$image->height, - $this->annotation->getPoints(), $this->annotation->getShape()); - - - Storage::disk($this->targetDisk)->put($targetPath, $buffer); - Storage::disk($this->targetDisk)->put($svgTargetPath, $svgAnnotation); + if ($this->createSVG) { + $svgTargetPath = str_replace(config('largo.patch_format'), 'svg', $targetPath); + $svgAnnotation = $this->getSVGAnnotationPatch($image->width, $image->height, $this->annotation->getPoints(), + $this->annotation->getShape()); + Storage::disk($this->targetDisk)->put($svgTargetPath, $svgAnnotation); + } } /** diff --git a/src/Jobs/GenerateVideoAnnotationPatch.php b/src/Jobs/GenerateVideoAnnotationPatch.php index c552ccac..8b23110d 100644 --- a/src/Jobs/GenerateVideoAnnotationPatch.php +++ b/src/Jobs/GenerateVideoAnnotationPatch.php @@ -30,11 +30,13 @@ public function handleFile(VolumeFile $file, $path) $video = $this->getVideo($path); $frame = $this->getVideoFrame($video, $this->annotation->frames[0]); - $buffer = $this->getAnnotationPatch($frame, $points, $this->annotation->shape); - Storage::disk($this->targetDisk)->put($targetPath, $buffer); + if ($this->createSVG !== 2) { + $buffer = $this->getAnnotationPatch($frame, $points, $this->annotation->shape); + Storage::disk($this->targetDisk)->put($targetPath, $buffer); + } - if ($this->annotation->shape->id !== Shape::wholeFrameId()) { + if ($this->annotation->shape->id !== Shape::wholeFrameId() && $this->createSVG) { $svgTargetPath = str_replace(config('largo.patch_format'), 'svg', $targetPath); $svgAnnotation = $this->getSVGAnnotationPatch($frame->width, $frame->height, $points, $this->annotation->shape); Storage::disk($this->targetDisk)->put($svgTargetPath, $svgAnnotation);