<?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 проблем нет.
Прямой обход по пикселям по скорости не подходит. Какие ещё подходы попробовать?