Как сохранить метаданные изображения в laravel 5.6

Пытаюсь сделать галерею изображений. Для этой цели я храню исходные изображения (сейчас около 7000, а в будущем их будет более 60 000) в пути laravel хранилища. Затем я делаю задание, которое сохраняет путь и метаданные (размер изображения, разрешение, mimetype, ширину и высоту) в db.

Проблема в том, что он очень медленный.

это мой контроллер:

 public function startJob() {

        // Start doing Jobs
        CreateDirectories::withChain([
            new RecordPaths,
            // new OptimizeImage,
            // new SendNotification,
        ])->dispatch()->delay(now()->addSeconds(3));
        echo 'create directories and stored paths to database!';
    }

В своем контроллере я делаю кое-какие работы. Сначала он создаст каталог, в котором я храню превью. После того, как эта работа будет выполнена, следующая - RecordPaths к БД.

И вот в чем проблема, он очень медленный (изображение / 2сек).

это моя работа:

class RecordPaths implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

        public function handle()
        {
            $this->truncate();

            $files = Storage::disk('gallery')->allFiles();
            foreach($files as $file) {
                $thumb = new Thumb;
                $thumb->brand = explode("/", $file, 2)[0];
                $thumb->name = array_slice(explode("/", $file),-1)[0];
                $thumb->path = $file;
                //
                $thumb->size = $this->imageMetadata($file, 'fileSize');
                $thumb->width = $this->imageMetadata($file, 'imageWidth');
                $thumb->height = $this->imageMetadata($file, 'imageHeight');
                $thumb->mime = $this->imageMetadata($file, 'mimeType');
                //
                $thumb->save();
            }
        }

        public function truncate() {
            return Thumb::truncate();
        }

        public function imageMetadata($file, $type) {
            $metaData = [];
            $metaData['mimeType'] = \Image::make(storage_path("app\public\gallery\\") . $file)->exif('MimeType');
            $metaData['fileSize'] = \Image::make(storage_path("app\public\gallery\\") . $file)->exif('FileSize');
            $metaData['imageWidth'] = \Image::make(storage_path("app\public\gallery\\") . $file)->exif('ExifImageWidth');
            $metaData['imageHeight'] = \Image::make(storage_path("app\public\gallery\\") . $file)->exif('ExifImageLength');
            return $metaData[$type];
        }
    }

$files = Storage::disk('gallery')->allFiles(); в методе handle возвращает это: enter image description here

и мой db после некоторых вставок: enter image description here

Есть ли у кого-нибудь идеи, как это ускорить?

Многопоточность?

Goodbye StackExchange 13.09.2018 20:28

@FrankerZ с laravel? :П

Stratadox 13.09.2018 20:40

"Хранилище :: диск ('галерея') -> allFiles ();" <- Файлы все? Похоже, вы повторяете процесс для каждого имеющегося у вас изображения, а не только для необработанных. В таком случае неудивительно, что он медленный.

Stratadox 13.09.2018 20:43

@Stratadox хм, стоит ли мне сохранить "Storage :: disk ('gallery') -> allFiles ();" в массив перед повторением?

Greg Ostry 13.09.2018 20:45

Эээ, нет, вам просто не следует повторять процесс для файлов, которые вы уже обработали. Я мог бы неправильно истолковать процесс, но похоже, что вы обрабатываете 7000 изображений каждый раз, когда загружаете 1. Если это действительно так, вы можете ускорить его в 7000 раз, не выполняя всю эту двойную работу.

Stratadox 13.09.2018 20:48

можешь дать мне простой пример? Если я не сохраню метаданные. Повторяющаяся часть для сохранения путей к файлам в БД занимает 3 секунды.

Greg Ostry 13.09.2018 20:52
0
6
1 210
1

Ответы 1

Сначала сделайте только один \Image::make вместо 4, затем просто вызовите метод -> exif с параметрами. Во-вторых, замените $thumb->save(); пакетной вставкой. Вы можете использовать библиотеку это или написать собственный код (см. это). P.S. Это увеличит время выполнения. P.S.S. Также вы можете попробовать использовать куски laravel или разделить изображения между несколькими рабочими.

Другие вопросы по теме