PHPackages                             rcsofttech/php-image-guard - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Image &amp; Media](/categories/media)
4. /
5. rcsofttech/php-image-guard

ActiveLibrary[Image &amp; Media](/categories/media)

rcsofttech/php-image-guard
==========================

SSIM-based image quality verification with auto-retry compression loop for PHP 8.4+

v1.0.0(4mo ago)81↓95%MITPHPPHP ^8.4CI passing

Since Mar 31Pushed 4mo agoCompare

[ Source](https://github.com/rcsofttech85/php-image-guard)[ Packagist](https://packagist.org/packages/rcsofttech/php-image-guard)[ RSS](/packages/rcsofttech-php-image-guard/feed)WikiDiscussions main Synced 6d ago

READMEChangelogDependencies (3)Versions (2)Used By (0)

php-image-guard
===============

[](#php-image-guard)

[![PHP 8.4](https://camo.githubusercontent.com/d99323f769f72040b693c48a2dfaa9b767bae7f8dc307ac17c678e033fe4bdd8/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e342b2d626c75652e737667)](https://php.net)[![License: MIT](https://camo.githubusercontent.com/fdf2982b9f5d7489dcf44570e714e3a15fce6253e0cc6b5aa61a075aac2ff71b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d79656c6c6f772e737667)](LICENSE)[![PHPStan: Max](https://camo.githubusercontent.com/745eb989b9e4903dc598fe2cc63ed4226198be55b7c729001cbd1ece7676fef6/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048505374616e2d6d61782d627269676874677265656e2e737667)](phpstan.neon)[![Codacy Badge](https://camo.githubusercontent.com/a0221ab10cfef288ee4dca23e9ab761935218b92eb59c99e6ae153829816e38d/68747470733a2f2f6170702e636f646163792e636f6d2f70726f6a6563742f62616467652f47726164652f3534623033323931396539363435303161346436383166353631343235613632)](https://app.codacy.com/gh/rcsofttech85/php-image-guard/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)[![Codacy Badge](https://camo.githubusercontent.com/c8f260c257262f68db52608075fa3c94ad3a539f347b905a6cc00536fef7b1e5/68747470733a2f2f6170702e636f646163792e636f6d2f70726f6a6563742f62616467652f436f7665726167652f3534623033323931396539363435303161346436383166353631343235613632)](https://app.codacy.com/gh/rcsofttech85/php-image-guard/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_coverage)

> SSIM-based image quality verification with auto-retry compression loop for PHP 8.4+

This package does **ONE job**: guard image quality. It does not compress, resize, or upload images. It verifies that a compression result meets your quality threshold — and retries if not.

---

Requirements
------------

[](#requirements)

- PHP 8.4+
- `ext-gd` (required)
- `ext-imagick` (optional — enables higher-precision SSIM via float pixel data)

---

Installation
------------

[](#installation)

```
composer require rcsofttech/php-image-guard
```

Quick Start
-----------

[](#quick-start)

### Minimal — check one image

[](#minimal--check-one-image)

```
use RcSoftTech\ImageGuard\ImageGuard;

$gdImage = imagecreatefromjpeg('original.jpg');

$result = ImageGuard::check(
    'original.jpg',
    function (int $quality, string $originalPath) use ($gdImage): string {
        $out = "/tmp/compressed_q{$quality}.jpg";
        imagejpeg($gdImage, $out, $quality);
        return $out;
    }
);

echo $result->summary();
// "Passed (SSIM: 0.961, Quality: 75, Saved: 68%, 143ms)"
```

### Standalone SSIM score (no retry)

[](#standalone-ssim-score-no-retry)

```
$score = ImageGuard::compare('original.jpg', 'compressed.jpg');
// float e.g. 0.961423
```

---

Full Fluent API
---------------

[](#full-fluent-api)

```
use RcSoftTech\ImageGuard\Enums\OnFailBehavior;
use RcSoftTech\ImageGuard\ImageGuard;

$result = ImageGuard::original('original.jpg')
    ->compressWith($compressor)
    ->threshold(0.92)            // or: 'strict' | 'balanced' | 'loose'
    ->startAt(75)                // initial quality integer
    ->maxQuality(95)             // ceiling for retry loop
    ->step(5)                    // quality bump per retry
    ->onFail(OnFailBehavior::RECOMPRESS)
    ->run(ImageGuard::resolveCalculator());

if ($result->failed()) {
    logger()->warning('Image below threshold', $result->toArray());
}
```

### Quality Presets

[](#quality-presets)

StringSSIM Threshold`'strict'`0.97`'balanced'`0.92`'loose'`0.85Custom numeric thresholds are typically used in the `0.0` to `1.0` range.

### Failure Behaviors

[](#failure-behaviors)

`OnFailBehavior`Action`RECOMPRESS`Retry up to `maxQuality`, then accept best result`WARN`Return `passed=false` + add `$result->warnings``ABORT`Throw exception holding the full `PipelineResult`---

Batch API
---------

[](#batch-api)

```
$report = ImageGuard::batch(glob('uploads/*.jpg'))
    ->compressWith($compressor)
    ->threshold('balanced')
    ->onFail(OnFailBehavior::WARN)
    ->run(ImageGuard::resolveCalculator());

echo $report->totalSaved();  // "38.1 MB saved across 147 images"
echo $report->failRate();    // "3 of 147 failed (2.0%)"
echo $report->averageSsim(); // 0.941200

file_put_contents('audit.json', $report->toJson());
file_put_contents('audit.csv', $report->toCsv());
```

---

Compressor Examples
-------------------

[](#compressor-examples)

The compressor callable receives a `quality` integer and the `originalPath`string, and **must return the path to the compressed file**. This decouples `php-image-guard` from any specific tool.

### Plain GD

[](#plain-gd)

```
$compressor = function (int $quality, string $originalPath) use ($tmpDir): string
{
    $gdImage = imagecreatefromjpeg($originalPath);
    $output = "{$tmpDir}/compressed_q{$quality}.jpg";
    imagejpeg($gdImage, $output, $quality);
    imagedestroy($gdImage);
    return $output;
};
```

### With `spatie/image-optimizer`

[](#with-spatieimage-optimizer)

```
use Spatie\ImageOptimizer\OptimizerChain;
use Spatie\ImageOptimizer\Optimizers\Jpegoptim;

$compressor = function (int $quality, string $originalPath) use ($tmpDir): string
{
    $output = "{$tmpDir}/compressed_q{$quality}.jpg";
    copy($originalPath, $output);
    (new OptimizerChain)->addOptimizer(
        new Jpegoptim(['--max=' . $quality])
    )->optimize($output);
    return $output;
};
```

### With `intervention/image`

[](#with-interventionimage)

```
$compressor = function (
    int $quality,
    string $originalPath,
) use ($manager, $tmpDir): string {
    $output = "{$tmpDir}/compressed_q{$quality}.webp";
    $manager->read($originalPath)->toWebp($quality)->save($output);
    return $output;
};
```

---

PipelineResult Shape
--------------------

[](#pipelineresult-shape)

```
$result->passed          // bool
$result->ssimScore       // float e.g. 0.961423
$result->threshold       // float e.g. 0.92
$result->qualityUsed     // int — final quality used
$result->attempts        // int — number of retry attempts
$result->originalSize    // int — bytes
$result->compressedSize  // int — bytes
$result->savingsPercent  // float e.g. 68.4
$result->formatInput     // string e.g. 'jpeg'
$result->formatOutput    // string e.g. 'webp'
$result->durationMs      // int — total pipeline time
$result->outputPath      // string — path to accepted output
$result->warnings        // string[] — any warnings

$result->summary()       // "Passed (SSIM: 0.961, Quality: 75, Saved: 68%, 143ms)"
$result->savings()       // "68%"
$result->passed()        // bool
$result->failed()        // bool
$result->toArray()       // array
$result->toJson()        // JSON string
```

SSIM Accuracy
-------------

[](#ssim-accuracy)

These are practical expectations aligned with the current test suite and generated fixtures (not universal guarantees for every image set).

ScenarioExpectedIdentical imagesSSIM = 1.000000White vs blackSSIM &lt; 0.05JPEG quality 95SSIM &gt; 0.98JPEG quality 10SSIM &lt; 0.92PNG vs 50% WebP0.85–0.995---

License
-------

[](#license)

MIT — see [LICENSE](LICENSE).

###  Health Score

37

—

LowBetter than 81% of packages

Maintenance75

Regular maintenance activity

Popularity7

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity52

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

137d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/acf551384df4ef2ac01cd242fa6d3ffa5bbb9ce7a9d4c685923f27f9d38aa706?d=identicon)[rcsofttech85](/maintainers/rcsofttech85)

---

Top Contributors

[![rcsofttech85](https://avatars.githubusercontent.com/u/17738213?v=4)](https://github.com/rcsofttech85 "rcsofttech85 (1 commits)")

---

Tags

phpimagecompressionqualityverificationssim

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/rcsofttech-php-image-guard/health.svg)

```
[![Health](https://phpackages.com/badges/rcsofttech-php-image-guard/health.svg)](https://phpackages.com/packages/rcsofttech-php-image-guard)
```

###  Alternatives

[ps/image-optimizer

Image optimization / compression library. This library is able to optimize png, jpg and gif files in very easy and handy way. It uses optipng, pngquant, pngcrush, pngout, gifsicle, jpegoptim and jpegtran tools.

9161.7M25](/packages/ps-image-optimizer)[kinglozzer/tinypng

TinyPNG PHP API

1296.4k2](/packages/kinglozzer-tinypng)[schmitzal/tinyimg

Image compression for all pngs and jpgs uploaded to the backend (using the tinypng API)

16132.9k](/packages/schmitzal-tinyimg)[gtuk/image-optimizer

PHP image optimizer for png, jpeg and gif files. It uses mozjpeg, pngquant and gifsicle for the optimization process

161.6k](/packages/gtuk-image-optimizer)[lciolecki/php-image-optimizer

PHP image file optimizer (uses https://github.com/bensquire/php-image-optim)

347.4k](/packages/lciolecki-php-image-optimizer)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
