perf: 默认使用文字头像

This commit is contained in:
kuaifan 2022-06-14 18:11:54 +08:00
parent d8d707175c
commit f7f668a032
7 changed files with 653 additions and 6 deletions

View File

@ -4,12 +4,14 @@ namespace App\Http\Controllers;
use App\Module\Base;
use App\Module\Ihttp;
use App\Module\RandomColor;
use App\Tasks\AutoArchivedTask;
use App\Tasks\DeleteTmpTask;
use App\Tasks\EmailNoticeTask;
use Arr;
use Cache;
use Hhxsv5\LaravelS\Swoole\Task\Task;
use LasseRafn\InitialAvatarGenerator\InitialAvatar;
use Redirect;
use Request;
@ -123,6 +125,39 @@ class IndexController extends InvokeController
return $array;
}
/**
* 头像
* @return \Psr\Http\Message\StreamInterface
*/
public function avatar()
{
$name = Request::input('name', 'H');
$size = Request::input('size', 128);
$color = Request::input('color');
$background = Request::input('background');
//
if (preg_match('/^[\x{4e00}-\x{9fa5}]+$/u', $name)) {
$name = mb_substr($name, mb_strlen($name) - 2);
}
if (empty($color)) {
$color = '#ffffff';
$cacheKey = "avatarBackgroundColor::" . md5($name);
$background = Cache::rememberForever($cacheKey, function() {
return RandomColor::one(['luminosity' => 'dark']);
});
}
//
$avatar = new InitialAvatar();
return $avatar->name($name)
->size($size)
->color($color)
->background($background)
->fontSize(0.35)
->autoFont()
->generate()
->stream('png', 100);
}
/**
* 接口文档
* @return \Illuminate\Http\RedirectResponse

View File

@ -67,6 +67,8 @@ class User extends AbstractModel
'updated_at',
];
protected $defaultAvatarMode = 'auto'; // auto自动生成system系统默认
/**
* 更新数据校验
* @param array $param
@ -97,11 +99,17 @@ class User extends AbstractModel
*/
public function getUserimgAttribute($value)
{
if ($value) {
if ($value && !str_starts_with($value, 'images/avatar/default')) {
return Base::fillUrl($value);
}
$name = ($this->userid - 1) % 21 + 1;
return url("images/avatar/default_{$name}.png");
if ($this->defaultAvatarMode === 'auto') {
// 自动生成头像
return url("avatar?name=" . urlencode($this->nickname));
} else {
// 系统默认头像
$name = ($this->userid - 1) % 21 + 1;
return url("images/avatar/default_{$name}.png");
}
}
/**

390
app/Module/RandomColor.php Normal file
View File

@ -0,0 +1,390 @@
<?php
/**
* RandomColor 1.0.5
*
* PHP port of David Merfield JavaScript randomColor
* https://github.com/davidmerfield/randomColor
*
*
* The MIT License (MIT)
*
* Copyright (c) 2014-2022 Damien "Mistic" Sorel
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
namespace App\Module;
class RandomColor
{
static public $dictionary = null;
private function __construct() {}
static public function one($options = array())
{
$h = self::_pickHue($options);
$s = self::_pickSaturation($h, $options);
$v = self::_pickBrightness($h, $s, $options);
return self::format(compact('h','s','v'), @$options['format']);
}
static public function many($count, $options = array())
{
$colors = array();
for ($i = 0; $i < $count; $i++)
{
$colors[] = self::one($options);
}
return $colors;
}
static public function format($hsv, $format='hex')
{
switch ($format)
{
case 'hsv':
return $hsv;
case 'hsl':
return self::hsv2hsl($hsv);
case 'hslCss':
$hsl = self::hsv2hsl($hsv);
return 'hsl(' . $hsl['h'] . ',' . $hsl['s'] . '%,' . $hsl['l'] . '%)';
case 'rgb':
return self::hsv2rgb($hsv);
case 'rgbCss':
return 'rgb(' . implode(',', self::hsv2rgb($hsv)) . ')';
case 'hex':
default:
return self::hsv2hex($hsv);
}
}
static private function _pickHue($options)
{
$range = self::_getHueRange($options);
if (empty($range))
{
return 0;
}
$hue = self::_rand($range, $options);
// Instead of storing red as two separate ranges,
// we group them, using negative numbers
if ($hue < 0)
{
$hue = 360 + $hue;
}
return $hue;
}
static private function _pickSaturation($h, $options)
{
if (@$options['hue'] === 'monochrome')
{
return 0;
}
if (@$options['luminosity'] === 'random')
{
return self::_rand(array(0, 100), $options);
}
$colorInfo = self::_getColorInfo($h);
$range = $colorInfo['s'];
switch (@$options['luminosity'])
{
case 'bright':
$range[0] = 55;
break;
case 'dark':
$range[0] = $range[1] - 10;
break;
case 'light':
$range[1] = 55;
break;
}
return self::_rand($range, $options);
}
static private function _pickBrightness($h, $s, $options)
{
if (@$options['luminosity'] === 'random')
{
$range = array(0, 100);
}
else
{
$range = array(
self::_getMinimumBrightness($h, $s),
100
);
switch (@$options['luminosity'])
{
case 'dark':
$range[1] = $range[0] + 20;
break;
case 'light':
$range[0] = round(($range[1] + $range[0]) / 2);
break;
}
}
return self::_rand($range, $options);
}
static private function _getHueRange($options)
{
$ranges = array();
if (isset($options['hue']))
{
if (!is_array($options['hue']))
{
$options['hue'] = array($options['hue']);
}
foreach ($options['hue'] as $hue)
{
if ($hue === 'random')
{
$ranges[] = array(0, 360);
}
else if (isset(self::$dictionary[$hue]))
{
$ranges[] = self::$dictionary[$hue]['h'];
}
else if (is_numeric($hue))
{
$hue = intval($hue);
if ($hue <= 360 && $hue >= 0)
{
$ranges[] = array($hue, $hue);
}
}
}
}
if (($l = count($ranges)) === 0)
{
return array(0, 360);
}
else if ($l === 1)
{
return $ranges[0];
}
else
{
return $ranges[self::_rand(array(0, $l-1), $options)];
}
}
static private function _getMinimumBrightness($h, $s)
{
$colorInfo = self::_getColorInfo($h);
$bounds = $colorInfo['bounds'];
for ($i = 0, $l = count($bounds); $i < $l - 1; $i++)
{
$s1 = $bounds[$i][0];
$v1 = $bounds[$i][1];
$s2 = $bounds[$i+1][0];
$v2 = $bounds[$i+1][1];
if ($s >= $s1 && $s <= $s2)
{
$m = ($v2 - $v1) / ($s2 - $s1);
$b = $v1 - $m * $s1;
return round($m * $s + $b);
}
}
return 0;
}
static private function _getColorInfo($h)
{
// Maps red colors to make picking hue easier
if ($h >= 334 && $h <= 360)
{
$h-= 360;
}
foreach (self::$dictionary as $color)
{
if ($color['h'] !== null && $h >= $color['h'][0] && $h <= $color['h'][1])
{
return $color;
}
}
}
static private function _rand($bounds, $options)
{
if (isset($options['prng']))
{
return $options['prng']($bounds[0], $bounds[1]);
}
else
{
return mt_rand($bounds[0], $bounds[1]);
}
}
static public function hsv2hex($hsv)
{
$rgb = self::hsv2rgb($hsv);
$hex = '#';
foreach ($rgb as $c)
{
$hex.= str_pad(dechex($c), 2, '0', STR_PAD_LEFT);
}
return $hex;
}
static public function hsv2hsl($hsv)
{
extract($hsv);
$s/= 100;
$v/= 100;
$k = (2-$s)*$v;
return array(
'h' => $h,
's' => round($s*$v / ($k < 1 ? $k : 2-$k), 4) * 100,
'l' => $k/2 * 100,
);
}
static public function hsv2rgb($hsv)
{
extract($hsv);
$h/= 360;
$s/= 100;
$v/= 100;
$i = floor($h * 6);
$f = $h * 6 - $i;
$m = $v * (1 - $s);
$n = $v * (1 - $s * $f);
$k = $v * (1 - $s * (1 - $f));
$r = 1;
$g = 1;
$b = 1;
switch ($i)
{
case 0:
list($r,$g,$b) = array($v,$k,$m);
break;
case 1:
list($r,$g,$b) = array($n,$v,$m);
break;
case 2:
list($r,$g,$b) = array($m,$v,$k);
break;
case 3:
list($r,$g,$b) = array($m,$n,$v);
break;
case 4:
list($r,$g,$b) = array($k,$m,$v);
break;
case 5:
case 6:
list($r,$g,$b) = array($v,$m,$n);
break;
}
return array(
'r' => floor($r*255),
'g' => floor($g*255),
'b' => floor($b*255),
);
}
}
/*
* h=hueRange
* s=saturationRange : bounds[0][0] ; bounds[-][0]
*/
RandomColor::$dictionary = array(
'monochrome' => array(
'bounds' => array(array(0,0), array(100,0)),
'h' => NULL,
's' => array(0,100)
),
'red' => array(
'bounds' => array(array(20,100),array(30,92),array(40,89),array(50,85),array(60,78),array(70,70),array(80,60),array(90,55),array(100,50)),
'h' => array(-26,18),
's' => array(20,100)
),
'orange' => array(
'bounds' => array(array(20,100),array(30,93),array(40,88),array(50,86),array(60,85),array(70,70),array(100,70)),
'h' => array(19,46),
's' => array(20,100)
),
'yellow' => array(
'bounds' => array(array(25,100),array(40,94),array(50,89),array(60,86),array(70,84),array(80,82),array(90,80),array(100,75)),
'h' => array(47,62),
's' => array(25,100)
),
'green' => array(
'bounds' => array(array(30,100),array(40,90),array(50,85),array(60,81),array(70,74),array(80,64),array(90,50),array(100,40)),
'h' => array(63,178),
's' => array(30,100)
),
'blue' => array(
'bounds' => array(array(20,100),array(30,86),array(40,80),array(50,74),array(60,60),array(70,52),array(80,44),array(90,39),array(100,35)),
'h' => array(179,257),
's' => array(20,100)
),
'purple' => array(
'bounds' => array(array(20,100),array(30,87),array(40,79),array(50,70),array(60,65),array(70,59),array(80,52),array(90,45),array(100,42)),
'h' => array(258,282),
's' => array(20,100)
),
'pink' => array(
'bounds' => array(array(20,100),array(30,90),array(40,86),array(60,84),array(80,80),array(90,75),array(100,73)),
'h' => array(283,334),
's' => array(20,100)
)
);

View File

@ -21,6 +21,7 @@
"hedeqiang/umeng": "^2.1",
"laravel/framework": "^v8.48.1",
"laravel/tinker": "^v2.6.1",
"lasserafn/php-initial-avatar-generator": "^4.2",
"maatwebsite/excel": "^3.1.31",
"madnest/madzipper": "^v1.1.0",
"mews/captcha": "^3.2.6",

215
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "899b6938adcec6d779c54a3005df68a2",
"content-hash": "9cb3ad18f25c6607bf31539b459e2dda",
"packages": [
{
"name": "asm89/stack-cors",
@ -1646,6 +1646,169 @@
},
"time": "2022-03-23T12:38:24+00:00"
},
{
"name": "lasserafn/php-initial-avatar-generator",
"version": "4.2.1",
"source": {
"type": "git",
"url": "https://github.com/LasseRafn/php-initial-avatar-generator.git",
"reference": "49d0b10cc8819af831e0f6fb1056a7d5ed9512d0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/LasseRafn/php-initial-avatar-generator/zipball/49d0b10cc8819af831e0f6fb1056a7d5ed9512d0",
"reference": "49d0b10cc8819af831e0f6fb1056a7d5ed9512d0",
"shasum": ""
},
"require": {
"ext-json": "*",
"intervention/image": "^2.3",
"lasserafn/php-initials": "^3.0",
"lasserafn/php-string-script-language": "^0.3.0",
"meyfa/php-svg": "^0.9.0",
"overtrue/pinyin": "^4.0",
"php": "^7.0|^7.1|^7.2|^7.3|^7.4|^8.0"
},
"require-dev": {
"doctrine/instantiator": "1.0.*",
"phpunit/phpunit": "^6.5",
"satooshi/php-coveralls": "^1.0"
},
"type": "library",
"autoload": {
"psr-4": {
"LasseRafn\\InitialAvatarGenerator\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Lasse Rafn",
"email": "lasserafn@gmail.com"
}
],
"description": "A package to generate avatars with initials for PHP",
"keywords": [
"Initials",
"avatar",
"image",
"svg"
],
"support": {
"issues": "https://github.com/LasseRafn/php-initial-avatar-generator/issues",
"source": "https://github.com/LasseRafn/php-initial-avatar-generator/tree/4.2.1"
},
"funding": [
{
"url": "https://opencollective.com/ui-avatars",
"type": "open_collective"
}
],
"time": "2020-12-24T13:12:12+00:00"
},
{
"name": "lasserafn/php-initials",
"version": "3.1",
"source": {
"type": "git",
"url": "https://github.com/LasseRafn/php-initials.git",
"reference": "d287e1542687390eb68de779949bc0adc49e2d52"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/LasseRafn/php-initials/zipball/d287e1542687390eb68de779949bc0adc49e2d52",
"reference": "d287e1542687390eb68de779949bc0adc49e2d52",
"shasum": ""
},
"require": {
"php": "^5.6|^7.0|^7.1|^8.0"
},
"require-dev": {
"phpunit/phpunit": "^5.7",
"satooshi/php-coveralls": "^1.0"
},
"type": "library",
"autoload": {
"psr-4": {
"LasseRafn\\Initials\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Lasse Rafn",
"email": "lasserafn@gmail.com"
}
],
"description": "A package to generate initials in PHP",
"keywords": [
"Initials",
"php"
],
"support": {
"issues": "https://github.com/LasseRafn/php-initials/issues",
"source": "https://github.com/LasseRafn/php-initials/tree/3.1"
},
"time": "2020-12-24T12:25:51+00:00"
},
{
"name": "lasserafn/php-string-script-language",
"version": "0.3",
"source": {
"type": "git",
"url": "https://github.com/LasseRafn/php-string-script-language.git",
"reference": "49a09d4a5e38c1e59a2656ac05b601d615c7cddb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/LasseRafn/php-string-script-language/zipball/49a09d4a5e38c1e59a2656ac05b601d615c7cddb",
"reference": "49a09d4a5e38c1e59a2656ac05b601d615c7cddb",
"shasum": ""
},
"require": {
"php": "^5.6|^7.0|^7.1|^8.0"
},
"require-dev": {
"doctrine/instantiator": "1.0.5",
"phpunit/phpunit": "^5.6",
"phpunit/phpunit-mock-objects": "3.2.4",
"satooshi/php-coveralls": "^1.0",
"sebastian/exporter": "^1.2"
},
"type": "library",
"autoload": {
"psr-4": {
"LasseRafn\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Lasse Rafn",
"email": "lasserafn@gmail.com"
}
],
"description": "Detect language/encoding of a string in PHP",
"keywords": [
"language",
"php",
"string"
],
"support": {
"issues": "https://github.com/LasseRafn/php-string-script-language/issues",
"source": "https://github.com/LasseRafn/php-string-script-language/tree/0.3"
},
"time": "2020-12-24T12:43:59+00:00"
},
{
"name": "league/commonmark",
"version": "2.3.3",
@ -2376,6 +2539,56 @@
},
"time": "2022-02-12T15:58:32+00:00"
},
{
"name": "meyfa/php-svg",
"version": "v0.9.1",
"source": {
"type": "git",
"url": "https://github.com/meyfa/php-svg.git",
"reference": "34401edef1f724898f468f71b85505fbcc8351bb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/meyfa/php-svg/zipball/34401edef1f724898f468f71b85505fbcc8351bb",
"reference": "34401edef1f724898f468f71b85505fbcc8351bb",
"shasum": ""
},
"require": {
"ext-gd": "*",
"ext-simplexml": "*",
"php": ">=5.3.3"
},
"require-dev": {
"meyfa/phpunit-assert-gd": "^1.1",
"phpunit/phpunit": "^4.8"
},
"type": "library",
"autoload": {
"psr-4": {
"SVG\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabian Meyer",
"homepage": "http://meyfa.net"
}
],
"description": "Read, edit, write, and render SVG files with PHP",
"homepage": "https://github.com/meyfa/php-svg",
"keywords": [
"svg"
],
"support": {
"issues": "https://github.com/meyfa/php-svg/issues",
"source": "https://github.com/meyfa/php-svg/tree/v0.9.1"
},
"time": "2019-07-30T18:41:25+00:00"
},
{
"name": "monolog/monolog",
"version": "2.7.0",

View File

@ -173,7 +173,7 @@
isDefault() {
const {userimg} = this.user
return $A.strExists(userimg, '/avatar/default_');
return $A.strExists(userimg, '/avatar');
},
nickname() {

View File

@ -62,7 +62,7 @@ export default {
},
initData() {
if (!$A.strExists(this.userInfo.userimg, '/avatar/default_')) {
if (!$A.strExists(this.userInfo.userimg, '/avatar')) {
this.$set(this.formData, 'userimg', this.userInfo.userimg);
}
const nickname = typeof this.userInfo.nickname_original !== "undefined" ? this.userInfo.nickname_original : this.userInfo.nickname;