计算颜色混合值

<?php
declare(strict_types=1);
ini_set('display_errors', 'On');
ini_set('error_reporting', E_ALL);

/**
 * 计算两种颜色混合后的值
 *
 * @param array $colorInfo1 颜色1信息,示例:['#07c160', 1.0]
 * @param array $colorInfo2 颜色2信息,示例:['#ffffff', 0.1]
 * @return string 混合后的16进制颜色值,示例:#20c770
 */
function color_mix(array $colorInfo1, array $colorInfo2): string
{
    // 解构颜色信息
    [$color1, $opacity1] = $colorInfo1;
    [$color2, $opacity2] = $colorInfo2;

    /**
     * 将颜色从16进制转换为RGB
     *
     * @param string $color 颜色的16进制值,示例:#07c160
     * @return array 颜色的RGB     */
    $hexToRgb = static function (string $color): array {
        $color = ltrim($color, '#'); // 去掉左侧的#符号(如果有的话)

        // 处理颜色简写格式,例如将#fff转换为#ffffff
        if (strlen($color) === 3) {
            $color = $color[0] . $color[0] . $color[1] . $color[1] . $color[2] . $color[2];
        }

        // 将颜色从16进制转换为RGB
        return [
            hexdec(substr($color, 0, 2)),
            hexdec(substr($color, 2, 2)),
            hexdec(substr($color, 4, 2))
        ];
    };

    /**
     * 混合颜色
     *
     * @param array $background 背景色
     * @param array $rgb 前景色
     * @param float $opacity 不透明度
     * @return array 混合后的RGB     */
    $mix = static function (array $background, array $rgb, float $opacity): array {
        return [
            round($background[0] * (1 - $opacity) + $rgb[0] * $opacity),
            round($background[1] * (1 - $opacity) + $rgb[1] * $opacity),
            round($background[2] * (1 - $opacity) + $rgb[2] * $opacity)
        ];
    };

    // 将颜色转换为RGB
    $rgb1 = $hexToRgb($color1);
    $rgb2 = $hexToRgb($color2);

    // 假设背景色为白色
    $background = [255, 255, 255];

    // 背景色本身就是一种颜色,所以需要先将颜色1盖在背景色上
    $mixed1 = $mix($background, $rgb1, $opacity1);

    // 再盖上颜色2得到最终颜色的RGB    $mixed2 = $mix($mixed1, $rgb2, $opacity2);

    // RGB值转回16进制
    return sprintf('#%02x%02x%02x', $mixed2[0], $mixed2[1], $mixed2[2]);
}

$color1 = ['#07c160', 1.0];
$color2 = ['#ffffff', 0.1];
echo color_mix($color1, $color2); // #20c770

Copyright © 2025 码农人生. All Rights Reserved