This post was updated 675 days ago and some of the ideas may be out of date.
代码
<?php
/**
* Created by PhpStorm.
* User: LinFei
* Created time 2023/02/22 22:55:11
* E-mail: fly@eyabc.cn
*/
declare (strict_types=1);
class ImageColorAnalyzer
{
/**
* 获取图片的主色调 | Get the main color of the image
* @param string $imagePath 图片路径或URL | Image path or URL
* @return array
*/
public static function getThemeColor(string $imagePath): array
{
// 创建 GD 图像对象
$image = @imagecreatefromstring(static::getImageData($imagePath));
if (!$image) {
throw new InvalidArgumentException('Invalid image path or URL');
}
// 缩放图像
$scaledImage = imagescale($image, 1, 1);
// 获取所有像素的颜色
$colorIndex = imagecolorat($scaledImage, 0, 0);
$colorComponents = imagecolorsforindex($scaledImage, $colorIndex);
// 创建颜色数组
$colorArray = [
[$colorComponents['red'], $colorComponents['green'], $colorComponents['blue']]
];
// 聚类分析颜色
$colorClusters = [];
foreach ($colorArray as $color) {
$closestCluster = null;
$closestDistance = null;
foreach ($colorClusters as $i => $cluster) {
$distance = static::calculateColorDistance($color, $cluster);
if ($closestDistance === null || $distance < $closestDistance) {
$closestDistance = $distance;
$closestCluster = $i;
}
}
if ($closestDistance < 50) {
$colorClusters[$closestCluster][] = $color;
} else {
$colorClusters[] = [$color];
}
}
// 找到最常见的颜色
$mostFrequentCluster = null;
$mostFrequentCount = null;
foreach ($colorClusters as $cluster) {
$count = count($cluster);
if ($mostFrequentCount === null || $count > $mostFrequentCount) {
$mostFrequentCount = $count;
$mostFrequentCluster = $cluster;
}
}
// 十六进制颜色代码
$hexColor = sprintf("#%02x%02x%02x", $mostFrequentCluster[0][0], $mostFrequentCluster[0][1], $mostFrequentCluster[0][2]);
return [
'hex' => $hexColor,
'rgb' => $mostFrequentCluster[0]
];
}
/**
* 计算两个颜色之间的距离 | Calculate the distance between two colors
* @param array $color1 颜色1 | Color 1
* @param array $color2 颜色2 | Color 2
* @return float
*/
private static function calculateColorDistance(array $color1, array $color2): float
{
$redMean = ($color1[0] + $color2[0]) / 2;
$redDiff = $color1[0] - $color2[0];
$greenDiff = $color1[1] - $color2[1];
$blueDiff = $color1[2] - $color2[2];
return sqrt((2 + $redMean / 256) * ($redDiff ** 2) + 4 * ($greenDiff ** 2) + (2 + (255 - $redMean) / 256) * ($blueDiff ** 2));
}
/**
* 获取图片数据 | Get image data
* @param string $path
* @return string
*/
private static function getImageData(string $path): string
{
return (string)file_get_contents($path);
}
}
调用
$color = ImageColorAnalyzer::getThemeColor('https://img.eyabc.cn/images/2023/02/15/j501zo.jpg');
var_dump($color);
// array(2) {
// ["hex"]=>
// string(7) "#ccd1d4"
// ["rgb"]=>
// array(3) {
// [0]=>
// int(204)
// [1]=>
// int(209)
// [2]=>
// int(212)
// }
// }
参与讨论