$avg ? $hist[$j] : 0; } $score = \array_sum($hist); if ($bestScore < $score) { $bestScore = $score; $bestDegree = $i; } } $im = \imagerotate($im, $bestDegree, 1); if ($im == false) { return; } if (\strripos($outPath, 'png') !== false) { \imagepng($im, $outPath); } elseif (\strripos($outPath, 'jpg') !== false || \strripos($outPath, 'jpeg') !== false) { \imagejpeg($im, $outPath); } else { \imagegif($im, $outPath); } \imagedestroy($im); } /** * Rotate the pixel matrix by a certain degree * * @param array $pixel Pixel matrix (0 index = y, 1 index = x) * @param array $dim Matrix dimension (0 index = y, 1 index = x) * @param int $deg Degree to rotate * * @return array * * @since 1.0.0 */ public static function rotatePixelMatrix(array $pixel, array $dim, int $deg) : array { $rad = \deg2rad($deg); $sin = \sin(-$rad); $cos = \cos(-$rad); $rotated = [[]]; for ($i = 0; $i < $dim[0]; ++$i) { $cY = $i - $dim[0] / 2.0; // center for ($j = 0; $j < $dim[1]; ++$j) { $cX = $j - $dim[1] / 2.0; // center $x = $cos * $cX + $sin * $cY + $dim[1] / 2.0; $y = -$sin * $cX + $cos * $cY + $dim[0] / 2.0; $rotated[$i][$j] = self::getNearestValue($pixel, $dim, $x, $y); } } return $rotated; } /** * Find the closes pixel based on floating points * * @param array $pixel Pixel matrix (0 index = y, 1 index = x) * @param array $dim Matrix dimension (0 index = y, 1 index = x) * @param float $x X coordinate * @param float $y Y coordinate * * @return int * * @since 1.0.0 */ private static function getNearestValue(array $pixel, array $dim, float $x, float $y) : int { $xLow = \min((int) $x, $dim[1] - 1); $xHigh = \min((int) \ceil($x), $dim[1] - 1); $yLow = \min((int) $y, $dim[0] - 1); $yHigh = \min((int) \ceil($y), $dim[0] - 1); $points = [ [$xLow, $yLow], [$xLow, $yHigh], [$xHigh, $yLow], [$xHigh, $yHigh], ]; $minDistance = \PHP_FLOAT_MAX; $minValue = 0; foreach ($points as $point) { $distance = ($point[0] - $x) * ($point[0] - $x) + ($point[1] - $y) * ($point[1] - $y); if ($distance < $minDistance) { $minDistance = $distance; $minValue = $point[0] >= 0 && $point[0] < $dim[0] && $point[1] >= 0 && $point[1] < $dim[1] ? $pixel[$point[1]][$point[0]] : 0; } } return $minValue; } }