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

Gif Frame Extractor Laravel Package

sybio/gif-frame-extractor

PHP library to extract and split frames from animated GIFs. Read frame durations, colors, dimensions and disposal methods without Imagick, then export frames as separate GIF, JPEG or PNG images for thumbnails, previews or processing.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

  • Framework-agnostic PHP library, not a Laravel package — no service provider, config, facade, or publishable assets. It lands in vendor/ as a single-purpose class (GifFrameExtractor\GifFrameExtractor) plus an exception type.
  • Fits cleanly as an infrastructure adapter behind an application-level interface (e.g. GifFrameExtractorService), keeping the vendor class out of controllers and jobs. This is the only sane boundary given the library is unmaintained and we may want to swap it later.
  • Hard runtime dependency on the Imagick extension (and by extension ImageMagick delegates for GIF). This is an extension-level constraint on our runtime image, not a Composer-only constraint, and it is the single biggest architectural decision point.
  • Stateless, synchronous, in-process. Every extraction is an in-request operation unless we explicitly wrap it in a queue job — there is no async or streaming API.

Integration feasibility

  • Trivial to install (composer require sybio/gif-frame-extractor) and trivial to call: extract(), isAnimated(), getFrames(), getFrameDuration(), getTotalDuration(), saveFrames(). Integration effort is measured in hours, not sprints.
  • The real work is not the library call — it's the surrounding guardrails: upload validation, pixel-dimension caps, job timeouts, storage layout, and cache invalidation for derived frames.

Technical risk

  • Unmaintained upstream. 178 stars, 0 dependents on Packagist, and the last meaningful activity is years old. Treat it as vendored code we own, not a supported dependency.
  • PHP 8 compatibility unverified. The codebase is PHP 5.3-era. Expect potential deprecation notices or breakage on 8.1+; must be validated against our exact PHP minor version before commitment.
  • Memory and CPU blowup. ImageMagick coalesces optimized GIFs into full frames in memory; a modest download can expand into hundreds of MB. OOM in PHP is a fatal, uncatchable error — this is a process-killer, not an exception.
  • Decompression-bomb surface. User-supplied GIFs are attacker-controlled input. Without pixel-count and frame-count limits enforced before decode, this is a DoS vector.
  • Imagick CVE exposure. ImageMagick delegates have a long CVE history. We inherit that risk plus the responsibility for patching the base image.
  • Transparency and disposal-method edge cases. Frame compositing for optimized GIFs is handled by Imagick's coalescing, but transparency edge cases exist and frame durations are centisecond-quantized (10ms floor) — accuracy claims must be tested, not assumed.

Key questions

  1. Does it run clean on our target PHP version (7.4 / 8.1 / 8.2)? Any deprecation noise under E_ALL?
  2. What is peak RSS for our realistic worst-case asset (size × dimensions × frame count)? At what threshold do we reject?
  3. Is the license (MIT-style) compatible with our distribution model? Confirm from LICENSE, not the README.
  4. Does isAnimated() correctly reject non-GIF and single-frame GIFs before we do expensive work?
  5. Do we actually need frame extraction, or only frame count and duration (cheaper metadata path)?
  6. What is the fallback if Imagick is unavailable in a target environment (shared hosting, restricted PaaS)?

Integration Approach

Stack fit

  • Sits in the media-processing layer alongside existing image handling. Natural home: a queued job (ExtractGifFrames) dispatched from the upload/ingest flow, writing to a configured filesystem disk via Laravel's Storage facade.
  • Wrap in a thin service class + optional facade; bind via a service provider so the concrete implementation is swappable. Do not let the vendor class leak into domain code.
  • Config surface we should own: max upload bytes, max pixel dimensions, max frame count, target disk, output format (PNG/JPEG/WebP), and a feature flag to disable extraction entirely.

Migration path

  • Greenfield if this is new capability: no existing data to migrate, only a new derived-asset table/bucket prefix.
  • If replacing an existing path (GD-based, FFmpeg, gifsicle CLI), run both in shadow mode on a sample corpus and diff frame counts, durations, and perceptual output before cutover.
  • Because dependents are zero, there is no ecosystem to conform to — we define the contract, which also means we absorb 100% of the maintenance.

Compatibility

  • Runtime image must include php-imagick and ImageMagick with GIF delegate support. Pin both versions in the Dockerfile; do not float latest.
  • Local/dev parity is the common failure: developers without Imagick installed will hit a fatal error. Add a preflight check (health endpoint or artisan command) that fails loudly at boot, not at first upload.
  • Pin the Composer constraint exactly (1.2.* or a commit hash). Given abandonment, consider committing a fork to a private VCS rather than relying on Packagist availability.

Sequencing

  1. Spike (1–2 days): install, verify PHP version compatibility, measure peak memory and wall time on 5–10 representative GIFs including worst case.
  2. Guardrails: implement pre-decode validation — MIME sniffing, byte cap, pixel cap, frame-count cap.
  3. Service layer: wrap the library, define the interface, add the boot-time Imagick preflight.
  4. Async pipeline: move all extraction into queue jobs with explicit timeout and memory_limit per worker; never extract in a web request.
  5. Storage + caching: persist frames to object storage, keyed by asset hash, so re-extraction never repeats.
  6. Observability: emit metrics for extraction duration, output frame count, and rejected assets; alert on OOM-restart rate.
  7. Reassess: if volume or asset size grows, evaluate replacing the library with direct Imagick coalescing or an out-of-process gifsicle/FFmpeg worker.

Operational Impact

Maintenance

  • Low code churn, high ownership. Upstream is effectively frozen: no security advisories, no PHP-version bumps, no bug triage. Budget a standing line item for "vendor fork maintenance" — realistically a few days per year plus reactive work when PHP or ImageMagick upgrades land.
  • Pin the version and vendor the source into our repo (or a private mirror) to insulate against Packagist deletion or a silent force-push.
  • Primary maintenance burden is not the PHP code — it's tracking ImageMagick/Imagick security releases in the base image.

Support

  • No vendor, no SLA, no security contact. Internal self-support only. Anyone on-call for the media pipeline must be able to read the class and reason about Imagick behavior.
  • Community is small (178 stars, 0 dependents) — issue searches will rarely help. Document our own runbook.
  • Document the two failure signatures explicitly: missing extension (fatal at construct) and OOM (fatal at decode). Both bypass normal exception handling.

Scaling

  • Scales horizontally with worker count, linearly with cost per extraction. Imagick is CPU-bound and memory-hungry; per-frame extraction of a 200-frame GIF is seconds of CPU, not milliseconds.
  • Isolate extraction onto a dedicated queue with its own worker pool and higher memory_limit, so a GIF bomb cannot starve the default queue.
  • Output volume is the sneaky scaling cost: a single 150-frame GIF produces 150 stored objects. Apply retention policies and derive-on-demand where the product allows.
  • Cache aggressively by content hash; the same asset should never be processed twice.

Failure modes

  • OOM during coalesce — fatal, uncatchable, kills the worker mid-job. Mitigation: pixel/frame caps pre-decode, queue retry_after > timeout, worker supervisor restart.
  • Imagick extension absent — fatal on instantiation. Mitigation: boot-time preflight, CI image build assertion.
  • Corrupt or truncated GIF — throws GifFrameExtractorException; recoverable if wrapped. Mitigation: catch, mark asset unprocessable, surface to the user.
  • Silent partial extraction — fewer frames returned than the source contains; no exception raised. Mitigation: compare extracted count against GIF logical screen/frame count from a lightweight header read.
  • Duration drift — centisecond quantization means totals can be off by up to 10ms/frame; unacceptable if durations drive billing or sync. Mitigation: verify tolerance against product requirements before shipping.
  • Queue timeout — long-running extractions exceed job timeout, get retried, and duplicate work. Mitigation: idempotent writes keyed by hash, plus a per-asset "in progress" lock.

Ramp-up

  • Engineer ramp-up on the library: under a day. The API is a handful of getters and one extract() call; there is nothing to architect around.
  • The real ramp is Imagick and animated-GIF semantics — coalescing, disposal methods, frame delays, transparency, memory behavior. Assume 2–3 days for an engineer unfamiliar with it to reach confident production ownership.
  • Organizational ramp is near zero: no new service to operate, no new language, no new platform. One Dockerfile line and one queue worker config.
  • Net read for a TPM: cheap to adopt, cheap to run, expensive to be surprised by. The library is a 200-line convenience wrapper we could reproduce in half a day; the value is speed of start, and the cost is inherited abandonment plus an extension-level dependency we must govern ourselves. Appropriate for an internal, low-volume, queued media pipeline with hard input caps — inappropriate anywhere Imagick is unavailable or where untrusted GIFs arrive at scale without guardrails.
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.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums