ralphjsmit/laravel-seo

It's not possible to generate ImageMeta for images from other sources than images from `public` directory

dejagersh opened this issue · 0 comments

I am trying to generate ImageMeta for a Post model, which has an image stored in S3. When this image is uploaded, I calculate their dimensions, write that information to my model, and then write the image to S3. ImageMeta only has a constructor for constructing from a public path, which I don't have.

I am currently working around this like this:

$imageMeta = new ImageMeta('images/logo-small.png');

$imageMeta->width = $post->image_width;
$imageMeta->height = $post->image_height;

Which isn't optimal... Is there a different way I should be doing this? Or is a better approach not possible right now? 😬

I have some ideas for improving ImageMeta, but it's a breaking change. Something like this would be much more flexible I think:

readonly class ImageMeta
{
    public function __construct(public int $width, public int $height)
    {
    }

    public static function forPublicImage(string $path): self
    {
        $publicPath = public_path($path);

        if (!is_file($publicPath)) {
            throw new Exception("Path {$publicPath} is not a file.");
        }

        [$width, $height] = getimagesize($publicPath);

        return new self($width, $height);
    }

    public static function forImageFromDisk(Filesystem $filesystem, string $path) {
        stream_copy_to_stream(
            $filesystem->readStream($path),
            $tmpFile = tmpfile()
        );

        [$width, $height] = getimagesize(stream_get_meta_data($tmpFile)['uri']);

        return new self($width, $height);
    }
}