Ogólnie to twoje pytanie jest bardzo fajne.
Ja widzę to tak kontroler przyjmuje przez DI (dependecy injection
https://laravel.com/docs/5.6/container) powiedzmy interface ImageResizer ta abstrakcja przyjmuje natomiast interaface Storage. Kontroller dodatkowo przyjmuje abstrakcje ImageRepository będzie to odpowidzialne za komunikacje z db. Nie wiem czy koniecznie chce swoje DTO na Image tutaj ale moze wtedy bedzie to ładniej wyglądać
ImageResizer - tutaj zawierasz logikę obróbki zdjęcia przekazuje on do Storage zdjęcia po obróbce zwracasz throw Exception jezeli coś poszło nie tak lub true jezli wszytko się udało
Storage - tutaj zawierasz logikę zapisu oczywiscie throw jezli coś poszło nie tak
ImageRepository - jezli wszytko się udało to zapisujesz nazwe przez repository
Dzięki takiemu podziałowi masz SRP a dzięki DI masz swobodne testowanie oraz podmianę odpowiednich abstraktów w zależności od środowiska.
P.S
Jak ognia unikaj w nazwach klas słów typu
-object
-helper
-service
-class
-base
to po prostu jest zbyt generczne i nic nikumu nie mówi...