Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Miniprogram Poster Laravel Package

ibrand/laravel-miniprogram-poster

ibrand/laravel-miniprogram-poster is a Laravel package for generating WeChat mini program sharing posters. It composes QR codes, images, and text into downloadable poster images through a simple, configurable API, streamlining referral and share-card workflows for PHP applications.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and wire up

composer require ibrand/laravel-miniprogram-poster
php artisan vendor:publish --provider="iBrand\MiniProgramPoster\ServiceProvider"

Laravel 5.5+ auto-discovers the provider and registers a facade alias. Confirm the config lands in config/ (the package predates the config/ibrand-*.php naming convention, so check the provider's mergeConfigFrom call rather than guessing the filename).

Check your runtime before you write a line of code. This package is a thin wrapper over intervention/image 2.x, which means GD (or Imagick). Verify:

php -r "var_dump(extension_loaded('gd'), function_exists('imagecreatefrompng'), function_exists('imagettftext'));"

Missing FreeType is the classic failure — the poster renders but any text layer is blank or fatal.

Where to look first. The package is small — read src/ end to end (it's a handful of classes) before integrating. There is no docs site, the README is minimal, and the facade is the real API surface. src/ServiceProvider.php → facade → the single poster/composition class tells you everything: constructor signature, how the background is loaded, how layer coordinates are passed, and what save() returns.

First use case — share poster for a mini-program page. The canonical job: take a background template, composite a mini-program QR code (obtained from WeChat's wxacode.getUnlimited API) into a fixed slot, save, return a URL the front-end renders in a share sheet.

use iBrand\MiniProgramPoster\Facades\MiniProgramPoster;

// QR PNG already fetched and cached from wxacode.getUnlimited
$path = MiniProgramPoster::make(public_path('posters/base-750x1334.png'))
    ->qrcode($qrPng, 275, 940, 200, 200)   // x, y, w, h
    ->save(storage_path("app/public/posters/{$hash}.png"));

Method names vary by release — treat the above as the shape, and open the facade to get the exact ones. The important part is that you supply the QR as an image file; this package does not call WeChat for you.

Implementation Patterns

Two-stage pipeline: fetch QR, then compose. Keep these separate. Fetching the QR involves an access token, HTTP, and rate limits; composition is local CPU. A QrCodeService (cache keyed by scene, backed by Cache::remember with a TTL shorter than the token) feeding a PosterService that owns the facade call keeps failures diagnosable — when a poster is blank you know instantly whether the QR or the composite broke.

Never generate on the share path. onShareAppMessage fires on tap and users expect an instant sheet. Generate on a write event (user "creates" a card, completes an order) or push it to a queue. A 2000×3000 PNG composite is 50–150 ms of pure CPU and will happily block a php-fpm worker.

Cache by content hash, not by user. The poster identity is f(template_id, page, scene, template_version). Store hash as a column or the filename and skip regeneration when it matches. Bump template_version when marketing swaps the background so old posters invalidate cleanly.

Config-driven layout. Put layer geometry (x/y/w/h per template) in config or a DB table, not in code. Marketing adds templates far more often than you'd like, and the whole package is "composite N layers" — layer positions are data.

Always write through the filesystem abstraction. Wrap the package's save() in Storage::disk('public') (or COS/OSS). Poster URLs get shared into WeChat group chats and live for years; you will migrate off local disk.

Confine the facade to one class. A PosterService that calls MiniProgramPoster and nothing else makes the eventual replacement (see gotchas) a one-file change instead of a grep across the app.

Testing. Freeze a fixture background and QR, assert output dimensions and that a few pixels inside the QR slot differ from the background. Do not snapshot-compare image bytes — GD/Imagick version drift makes those flaky.

Gotchas and Tips

  • The package is stale. Last release 2019-02-18, zero dependents. Its illuminate/* constraints almost certainly cap out around Laravel 5.7/5.8. On Laravel 9+ you'll be fighting composer or forking. Given the code is a few hundred lines, copying it into app/Support/ and dropping the dependency is usually cheaper than patching the constraint — and you gain the ability to fix the remaining items below.
  • The QR must stay square and keep its quiet zone. Stretching with imagecopyresampled into a non-square slot, or cropping into the white border, produces a poster that looks perfect and won't scan. Crop/letterbox the background slot, never the QR. Most "WeChat can't scan it" tickets are this.
  • Transparency. A transparent PNG QR composited onto a JPEG background yields a black box. Composite onto a white-filled rectangle first, or use a PNG background.
  • Size budget. GD's default compression produces 1–3 MB PNGs. WeChat share images should stay well under ~200 KB. Convert to JPEG at quality ~85 unless you need alpha, and downscale the template if it was designed at 2x.
  • Fonts. Any text layer needs an absolute path to a real .ttf with read permission. imagettftext fails noisily on some builds and silently draws nothing on others. Ship the font inside your repo and reference it via resource_path().
  • Memory. Each loaded layer holds a full RGBA buffer — a 2000×3000 image is ~24 MB. Call ->destroy() on intermediates and keep memory_limit at 256M+.
  • GD fails quietly. Bad path, unreadable file, unsupported format — you get false or a PHP warning, not an exception. Wrap composition in try/finally and during development dump each intermediate layer to a temp dir so you can see which one is missing.
  • Concurrency. Two requests writing the same path produce a truncated PNG that WeChat then caches. Write to a temp file and rename() into place (atomic on the same filesystem), or gate with a cache lock.
  • QR expiry in the cache key. getUnlimited codes are permanent per scene, but if you're using a short-lived code variant the cached poster goes stale — include expiry in the hash.
  • Extension points are thin. Text, avatars, rounded corners, dynamic fonts — assume the package doesn't expose them. The pragmatic move is to let it do the background+QR composite and then chain Intervention\Image calls on the result yourself, or subclass the poster class and add your own layer methods.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource