• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

tito10047 / progressive-image-bundle / 20688684442

04 Jan 2026 06:11AM UTC coverage: 88.746%. Remained the same
20688684442

push

github

tito10047
update comments and exception messages: standardize English terminology in comments, exceptions, and test outputs across all source files and tests

0 of 5 new or added lines in 3 files covered. (0.0%)

623 of 702 relevant lines covered (88.75%)

185.41 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

90.91
/src/Analyzer/GdImageAnalyzer.php
1
<?php
2

3
/*
4
 * This file is part of the Progressive Image Bundle.
5
 *
6
 * (c) Jozef Môstka <https://github.com/tito10047/progressive-image-bundle>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11

12
namespace Tito10047\ProgressiveImageBundle\Analyzer;
13

14
use kornrunner\Blurhash\Blurhash;
15
use Tito10047\ProgressiveImageBundle\DTO\ImageMetadata;
16
use Tito10047\ProgressiveImageBundle\Exception\ImageProcessingException;
17
use Tito10047\ProgressiveImageBundle\Loader\LoaderInterface;
18

19
final class GdImageAnalyzer implements ImageAnalyzerInterface
20
{
21
    public function __construct(
22
        private readonly int $componentsX = 4,
23
        private readonly int $componentsY = 3,
24
    ) {
25
    }
350✔
26

27
    public function analyze(LoaderInterface $loader, string $path): ImageMetadata
28
    {
29
        $stream = $loader->load($path);
168✔
30
        $data = stream_get_contents($stream);
168✔
31

32
        if (false === $data) {
168✔
NEW
33
                        throw new ImageProcessingException('Failed to load data from loader for path: ' . $path);
×
34
        }
35

36
        $image = @imagecreatefromstring($data);
168✔
37
        if (false === $image) {
168✔
NEW
38
                        throw new ImageProcessingException('GD could not load image from data for path: ' . $path);
×
39
        }
40

41
        $width = imagesx($image);
168✔
42
        $height = imagesy($image);
168✔
43

44
                // Downscale to max 64x64 for Blurhash (preserving aspect ratio)
45
        $targetWidth = 64;
168✔
46
        $targetHeight = 64;
168✔
47

48
        if ($width > $height) {
168✔
49
            $targetHeight = (int) ($height * (64 / $width));
×
50
        } else {
51
            $targetWidth = (int) ($width * (64 / $height));
168✔
52
        }
53

54
        $resizedImage = imagecreatetruecolor($targetWidth, $targetHeight);
168✔
55
        imagecopyresampled($resizedImage, $image, 0, 0, 0, 0, $targetWidth, $targetHeight, $width, $height);
168✔
56

57
        $pixels = [];
168✔
58
        for ($y = 0; $y < $targetHeight; ++$y) {
168✔
59
            $row = [];
168✔
60
            for ($x = 0; $x < $targetWidth; ++$x) {
168✔
61
                $rgb = imagecolorat($resizedImage, $x, $y);
168✔
62
                $r = ($rgb >> 16) & 0xFF;
168✔
63
                $g = ($rgb >> 8) & 0xFF;
168✔
64
                $b = $rgb & 0xFF;
168✔
65
                $row[] = [$r, $g, $b];
168✔
66
            }
67
            $pixels[] = $row;
168✔
68
        }
69

70
        $hash = Blurhash::encode($pixels, $this->componentsX, $this->componentsY);
168✔
71

72
        return new ImageMetadata(
168✔
73
            $hash,
168✔
74
            $width,
168✔
75
            $height
168✔
76
        );
168✔
77
    }
78
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc