алгоритм — PHP генерирует RGB-цвет для объекта на основе уникального значения

Я знаю, что об этом уже спрашивали, но мне нужно немного больше помощи, чем другие ответы на SO.

В настоящее время у меня есть цикл foreach, который перебирает записи в моей БД. Каждая строка содержит уникальный первичный атрибут «id» (1,2,3,4,5 и т. Д.).

В моем цикле мне нужно сгенерировать уникальное значение RGB для каждой записи на основе ее идентификатора. Полученное значение RGB будет применено к тексту HTML-элемента, привязанного к этой записи. Сгенерированный цвет должен быть уникальным для самой записи (через «id»), поэтому я не использую итератор цикла.

Я уже создал работающую функцию, чтобы сделать это для меня, но мне нужно еще одно — мне нужно, чтобы значение rgb имело контрастность выше 4: 5: 1 на белом фоне. У меня есть функция, которая генерирует слишком яркие цвета, что затрудняет чтение текста. Как я могу изменить свою функцию, чтобы получить более темные цвета, которые хорошо контрастируют на белом фоне?

function makeRgbFromValue(int $value){
$hash = md5($value);

return implode(", ", [
hexdec(substr($hash, 0, 2)), // r
hexdec(substr($hash, 2, 2)), // g
hexdec(substr($hash, 4, 2))  // b
]);
}

// Example output: "100, 201, 20"
// My html, using Laravel Blade syntax:

@foreach($categories as $cat)
<a
href="/blog/channels/{{ $cat->slug }}"style="color: rgb(
{{ makeRgbFromValue($cat->id) }}
)">
{{ $cat->name }}
</a>
@endforeach

Может быть, это невозможно … но я надеюсь, что один из вас, математические гении, может мне помочь 🙂

0

Решение

Вы можете рассчитать яркость:

function lumdiff($R1,$G1,$B1,$R2,$G2,$B2){
$L1 = 0.2126 * pow($R1/255, 2.2) +
0.7152 * pow($G1/255, 2.2) +
0.0722 * pow($B1/255, 2.2);

$L2 = 0.2126 * pow($R2/255, 2.2) +
0.7152 * pow($G2/255, 2.2) +
0.0722 * pow($B2/255, 2.2);

if($L1 > $L2){
return ($L1+0.05) / ($L2+0.05);
}else{
return ($L2+0.05) / ($L1+0.05);
}
}

Возвращаемое значение должно быть больше 5 для лучшей читаемости.
Функция найдена Вот

Но вы должны получить еще один символ из хеша, чтобы получить другой цвет, так что столкновение более вероятно.

function makeRgbFromValue($value){
$hash = md5($value);
$brightness = 0;
$shift = 0;

while($brightness < 5 && $shift<26) {
$color = [
hexdec(substr($hash, $shift, 2)), // r
hexdec(substr($hash, $shift+2, 2)), // g
hexdec(substr($hash, $shift+4, 2))  // b
];
$brightness = lumdiff($color[0], $color[1], $color[2], 255,255,255);
$shift++;
}

return implode(", ", $color);
}

Я считаю, что цвет будет найден в 25 циклах 🙂

0

Другие решения

Несмотря на то, что переводить это сложно, вероятно, для этого лучше использовать цветовое пространство. Мне нравится выбирать набор Насыщенность [0.75 хорошо], а затем играть с оттенком и значением.

Отмена функции преобразования HSV / RGB из этот смысл:

function HSV_TO_RGB ($H, $S, $V) {
$RGB = array();
if($S == 0) {
$R = $G = $B = $V * 255;
} else {
$var_H = $H * 6;
$var_i = floor( $var_H );
$var_1 = $V * ( 1 - $S );
$var_2 = $V * ( 1 - $S * ( $var_H - $var_i ) );
$var_3 = $V * ( 1 - $S * (1 - ( $var_H - $var_i ) ) );
if       ($var_i == 0) { $var_R = $V     ; $var_G = $var_3  ; $var_B = $var_1 ; }
else if  ($var_i == 1) { $var_R = $var_2 ; $var_G = $V      ; $var_B = $var_1 ; }
else if  ($var_i == 2) { $var_R = $var_1 ; $var_G = $V      ; $var_B = $var_3 ; }
else if  ($var_i == 3) { $var_R = $var_1 ; $var_G = $var_2  ; $var_B = $V     ; }
else if  ($var_i == 4) { $var_R = $var_3 ; $var_G = $var_1  ; $var_B = $V     ; }
else                   { $var_R = $V     ; $var_G = $var_1  ; $var_B = $var_2 ; }
$R = $var_R * 255;
$G = $var_G * 255;
$B = $var_B * 255;
}
$RGB['R'] = $R;
$RGB['G'] = $G;
$RGB['B'] = $B;
return $RGB;
}

А потом:

$fmt = '<span style="background-color: #%s" title="%s">%s</span>' . "\n";
$fill = str_repeat('&nbsp;', 5);

$S = 0.75;
for($i=0; $i<25; $i++) {
$hash = md5(mt_rand());
$H =   hexdec(substr($hash, 0, 2))/255;
$V = ( hexdec(substr($hash, 2, 2))/255 ) / 2 + 0.5; // pick from the brighter half
$rgb = implode('', array_map(
function($a){
return str_pad(dechex(intval($a)), 2, '0', STR_PAD_LEFT);
}, HSV_TO_RGB($H, $S, $V)));
printf($fmt, $rgb, sprintf("HSV(%0.2f,%0.2f,%0.2f)", $H, $S, $V), $fill);
}

Дает нам что-то вроде:

уй цветные коробки!

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector