perf: 优化文字头像

This commit is contained in:
kuaifan 2024-11-04 14:59:15 +08:00
parent ceb4fc8292
commit 67baddf7a8
5 changed files with 867 additions and 666 deletions

View File

@ -16045,7 +16045,7 @@
/**
*
*
* @see \Maatwebsite\Excel\Mixins\DownloadCollection::downloadExcel()
* @see \Maatwebsite\Excel\Mixins\DownloadCollectionMixin::downloadExcel()
* @param string $fileName
* @param string|null $writerType
* @param mixed $withHeadings
@ -16059,7 +16059,7 @@
/**
*
*
* @see \Maatwebsite\Excel\Mixins\StoreCollection::storeExcel()
* @see \Maatwebsite\Excel\Mixins\StoreCollectionMixin::storeExcel()
* @param string $filePath
* @param string|null $disk
* @param string|null $writerType
@ -16439,6 +16439,247 @@
}
}
namespace Laravolt\Avatar {
/**
*
*
*/
class Facade {
/**
*
*
* @static
*/
public static function setGenerator($generator)
{
/** @var \Laravolt\Avatar\Avatar $instance */
return $instance->setGenerator($generator);
}
/**
*
*
* @static
*/
public static function create($name)
{
/** @var \Laravolt\Avatar\Avatar $instance */
return $instance->create($name);
}
/**
*
*
* @static
*/
public static function applyTheme($config)
{
/** @var \Laravolt\Avatar\Avatar $instance */
return $instance->applyTheme($config);
}
/**
*
*
* @static
*/
public static function addTheme($name, $config)
{
/** @var \Laravolt\Avatar\Avatar $instance */
return $instance->addTheme($name, $config);
}
/**
*
*
* @static
*/
public static function toBase64()
{
/** @var \Laravolt\Avatar\Avatar $instance */
return $instance->toBase64();
}
/**
*
*
* @static
*/
public static function save($path, $quality = 90)
{
/** @var \Laravolt\Avatar\Avatar $instance */
return $instance->save($path, $quality);
}
/**
*
*
* @static
*/
public static function toSvg()
{
/** @var \Laravolt\Avatar\Avatar $instance */
return $instance->toSvg();
}
/**
*
*
* @static
*/
public static function toGravatar($param = null)
{
/** @var \Laravolt\Avatar\Avatar $instance */
return $instance->toGravatar($param);
}
/**
*
*
* @static
*/
public static function getInitial()
{
/** @var \Laravolt\Avatar\Avatar $instance */
return $instance->getInitial();
}
/**
*
*
* @static
*/
public static function getImageObject()
{
/** @var \Laravolt\Avatar\Avatar $instance */
return $instance->getImageObject();
}
/**
*
*
* @static
*/
public static function buildAvatar()
{
/** @var \Laravolt\Avatar\Avatar $instance */
return $instance->buildAvatar();
}
/**
*
*
* @static
*/
public static function getAttribute($key)
{
/** @var \Laravolt\Avatar\Avatar $instance */
return $instance->getAttribute($key);
}
/**
*
*
* @static
*/
public static function setTheme($theme)
{
/** @var \Laravolt\Avatar\Avatar $instance */
return $instance->setTheme($theme);
}
/**
*
*
* @static
*/
public static function setBackground($hex)
{
/** @var \Laravolt\Avatar\Avatar $instance */
return $instance->setBackground($hex);
}
/**
*
*
* @static
*/
public static function setForeground($hex)
{
/** @var \Laravolt\Avatar\Avatar $instance */
return $instance->setForeground($hex);
}
/**
*
*
* @static
*/
public static function setDimension($width, $height = null)
{
/** @var \Laravolt\Avatar\Avatar $instance */
return $instance->setDimension($width, $height);
}
/**
*
*
* @static
*/
public static function setFontSize($size)
{
/** @var \Laravolt\Avatar\Avatar $instance */
return $instance->setFontSize($size);
}
/**
*
*
* @static
*/
public static function setFontFamily($font)
{
/** @var \Laravolt\Avatar\Avatar $instance */
return $instance->setFontFamily($font);
}
/**
*
*
* @static
*/
public static function setBorder($size, $color, $radius = 0)
{
/** @var \Laravolt\Avatar\Avatar $instance */
return $instance->setBorder($size, $color, $radius);
}
/**
*
*
* @static
*/
public static function setBorderRadius($radius)
{
/** @var \Laravolt\Avatar\Avatar $instance */
return $instance->setBorderRadius($radius);
}
/**
*
*
* @static
*/
public static function setShape($shape)
{
/** @var \Laravolt\Avatar\Avatar $instance */
return $instance->setShape($shape);
}
/**
*
*
* @static
*/
public static function setChars($chars)
{
/** @var \Laravolt\Avatar\Avatar $instance */
return $instance->setChars($chars);
}
/**
*
*
* @static
*/
public static function setFont($font)
{
/** @var \Laravolt\Avatar\Avatar $instance */
return $instance->setFont($font);
}
}
}
namespace Maatwebsite\Excel\Facades {
@ -16467,9 +16708,10 @@
/**
*
*
* @param string|null $disk Fallback for usage with named properties
* @param object $export
* @param string $filePath
* @param string|null $disk
* @param string|null $diskName
* @param string $writerType
* @param mixed $diskOptions
* @return bool
@ -16477,10 +16719,10 @@
* @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
* @static
*/
public static function store($export, $filePath, $diskName = null, $writerType = null, $diskOptions = [])
public static function store($export, $filePath, $diskName = null, $writerType = null, $diskOptions = [], $disk = null)
{
/** @var \Maatwebsite\Excel\Excel $instance */
return $instance->store($export, $filePath, $diskName, $writerType, $diskOptions);
return $instance->store($export, $filePath, $diskName, $writerType, $diskOptions, $disk);
}
/**
*
@ -16698,7 +16940,7 @@
* @param $pathToFile string The file to open
* @param \Madnest\Madzipper\Repositories\RepositoryInterface|string $type The type of the archive, defaults to zip, possible are zip, phar
* @throws \RuntimeException
* @throws \Exception
* @throws Exception
* @throws \InvalidArgumentException
* @return \Madnest\Madzipper\Madzipper Madzipper instance
* @static
@ -16712,7 +16954,7 @@
* Create a new zip archive or open an existing one.
*
* @param string $pathToFile
* @throws \Exception
* @throws Exception
* @return self
* @static
*/
@ -16725,7 +16967,7 @@
* Create a new phar file or open one.
*
* @param string $pathToFile
* @throws \Exception
* @throws Exception
* @return self
* @static
*/
@ -16738,7 +16980,7 @@
* Create a new rar file or open one.
*
* @param string $pathToFile
* @throws \Exception
* @throws Exception
* @return self
* @static
*/
@ -16755,7 +16997,7 @@
* @param $path string The path to extract to
* @param array $files An array of files
* @param int $methodFlags The Method the files should be treated
* @throws \Exception
* @throws Exception
* @return void
* @static
*/
@ -16782,7 +17024,7 @@
* Gets the content of a single file if available.
*
* @param $filePath string The full path (including all folders) of the file in the zip
* @throws \Exception
* @throws Exception
* @return mixed returns the content or throws an exception
* @static
*/
@ -18774,6 +19016,64 @@ namespace {
/**
*
*
* @see \Maatwebsite\Excel\Mixins\DownloadQueryMacro::__invoke()
* @param string $fileName
* @param string|null $writerType
* @param mixed $withHeadings
* @static
*/
public static function downloadExcel($fileName, $writerType = null, $withHeadings = false)
{
return \Illuminate\Database\Eloquent\Builder::downloadExcel($fileName, $writerType, $withHeadings);
}
/**
*
*
* @see \Maatwebsite\Excel\Mixins\StoreQueryMacro::__invoke()
* @param string $filePath
* @param string|null $disk
* @param string|null $writerType
* @param mixed $withHeadings
* @static
*/
public static function storeExcel($filePath, $disk = null, $writerType = null, $withHeadings = false)
{
return \Illuminate\Database\Eloquent\Builder::storeExcel($filePath, $disk, $writerType, $withHeadings);
}
/**
*
*
* @see \Maatwebsite\Excel\Mixins\ImportMacro::__invoke()
* @param string $filename
* @param string|null $disk
* @param string|null $readerType
* @static
*/
public static function import($filename, $disk = null, $readerType = null)
{
return \Illuminate\Database\Eloquent\Builder::import($filename, $disk, $readerType);
}
/**
*
*
* @see \Maatwebsite\Excel\Mixins\ImportAsMacro::__invoke()
* @param string $filename
* @param callable $mapping
* @param string|null $disk
* @param string|null $readerType
* @static
*/
public static function importAs($filename, $mapping, $disk = null, $readerType = null)
{
return \Illuminate\Database\Eloquent\Builder::importAs($filename, $mapping, $disk, $readerType);
}
/**
*
*
* @see \App\Providers\AppServiceProvider::boot()
* @static
*/
@ -20814,6 +21114,7 @@ namespace {
class View extends \Illuminate\Support\Facades\View {}
class Flare extends \Facade\Ignition\Facades\Flare {}
class Image extends \Intervention\Image\Facades\Image {}
class Avatar extends \Laravolt\Avatar\Facade {}
class Excel extends \Maatwebsite\Excel\Facades\Excel {}
class Madzipper extends \Madnest\Madzipper\Facades\Madzipper {}
class Captcha extends \Mews\Captcha\Facades\Captcha {}

View File

@ -23,7 +23,7 @@ use App\Tasks\CheckinRemindTask;
use App\Tasks\CloseMeetingRoomTask;
use App\Tasks\UnclaimedTaskRemindTask;
use Hhxsv5\LaravelS\Swoole\Task\Task;
use LasseRafn\InitialAvatarGenerator\InitialAvatar;
use Laravolt\Avatar\Avatar;
/**
@ -83,7 +83,7 @@ class IndexController extends InvokeController
/**
* 头像
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response|\Symfony\Component\HttpFoundation\BinaryFileResponse
*/
public function avatar()
{
@ -91,15 +91,83 @@ class IndexController extends InvokeController
if ($segment && preg_match('/.*?\.png$/i', $segment)) {
$name = substr($segment, 0, -4);
} else {
$name = Request::input('name', 'H');
$name = Request::input('name', 'D');
}
$size = Request::input('size', 128);
$color = Request::input('color');
$background = Request::input('background');
// 移除各种括号及其内容
$pattern = '/[(\[【{<<『「](.*?)[)\]】}>>』」]/u';
$name = preg_replace($pattern, '', $name) ?: preg_replace($pattern, '$1', $name);
// 移除常见标识词(不区分大小写)
$filterWords = [
// 测试相关
'测试', '测试号', '测试账号', '内测', '体验', '试用', 'test', 'testing', 'beta',
// 账号相关
'账号', '帐号', '账户', '帐户', 'account', 'acc', 'id', 'uid',
// 临时标识
'临时', '暂用', '备用', '主号', '副号', '小号', '大号', 'temp', 'temporary', 'backup',
// 系统相关
'系统', '管理员', 'admin', 'administrator', 'system', 'sys', 'root',
// 用户相关
'用户', 'user', '会员', 'member', 'vip', 'svip', 'mvip', 'premium',
// 官方相关
'官方', '正式', '认证', 'official', 'verified', 'auth',
// 客服相关
'客服', '售后', '服务', 'service', 'support', 'helper', 'assistant',
// 游戏相关
'game', 'gaming', 'player', 'gamer',
// 社交媒体相关
'ins', 'instagram', 'fb', 'facebook', 'tiktok', 'tweet', 'weibo', 'wechat',
// 常见后缀
'official', 'real', 'fake', 'copy', 'channel', 'studio', 'team', 'group',
// 职业相关
'dev', 'developer', 'designer', 'artist', 'writer', 'editor',
// 其他
'bot', 'robot', 'auto', 'anonymous', 'guest', 'default', 'new', 'old'
];
$filterWords = array_map(function($word) {
return preg_quote($word, '/');
}, $filterWords);
$name = preg_replace('/' . implode('|', $filterWords) . '/iu', '', $name) ?: $name;
// 移除分隔符和特殊字符
$filterSymbols = [
// 常见分隔符
'-', '_', '=', '+', '/', '\\', '|',
'~', '@', '#', '$', '%', '^', '&', '*',
// 空格类字符
' ', ' ', "\t", "\n", "\r",
// 标点符号(中英文)
'。', '', '、', '', '', '', '',
'', '…', '‥', '', '″', '℃',
'.', ',', ';', ':', '?', '!',
// 引号类(修正版)
'"', "'", '', '', '“', '”', '`',
// 特殊符号
'★', '☆', '○', '●', '◎', '◇', '◆',
'□', '■', '△', '▲', '▽', '▼',
'♀', '♂', '♪', '♫', '♯', '♭', '♬',
'→', '←', '↑', '↓', '↖', '↗', '↙', '↘',
'√', '×', '÷', '±', '∵', '∴',
'♠', '♥', '♣', '♦',
// emoji 表情符号范围
'\x{1F300}-\x{1F9FF}',
'\x{2600}-\x{26FF}',
'\x{2700}-\x{27BF}',
'\x{1F900}-\x{1F9FF}',
'\x{1F600}-\x{1F64F}'
];
$filterSymbols = array_map(function($symbol) {
return preg_quote($symbol, '/');
}, $filterSymbols);
$name = preg_replace('/[' . implode('', $filterSymbols) . ']/u', '', $name) ?: $name;
//
if (preg_match('/^[\x{4e00}-\x{9fa5}]+$/u', $name)) {
$name = mb_substr($name, mb_strlen($name) - 2);
}
if (empty($name)) {
$name = 'D';
}
if (empty($color)) {
$color = '#ffffff';
$cacheKey = "avatarBackgroundColor::" . md5($name);
@ -108,17 +176,35 @@ class IndexController extends InvokeController
});
}
//
$avatar = new InitialAvatar();
$content = $avatar->name($name)
->size($size)
->color($color)
->background($background)
->fontSize(0.35)
->autoFont()
->generate()
->stream('png', 100);
$path = public_path('uploads/tmp/avatar/' . substr(md5($name), 0, 2));
$file = Base::joinPath($path, md5($name) . '.png');
if (file_exists($file)) {
return response()->file($file, [
'Pragma' => 'public',
'Cache-Control' => 'max-age=1814400',
'Content-type' => 'image/png',
'Expires' => gmdate('D, d M Y H:i:s \G\M\T', time() + 1814400),
]);
}
Base::makeDir($path);
//
return response($content)
$avatar = new Avatar([
'shape' => 'square',
'width' => $size,
'height' => $size,
'chars' => 2,
'fontSize' => $size / 2.9,
'uppercase' => true,
'fonts' => [resource_path('assets/statics/fonts/Source_Han_Sans_SC_Regular.otf')],
'foregrounds' => [$color],
'backgrounds' => [$background],
'border' => [
'size' => 0,
'color' => 'foreground',
'radius' => 0,
],
]);
return response($avatar->create($name)->save($file))
->header('Pragma', 'public')
->header('Cache-Control', 'max-age=1814400')
->header('Content-type', 'image/png')

View File

@ -26,7 +26,7 @@
"hedeqiang/umeng": "^2.1",
"laravel/framework": "^v8.83.27",
"laravel/tinker": "^v2.6.1",
"lasserafn/php-initial-avatar-generator": "^4.2",
"laravolt/avatar": "^5.1",
"league/commonmark": "^2.5",
"maatwebsite/excel": "^3.1.31",
"madnest/madzipper": "^v1.1.0",

1096
composer.lock generated

File diff suppressed because it is too large Load Diff