abordage/laravel-og-images

Generate Open Graph images (og:image, twitter:image, vk:image) for each site pages

0.4.2 2024-03-23 19:35 UTC

README

Create Open Graph images (og:image, twitter:image, vk:image) for each (or some) site pages.

Open Graph Images Generator

Packagist Version GitHub Tests Status GitHub Code Style Status Packagist PHP Version Support License

Use page title to create an eye-catching page preview when users share the link on social networks or instant messengers. Learn more about Open Graph.

Features:

  • Image generation with your text and site name
  • Fully customizable (see configuration)
  • Small image size (15-50 Kb) with high resolution and quality (check it)
  • Aspect ratios presets for popular social networks

See examples

Requirements

  • PHP 7.4 - 8.3
  • Laravel 8.x - 11.x
  • The Imagick PHP extension

Installation

You can install the package via composer:

composer require abordage/laravel-og-images

You can publish config file with:

php artisan vendor:publish --tag="og-images-config"

Quick start

use Abordage\LaravelOpenGraphImages\Facades\OpenGraphImages;

$text = 'The adventures first, explanations take such a dreadful time!';
$path = \Storage::put('first-og-image.png');

$opengraph = OpenGraphImages::make($text)->save($path);

Note
All images are encoded in PNG format as it provides the best ratio between size/quality. For the same reason, the package uses the Imagick driver - in tests, it showed an advantage in speed and final size of the generated images.

Usage

// for <og:image>
OpenGraphImages::make($text)->save($path);
// or
OpenGraphImages::make($text, 'opengraph')->save($path);

// for <twitter:image>
OpenGraphImages::make($text, 'twitter')->save($path);

// for <vk:image>
OpenGraphImages::make($text, 'vk')->save($path);

// custom size
OpenGraphImages::makeCustom($text, 600, 400)->save($path);

After generation, you need to somehow organize the relationship of images with a specific page (for example, attach to a model). If you already have a solution ready to accept an image and attach it to a specific page, you can get the image as a string instead of saving it:

$imageBlob = OpenGraphImages::make($text)->get();

If after generation you need to get sizes of the image, you can get it as follows:

$openGraphImage = OpenGraphImages::make($text, 'twitter');
$openGraphImage->save($path);
$imageSizes = $openGraphImage->getImageSizes();
// return [
//    'width' => 1200,
//    'height' => 600
// ];

Usage with spatie/laravel-medialibrary

spatie/laravel-medialibrary is a great package for associate all sorts of files with Eloquent models. If you are using this package (or similar), all you need to do is to add new collections to the model and attach images using media library.

class Page extends Model implements HasMedia
{
    use InteractsWithMedia;
    
    // ...

    public function registerMediaCollections(): void
    {
        // ...
        
        $this->addMediaCollection('opengraph')
             ->singleFile();
       
        $this->addMediaCollection('twitter')
             ->singleFile();
    }
    
    // ...
}

Next, when creating a new page (or updating), generate an og-image and attach it:

$page = new Page();
$page->title = 'Your awesome title';
$page->save();

// generate image and attach to model
$image = OpenGraphImages::make($page->title);
$page->addMediaFromString($image->get())
     ->usingFileName(\Str::slug($page->title) . '.png')
     ->withCustomProperties($image->getImageSizes())
     ->toMediaCollection('opengraph');

Multiple images:

$page = new Page();
$page->title = 'Your awesome title';
$page->save();

$presets = ['opengraph', 'twitter', 'vk'];
foreach ($presets as $preset) {
    $image = OpenGraphImages::make($page->title, $preset);
    $page->addMediaFromString($image->get())
         ->usingFileName(\Str::slug($page->title) . '-' . $preset . '.png')
         ->withCustomProperties($image->getImageSizes())
         ->toMediaCollection($preset);
}

Now you can get the link for the og:image meta tag as follows:

$ogImageUrl = $page->getFirstMediaUrl('opengraph');
$twitterImageUrl = $page->getFirstMediaUrl('twitter');
$vkImageUrl = $page->getFirstMediaUrl('vk');

Configuration

$config = [
    /*
    |--------------------------------------------------------------------------
    | Background Color
    |--------------------------------------------------------------------------
    |
    | Supported: HEX, RGB or RGBA format
    |
    */
    'background_color' => '#474761',

    /*
    |--------------------------------------------------------------------------
    | Text Color
    |--------------------------------------------------------------------------
    |
    | Supported: HEX, RGB or RGBA format
    |
    */
    'text_color' => '#eee',

    /*
    |--------------------------------------------------------------------------
    | App Name
    |--------------------------------------------------------------------------
    |
    | Set null to disable
    |
    | Supported: string or null
    |
    */
    'app_name' => config('app.name'),

    /*
    |--------------------------------------------------------------------------
    | App Name Text Color
    |--------------------------------------------------------------------------
    |
    | Supported: HEX, RGB or RGBA format
    |
    */
    'app_name_color' => '#eee',

    /*
    |--------------------------------------------------------------------------
    | App Name Decoration Color
    |--------------------------------------------------------------------------
    |
    | Supported: HEX, RGB or RGBA format
    |
    */
    'app_name_decoration_color' => '#fb3361',

    /*
    |--------------------------------------------------------------------------
    | Text Alignment
    |--------------------------------------------------------------------------
    |
    | Multiline text alignment
    |
    | Supported: "left", "center", "right"
    |
    */
    'text_alignment' => 'left',

    /*
    |--------------------------------------------------------------------------
    | Text Sticky
    |--------------------------------------------------------------------------
    |
    | Supported: "left", "center", "right"
    |
    */
    'text_sticky' => 'center',

    /*
    |--------------------------------------------------------------------------
    | App Name Position
    |--------------------------------------------------------------------------
    |
    | Supported: "top-left", "top-center", "top-right",
    |            "bottom-left", "bottom-center", "bottom-right"
    |
    */
    'app_name_position' => 'bottom-center',

    /*
    |--------------------------------------------------------------------------
    | App Name Decoration Style
    |--------------------------------------------------------------------------
    |
    | Set null to disable
    |
    | Supported: "line", "label", "rectangle", null
    |
    */
    'app_name_decoration_style' => 'line',

    /*
    |--------------------------------------------------------------------------
    | Font Size
    |--------------------------------------------------------------------------
    |
    */
    'font_size' => 55,

    /*
    |--------------------------------------------------------------------------
    | App Name Font Size
    |--------------------------------------------------------------------------
    |
    */
    'app_name_font_size' => 30,

    /*
    |--------------------------------------------------------------------------
    | Text Font
    |--------------------------------------------------------------------------
    |
    | If set null, will be used Preset Font (Roboto Regular)
    |
    | Supported: "absolute/path/to/your/font.ttf", null
    |
    */
    'font_path' => null,

    /*
    |--------------------------------------------------------------------------
    | App Name Font
    |--------------------------------------------------------------------------
    |
    | If set null, will be used Preset Font (Roboto Medium)
    |
    | Supported: "absolute/path/to/your/font.ttf", null
    |
    */
    'app_name_font_path' => null,
];

API Reference

Method Returns Added in Changed in
make(string $text, string $preset = 'opengraph') self 0.1.0 0.2.0
makeCustom(string $text, int $width, int $height) self 0.2.0 -
get() string 0.1.0 -
save(string $path) boolean 0.1.0 -
getImageSizes() array 0.3.0 -

Images aspect ratios

Preset Aspect ratios Docs
make(string $text) 1200 x 630 (1.91:1)
make(string $text, 'opengraph') 1200 x 630 (1.91:1)
make(string $text, 'facebook') 1200 x 630 (1.91:1) fb
make(string $text, 'twitter') 1200 x 600 (2:1) twitter
make(string $text, 'vk') 1200 x 536 (2.2:1) vk

Roadmap

Add ability to use gradients and images for the background.

Testing

Run all tests

composer test:all

or

composer test:phpunit
composer test:phpstan
composer test:phpcs

or see https://github.com/abordage/laravel-og-images/actions/workflows/tests.yml

Feedback

Find a bug or have a feature request? Open an issue, or better yet, submit a pull request - contribution welcome!

Contributing

Please see CONTRIBUTING for details.

Credits

License

The MIT License (MIT). Please see License File for more information.