分类 算法 下的文章

九宫格切割以及加文字方法

!defined('BASE_PATH') && define('BASE_PATH', dirname(__DIR__, 1));
define('CACHE_PATH', BASE_PATH . '/runtime/cache');
define('RESOURCE_PATH', BASE_PATH . '/resource');

// 九宫格切图且添加文字
imageSlicing9($imgPath, $fonts = [], $fontPath = null)
{
    list($width, $height) = getimagesize($imgPath);
    $source = imagecreatefromjpeg($imgPath);

    $width = $width - $width % 3;
    $height = $height - $height % 3;

    $baseWidth = $width / 3;
    $baseHeight = $height / 3;;

    $imgPathMd5 = md5($imgPath);
    $results = [];
    foreach ([
                 [0, 0],
                 [$baseWidth, 0],
                 [$baseWidth * 2, 0],

                 [0, $baseHeight],
                 [$baseWidth, $baseHeight],
                 [$baseWidth * 2, $baseHeight],

                 [0, $baseHeight * 2],
                 [$baseWidth, $baseHeight * 2],
                 [$baseWidth * 2, $baseHeight * 2],
             ] as $key => $item) {
        $thumb = ImageCreateTrueColor($baseWidth, $baseHeight);
        imagecopyresized($thumb, $source, 0, 0, $item[0], $item[1], $baseWidth, $baseHeight, $baseWidth, $baseHeight);

        if (!empty($fonts[$key])) {

            $fontCount = mb_strlen($fonts[$key], 'utf-8');
            $black = imagecolorallocate($thumb, 0, 0, 0);//字体颜色 RGB
            $fontSize = 12;   //字体大小

            $circleSize = 0; //旋转角度
            $left = 5;
            $right = 5;
            $fonttIndex = 0;
            $fontList = [];
            $fonttRowWidth = $baseWidth - $left - $right;
            $fontList[$fonttIndex] = '';
            $fontListWidth[$fonttIndex] = 0;
            $fonttHeight = $fontSize;
            for ($iii = 0; $iii < $fontCount; $iii++) {
                $fontt = mb_substr($fonts[$key], $iii, 1, 'utf-8');
                $pos = imagettfbbox($fontSize, 0, $fontPath, $fontt);
                $fonttWidth = $pos[2] - $pos[0];
                $fonttHeight = $pos[3] - $pos[5];
                // 计算剩余宽度, 如果够, 那么就挤进去, 否则下一排
                if (($fonttRowWidth = $fonttRowWidth - $fonttWidth) > 0) {
                    $fontList[$fonttIndex] .= $fontt;
                    $fontListWidth[$fonttIndex] += $fonttWidth;
                } else {
                    $fonttRowWidth = $baseWidth - $left - $right - $fonttWidth;
                    $fonttIndex++;
                    $fontList[$fonttIndex] = $fontt;
                    $fontListWidth[$fonttIndex] = $fonttWidth;
                }
            }
            $top = $baseHeight - ($fonttHeight + 5) * count($fontList) + 5;
            if ($top < 0) {
                $top = 10;
            }
            if (count($fontList) == 1) {
                $left = intval(($baseWidth - $fontListWidth[0]) / 2);
            }
            foreach ($fontList as $fontvalue) {
                imagefttext($thumb, $fontSize, $circleSize, $left, $top, $black, $fontPath, $fontvalue);
                $top = $top + $fonttHeight + 5;
            }


            /*
            $widthFonts = intval($baseWidth / ($fontSize * 1.4)); // 一排显示的文字数量
            $rows = ceil($fontCount / $widthFonts);
            $top = $baseHeight - ($fontSize + 5) * $rows;
            if ($top < 0) {
                $top = 0;
            }
            for ($ii = 1; $ii <= $rows; $ii++) {
                // $fontItem = substr($fonts[$key], ($ii - 1) * $widthFonts, $widthFonts);
                $fontItem = mb_substr($fonts[$key], ($ii - 1) * $widthFonts, $widthFonts, 'utf-8');
                if (!empty($fontItem)) {
                    var_dump([$left, $top, $fontItem]);
                    imagefttext($thumb, $fontSize, $circleSize, $left, $top, $black, $fontPath, $fontItem);
                }
                $top = $top + $fontSize + 5;
            }
            */
        }

        imagejpeg($thumb, $results[] = CACHE_PATH . "/" . $imgPathMd5 . "{$key}.jpg", 100);
    }
    return $results;
}

执行图片切割且加文字

$imgPath = BASE_PATH . '/runtime/cache/timg.jpg';
$fontPath = RESOURCE_PATH . '/fonts/方正黑体简体.TTF';//字体,字体文件需保存到相应文件夹下
$fonts = ["啊1","啊2","啊3","啊4","啊5","啊6","啊7","啊8","啊9",]
$pp = imageSlicing9($imgPath, $fonts, $fontPath);
var_dump($pp);

普通写法

function get_chance($chance = [
    '和谐' => 3000,
    '爱国' => 5000,
    '敬业' => 110,
    '友善' => 1000,
    '富强' => 3000,
])
{
    $cardRange = [];
    $num = rand(0, array_sum(array_values($chance)));
    $total = 0;
    foreach ($chance as $key => $value) {
        $totalBefore = $total;
        $total += $value;
        if ($num >= $totalBefore && $num < $total) {
            return $key;
        }
        $cardRange[$key] = [$totalBefore, $total];
    }
    return $key;
}

在swoole环境中的写法, 兼容所有环境

function get_chance($chance = [
    '和谐' => 3000,
    '爱国' => 5000,
    '敬业' => 110,
    '友善' => 1000,
    '富强' => 3000,
])
{
    // 在协程中避免rand一段时间内值一致的问题
    $cardRange = [];
    $total = array_sum(array_values($chance));
    // $randValue = substr(explode(' ', microtime())[0], 0, 8);
    $randValue = strrev(substr(explode(' ', microtime())[0], 2, 6)) / 1000000;
    $rangeBefore = 0;
    $total2 = 0;
    foreach ($chance as $key => $value) {
        $total2 += $value;
        $rangeAfter = $total2 / $total;
        if ($randValue >= $rangeBefore && $randValue < $rangeAfter) {
            return $key;
        }
        $rangeBefore = $rangeAfter;
    }
    return $key;
}

校验数据和预期值的差异量

$t = [
    '记' => 300,
    '得' => 900,
    '我' => 150,
];
$r = [
    '记' => 0,
    '得' => 0,
    '我' => 0,
];
for ($k = 0; $k <= 10000; $k++) {
    $r[get_chance($t)]++;
}
var_dump($r);