maestroerror/php-heic-to-jpg
Convert HEIC images to JPG in PHP with this lightweight wrapper around libheif. Handles iPhone photos and other HEIC files, with options to control quality and output, making it easy to generate web-friendly JPEGs from Apple's default image format.
composer require maestroerror/php-heic-to-jpg — pin ^1.0.8 so you pick up the corrected default heif-converter binary path.Maestroerror\HeicToJpg), so you just use the class in a controller, job, or action. If you want it injectable/mockable, wrap it in your own thin service.use Maestroerror\HeicToJpg;
$path = $request->file('photo')->getRealPath();
$jpg = HeicToJpg::convert($path)->saveAs(
storage_path('app/public/photos/'.Str::uuid().'.jpg')
);
HeicToJpg::isHeic($path). iOS falls back to JPEG when the user has "Most Compatible" enabled, and Android uploads can be anything. Branch on detection rather than on the file extension.->get() returns the JPEG as a binary string — use it for S3/streamed responses where you don't want an intermediate file. ->saveAs($path) writes to the local filesystem only; for object storage, convert to a temp path (or use get()), then Storage::disk('s3')->put(...).heic/heif are not in Laravel's default mime guessing for mimes: in all versions. Validate with an explicit rule (mimes:heic,heif,jpg,jpeg) plus a getimagesize/signature check, and never trust the client-supplied extension.pending state until the derivative exists. Set generous $timeout — 48MP HEICs are slow.Photo model with an observer or ProcessPhoto job keeps this tidy.try/catch; one corrupt HEIC should not abort the whole batch.getimagesize($output)['mime'] === 'image/jpeg'. For unit tests of your own code, put the package behind an interface so you can fake it — the static API is otherwise hard to stub.heif-converter binary path; on versions below it you can get "converter not found"-style failures out of the box. On Docker/Alpine/Forge, confirm with which heif-converter and, if the default is wrong for your image, override it with the package's converter-path setter.+x after a deploy or a vendor cache restore. Add a chmod +x in your deploy script and re-check after every deploy.proc_open/exec disabled on shared hosting kills the package at runtime with a confusing error. Fail fast in a health check./tmp (tmpfs with low size limits) will bite you on large uploads.App\Support\HeicConverter so the rest of the codebase isn't coupled to a static API, and so a future swap (Imagick with HEIC support, a hosted service) is a one-file change.^1.0.8 is the minimum you want.How can I help you explore Laravel packages today?