Blurhash with Laravel Spatie Media Library
If you don't know BlurHash, it's a way to generate blurred placeholders for images that are efficiently storable in a DB because of their size of 20—30 characters. It's really a great tool and I use it as a placeholder for images in my apps. It makes the transition smoother until the image is loaded.
Integration with Laravel
To work with BlurHash in Laravel, I use the bepsvpt/blurhash
package which exposes a Facade to make it easy to work in Laravel.
You can then generate the BlurHash from a file like this:
_10use Bepsvpt\Blurhash\Facades\BlurHash;_10_10// From a local file path_10BlurHash::encode($path); // LEHV6nWB2yk8pyo0adR*.7kCMdnj_10_10// From an uploaded path_10BlurHash::encode($request->file('avatar')); // LEHV6nWB2yk8pyo0adR*.7kCMdnj
Integration with Spatie Media Library
Spatie Media Library is certainly the best media library out there in the Laravel ecosystem. They have so many good & well-thought features it'd be a crime not to use it in your app if you links files to your models.
I wanted to generate a BlurHash for my media and my first idea was to use an Event Listener.
Media Library fires a few events that we can listen for. So my first implementation looked like this:
This worked fine, until I changed my media driver to cloud driver.
The $media->getPath()
would return a local path, while the file would only exists on the cloud driver. This will throw an error as the BlurHash library will try to read the file that doesn't exist.
My first idea was to download the file content, create a new temporary file and use that file path to generate the BlurHash but that felt wrong. It'd make unecessary network requests and add some unecessary delay to the request. Ideally I'd reuse the original file so that I don't have to download it again just after uploading it.
So I changed my implementation, and instead of using a Listener where the uploaded file is not available, I'll generate the BlurHash where I upload my file, in my Controller.
And that wraps it! We can now get the blurhash from the media.