@ZelenovM

Как сделать проверку что в изображении нет пикселей с цветом ярче чем #eeeeee?

<?php

use Exception;
use Imagick;


abstract class NoBrightPixelsChecker
{
    protected string $imagePath;
    protected string $thresholdColor;
    protected Imagick $imagick;

    /**
     * @throws Exception
     */
    public function __construct(string $imagePath, string $thresholdColor = '#eeeeee')
    {
        $this->imagePath = $imagePath;
        $this->thresholdColor = $thresholdColor;
        $this->loadImage();
    }

    /**
     * @throws Exception
     */
    private function loadImage(): void
    {
        try {
            $this->imagick = new Imagick($this->imagePath);
        } catch (Exception $e) {
            throw new Exception('Failed to load image: ' . $e->getMessage());
        }
    }

    abstract public function checkImage(): bool;
}

<?php



use Imagick;

class PixelStatisticsNoBrightPixelsChecker extends NoBrightPixelsChecker
{
    /**
     * @throws \ImagickException
     */
    public function checkImage(): bool
    {
   
        // Get image channel statistics
        $statistics = $this->imagick->getImageChannelStatistics();


        // Convert quantum range to 255
        $quantumRange = $this->imagick->getQuantumRange();
        $maxQuantum = $quantumRange['quantumRangeLong'];

        // Get maximum brightness for each channel
        $rMaxBrightness = $statistics[Imagick::CHANNEL_RED]['maxima'] / $maxQuantum * 255;
        $gMaxBrightness = $statistics[Imagick::CHANNEL_GREEN]['maxima'] / $maxQuantum * 255;
        $bMaxBrightness = $statistics[Imagick::CHANNEL_BLUE]['maxima'] / $maxQuantum * 255;

        list($rThreshold, $gThreshold, $bThreshold) = sscanf($this->thresholdColor, "#%02x%02x%02x");

        echo $rThreshold.PHP_EOL;
        echo $gThreshold.PHP_EOL;
        echo $bThreshold.PHP_EOL;

        echo $rMaxBrightness.PHP_EOL;
        echo $gMaxBrightness.PHP_EOL;
        echo $bMaxBrightness.PHP_EOL;

        if ($rMaxBrightness > $rThreshold && $gMaxBrightness > $gThreshold && $bMaxBrightness > $bThreshold) {
            return false;
        }
        return true;
    }

}



<?php

use Imagick;


class ResizedImageNoBrightPixelsChecker extends NoBrightPixelsChecker
{
    private int $sampleSize;

    public function __construct(string $imagePath, string $thresholdColor = '#eeeeee', int $sampleSize = 100)
    {
        parent::__construct($imagePath, $thresholdColor);
        $this->sampleSize = $sampleSize;
    }

    /**
     * @throws \ImagickException
     * @throws \ImagickPixelException
     */
    public function checkImage(): bool
    {
        list($rThreshold, $gThreshold, $bThreshold) = sscanf($this->thresholdColor, "#%02x%02x%02x");

   


        $maxR = 0;
        $maxG = 0;
        $maxB = 0;

        $count = 0;

        for ($y = 0; $y < $this->imagick->getImageHeight(); $y++) {
            for ($x = 0; $x < $this->imagick->getImageWidth(); $x++) {
                $pixel = $this->imagick->getImagePixelColor($x, $y);
                $color = $pixel->getColor();
                $alpha = $color['a'] / 255.0;

                // Ignore fully transparent pixels
                if ($alpha == 0) {
                    continue;
                }
                

                if ($color['r'] > $rThreshold and $color['g'] > $gThreshold and $color['b'] > $bThreshold) {
                    $count++;
                }
            }
        }

        echo $count.PHP_EOL;

        return $count ==- 0;
    }
}


Класс проверяющий цвет по статистике, в целом работает, но на изображениях с яркостью -6 (делаю через замену цвета в фотошопе с разбросом в 200 от белого) он находит 255 255 255, хотя попиксельный проход их не находит. На изображениях с яркостью -11 проблем нет.
Прямой обход по пикселям по скорости не подходит. Какие ещё подходы попробовать?
  • Вопрос задан
  • 101 просмотр
Пригласить эксперта
Ответы на вопрос 1
@maksam07
Попробуй:

<?php

use Exception;
use Imagick;

abstract class NoBrightPixelsChecker
{
    protected string $imagePath;
    protected string $thresholdColor;
    protected Imagick $imagick;

    public function __construct(string $imagePath, string $thresholdColor = '#eeeeee')
    {
        $this->imagePath = $imagePath;
        $this->thresholdColor = $thresholdColor;
        $this->loadImage();
    }

    private function loadImage(): void
    {
        try {
            $this->imagick = new Imagick($this->imagePath);
        } catch (Exception $e) {
            throw new Exception('Failed to load image: ' . $e->getMessage());
        }
    }

    abstract public function checkImage(): bool;
}

class ThresholdMaskNoBrightPixelsChecker extends NoBrightPixelsChecker
{
    public function checkImage(): bool
    {
        list($rThreshold, $gThreshold, $bThreshold) = sscanf($this->thresholdColor, "#%02x%02x%02x");

        $imageClone = clone $this->imagick;
        $thresholdColor = new ImagickPixel("rgb($rThreshold, $gThreshold, $bThreshold)");
        $imageClone->thresholdImage($thresholdColor);
        $histogram = $imageClone->getImageHistogram();

        $whitePixelCount = 0;
        foreach ($histogram as $pixel) {
            $color = $pixel->getColor();
            if ($color['r'] == 255 && $color['g'] == 255 && $color['b'] == 255) {
                $whitePixelCount += $pixel->getColorCount();
            }
        }

        return $whitePixelCount === 0;
    }
}

// Пример использования
try {
    $checker = new ThresholdMaskNoBrightPixelsChecker('path/to/your/image.jpg');
    $result = $checker->checkImage();
    echo $result ? 'No bright pixels found' : 'Bright pixels found';
} catch (Exception $e) {
    echo 'Error: ' . $e->getMessage();
}
?>
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы