我将为您创建一个完整的PHP脚本,用于批量生成NFT图片,这个脚本会结合多个图层组件(如背景、身体、眼睛、装饰等)来生成独特的NFT图片。

完整PHP NFT生成脚本
<?php
/**
* NFT图片批量生成器
* 通过组合不同图层生成独特的NFT图片
*/
class NFTGenerator {
private $layers = [];
private $outputDir;
private $width = 1000;
private $height = 1000;
private $totalSupply = 100;
private $rarityLevels = ['common' => 0.6, 'rare' => 0.25, 'epic' => 0.1, 'legendary' => 0.05];
public function __construct($outputDir = 'nft_output') {
$this->outputDir = $outputDir;
if (!file_exists($outputDir)) {
mkdir($outputDir, 0777, true);
}
if (!extension_loaded('gd')) {
die('需要启用GD库');
}
}
/**
* 配置图层
*
* 目录结构示例:
* layers/
* background/
* 红色背景.png
* 蓝色背景.png
* body/
* 标准身体.png
* 特殊身体.png
*/
public function loadLayers($layersDir) {
$directories = ['background', 'body', 'eyes', 'mouth', 'accessory'];
foreach ($directories as $dir) {
$path = $layersDir . '/' . $dir;
if (is_dir($path)) {
$files = glob($path . '/*.{png,jpg,jpeg}', GLOB_BRACE);
if (!empty($files)) {
$this->layers[$dir] = [];
foreach ($files as $file) {
$this->layers[$dir][] = [
'path' => $file,
'name' => pathinfo($file, PATHINFO_FILENAME),
'rarity' => $this->determineRarity($file)
];
}
}
}
}
if (empty($this->layers)) {
die('没有找到图层文件');
}
}
/**
* 根据文件名确定稀有度(可通过文件名包含关键字)
*/
private function determineRarity($file) {
$filename = strtolower(basename($file));
if (strpos($filename, 'legendary') !== false) return 'legendary';
if (strpos($filename, 'epic') !== false) return 'epic';
if (strpos($filename, 'rare') !== false) return 'rare';
return 'common';
}
/**
* 生成单个NFT
*/
public function generateSingle($id) {
$bg = imagecreatetruecolor($this->width, $this->height);
// 设置白色背景
$white = imagecolorallocate($bg, 255, 255, 255);
imagefill($bg, 0, 0, $white);
$selectedLayers = [];
$attributes = [];
// 后台优先
if (isset($this->layers['background'])) {
$layer = $this->selectLayer($this->layers['background']);
$this->applyLayer($bg, $layer);
$attributes[] = ['trait_type' => 'Background', 'value' => $layer['name']];
$selectedLayers[] = $layer;
}
// 身体
if (isset($this->layers['body'])) {
$layer = $this->selectLayer($this->layers['body']);
$this->applyLayer($bg, $layer);
$attributes[] = ['trait_type' => 'Body', 'value' => $layer['name']];
$selectedLayers[] = $layer;
}
// 眼睛
if (isset($this->layers['eyes'])) {
$layer = $this->selectLayer($this->layers['eyes']);
$this->applyLayer($bg, $layer);
$attributes[] = ['trait_type' => 'Eyes', 'value' => $layer['name']];
$selectedLayers[] = $layer;
}
// 嘴巴
if (isset($this->layers['mouth'])) {
$layer = $this->selectLayer($this->layers['mouth']);
$this->applyLayer($bg, $layer);
$attributes[] = ['trait_type' => 'Mouth', 'value' => $layer['name']];
$selectedLayers[] = $layer;
}
// 装饰品
if (isset($this->layers['accessory'])) {
$layer = $this->selectLayer($this->layers['accessory']);
$this->applyLayer($bg, $layer);
$attributes[] = ['trait_type' => 'Accessory', 'value' => $layer['name']];
$selectedLayers[] = $layer;
}
// 计算稀有度
$rarity = 'common';
$rarityScore = 1;
foreach ($selectedLayers as $layer) {
if ($layer['rarity'] === 'legendary') {
$rarity = 'legendary';
$rarityScore *= 0.5;
} elseif ($layer['rarity'] === 'epic' && $rarity !== 'legendary') {
$rarity = 'epic';
$rarityScore *= 0.7;
} elseif ($layer['rarity'] === 'rare' && $rarity === 'common') {
$rarity = 'rare';
$rarityScore *= 0.85;
}
}
// 保存图片
$filename = $this->outputDir . '/nft_' . $id . '.png';
imagepng($bg, $filename);
imagedestroy($bg);
// 生成元数据
$metadata = [
'name' => 'NFT #' . $id,
'description' => '独特的数字艺术品 NFT #' . $id,
'image' => $filename,
'attributes' => $attributes,
'rarity' => $rarity,
'rarity_score' => round($rarityScore, 3)
];
// 保存元数据
file_put_contents($this->outputDir . '/nft_' . $id . '.json', json_encode($metadata, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
echo "生成 NFT #{$id} 成功 (稀有度: {$rarity})\n";
return $metadata;
}
/**
* 选择图层(带稀有度权重)
*/
private function selectLayer($layers) {
// 根据稀有度权重选择
$totalWeight = 0;
foreach ($layers as $layer) {
$weight = $this->rarityLevels[$layer['rarity']] ?? 0.1;
$totalWeight += $weight;
}
$random = mt_rand(0, $totalWeight * 100) / 100;
$cumulativeWeight = 0;
shuffle($layers); // 随机排序增加多样性
foreach ($layers as $layer) {
$weight = $this->rarityLevels[$layer['rarity']] ?? 0.1;
$cumulativeWeight += $weight;
if ($random <= $cumulativeWeight) {
return $layer;
}
}
return $layers[0]; // 默认返回第一个
}
/**
* 应用图层到图像
*/
private function applyLayer($base, $layer) {
$overlay = imagecreatefromstring(file_get_contents($layer['path']));
// 调整大小
$overlay = $this->resizeImage($overlay, $this->width, $this->height);
// 合并图像
imagecopy($base, $overlay, 0, 0, 0, 0, $this->width, $this->height);
imagedestroy($overlay);
}
/**
* 调整图像大小
*/
private function resizeImage($image, $width, $height) {
$newImage = imagecreatetruecolor($width, $height);
imagealphablending($newImage, true);
imagesavealpha($newImage, true);
$srcW = imagesx($image);
$srcH = imagesy($image);
imagecopyresampled($newImage, $image, 0, 0, 0, 0, $width, $height, $srcW, $srcH);
imagedestroy($image);
return $newImage;
}
/**
* 批量生成NFT
*/
public function generateBatch($count) {
$generated = [];
$usedCombinations = [];
echo "开始生成 {$count} 个NFT...\n";
for ($i = 1; $i <= $count; $i++) {
// 获取唯一组合
do {
$combination = $this->getRandomCombination();
$hash = md5(implode('|', $combination));
} while (in_array($hash, $usedCombinations));
$usedCombinations[] = $hash;
$this->generateSingle($i);
$generated[] = $i;
if ($i % 10 == 0) {
echo "已完成 {$i}/{$count} 个NFT\n";
}
}
echo "批量生成完成!共生成 " . count($generated) . " 个NFT\n";
}
/**
* 获取随机组合(用于唯一性检查)
*/
private function getRandomCombination() {
$combination = [];
foreach ($this->layers as $layerType => $layers) {
$combination[] = $this->selectLayer($layers)['name'];
}
return $combination;
}
/**
* 生成项目级元数据
*/
public function generateCollectionMetadata($name, $description) {
$metadata = [
'name' => $name,
'description' => $description,
'image' => 'https://example.com/logo.png',
'external_link' => 'https://example.com',
'seller_fee_basis_points' => 500,
'fee_recipient' => '0x0000000000000000000000000000000000000000'
];
file_put_contents($this->outputDir . '/collection.json', json_encode($metadata, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
echo "项目元数据已生成\n";
}
/**
* 生成统计报告
*/
public function generateStatistics() {
$stats = [];
$jsonFiles = glob($this->outputDir . '/*.json');
foreach ($jsonFiles as $file) {
if (basename($file) === 'collection.json') continue;
$data = json_decode(file_get_contents($file), true);
if (isset($data['rarity'])) {
$stats[$data['rarity']] = ($stats[$data['rarity']] ?? 0) + 1;
}
}
echo "\n=== NFT稀有度统计 ===\n";
foreach ($stats as $rarity => $count) {
$percentage = round(($count / array_sum($stats)) * 100, 2);
echo "{$rarity}: {$count}个 ({$percentage}%)\n";
}
return $stats;
}
}
// ==================== 使用示例 ====================
// 初始化生成器
$generator = new NFTGenerator('my_nft_collection');
// 加载图层(请确保图层目录结构正确)
$generator->loadLayers('layers');
// 设置NFT数量
$totalNFTs = 100;
// 批量生成
$generator->generateBatch($totalNFTs);
// 生成项目元数据
$generator->generateCollectionMetadata(
'我的NFT收藏',
'这是一个由PHP自动生成的独特NFT收藏系列'
);
// 生成统计报告
$generator->generateStatistics();
echo "\nNFT生成完成!请检查 my_nft_collection 目录\n";
// 可以添加更多的自定义功能
?>
辅助脚本:创建示例图层
创建以下脚本来生成简单的示例图层:
<?php
/**
* 生成示例NFT图层
*/
class LayerCreator {
private $layersDir;
public function __construct() {
$this->layersDir = __DIR__ . '/layers';
$this->createDirectories();
}
private function createDirectories() {
$dirs = ['background', 'body', 'eyes', 'mouth', 'accessory'];
foreach ($dirs as $dir) {
if (!file_exists($this->layersDir . '/' . $dir)) {
mkdir($this->layersDir . '/' . $dir, 0777, true);
}
}
}
public function generateBackgrounds() {
$colors = [
'common' => ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4'],
'rare' => ['#FFEAA7', '#DDA0DD', '#98FB98', '#FFDAB9'],
'epic' => ['#FFB6C1', '#87CEEB', '#DDA0DD', '#FF69B4'],
'legendary' => ['#FFD700', '#FF1493', '#00CED1', '#8A2BE2']
];
foreach ($colors as $rarity => $palette) {
foreach ($palette as $i => $color) {
$img = imagecreatetruecolor(1000, 1000);
$rgb = $this->hexToRgb($color);
$bg = imagecolorallocate($img, $rgb[0], $rgb[1], $rgb[2]);
imagefill($img, 0, 0, $bg);
// 添加简单的渐变效果
for ($y = 0; $y < 1000; $y += 10) {
$alpha = ($y / 1000) * 127;
$gradient = imagecolorallocatealpha($img, 255, 255, 255, $alpha);
imageline($img, 0, $y, 1000, $y, $gradient);
}
$filename = $this->layersDir . "/background/bg_{$rarity}_{$i}.png";
imagepng($img, $filename);
imagedestroy($img);
}
}
echo "生成背景图层完成\n";
}
public function generateBodies() {
$shapes = [
'circle', 'rounded', 'squared', 'star'
];
foreach ($shapes as $i => $shape) {
$img = imagecreatetruecolor(1000, 1000);
imagesavealpha($img, true);
$transparent = imagecolorallocatealpha($img, 0, 0, 0, 127);
imagefill($img, 0, 0, $transparent);
$color = imagecolorallocate($img, 255, 128, 0);
switch ($shape) {
case 'circle':
imagefilledellipse($img, 500, 500, 700, 700, $color);
break;
case 'rounded':
imagefilledrectangle($img, 300, 300, 700, 700, $color);
break;
case 'squared':
imagefilledrectangle($img, 250, 250, 750, 750, $color);
break;
case 'star':
$points = $this->getStarPoints(5, 350, 500, 500);
imagefilledpolygon($img, $points, 5, $color);
break;
}
$rarity = $i < 2 ? 'common' : ($i < 3 ? 'rare' : 'epic');
$filename = $this->layersDir . "/body/body_{$rarity}_{$i}.png";
imagepng($img, $filename);
imagedestroy($img);
}
echo "生成身体图层完成\n";
}
public function generateEyes() {
$styles = [
'small', 'large', 'round', 'cat', 'robot', 'sleepy'
];
foreach ($styles as $i => $style) {
$img = imagecreatetruecolor(1000, 1000);
imagesavealpha($img, true);
$transparent = imagecolorallocatealpha($img, 0, 0, 0, 127);
imagefill($img, 0, 0, $transparent);
$eyeColor = imagecolorallocate($img, 50, 50, 50);
$white = imagecolorallocate($img, 255, 255, 255);
switch ($style) {
case 'small':
imagefilledellipse($img, 400, 400, 40, 40, $eyeColor);
imagefilledellipse($img, 600, 400, 40, 40, $eyeColor);
break;
case 'large':
imagefilledellipse($img, 380, 380, 100, 100, $white);
imagefilledellipse($img, 620, 380, 100, 100, $white);
imagefilledellipse($img, 380, 380, 60, 60, $eyeColor);
imagefilledellipse($img, 620, 380, 60, 60, $eyeColor);
break;
case 'robot':
imagefilledrectangle($img, 360, 360, 440, 440, $eyeColor);
imagefilledrectangle($img, 560, 360, 640, 440, $eyeColor);
break;
default:
imagefilledellipse($img, 400, 400, 70, 70, $eyeColor);
imagefilledellipse($img, 600, 400, 70, 70, $eyeColor);
}
$rarity = $i < 3 ? 'common' : ($i < 5 ? 'rare' : 'legendary');
$filename = $this->layersDir . "/eyes/eyes_{$rarity}_{$i}.png";
imagepng($img, $filename);
imagedestroy($img);
}
echo "生成眼睛图层完成\n";
}
public function generateMouths() {
$styles = ['smile', 'grin', 'frown', 'surprised', 'neutral'];
foreach ($styles as $i => $style) {
$img = imagecreatetruecolor(1000, 1000);
imagesavealpha($img, true);
$transparent = imagecolorallocatealpha($img, 0, 0, 0, 127);
imagefill($img, 0, 0, $transparent);
$mouthColor = imagecolorallocate($img, 150, 50, 50);
switch ($style) {
case 'smile':
imagearc($img, 500, 600, 200, 100, 0, 180, $mouthColor);
break;
case 'grin':
imagefilledellipse($img, 500, 600, 200, 100, $mouthColor);
break;
case 'frown':
imagearc($img, 500, 700, 200, 100, 180, 360, $mouthColor);
break;
case 'surprised':
imagefilledellipse($img, 500, 650, 50, 80, $mouthColor);
break;
default:
imageline($img, 400, 650, 600, 650, $mouthColor);
}
$rarity = $i < 3 ? 'common' : ($i < 4 ? 'rare' : 'epic');
$filename = $this->layersDir . "/mouth/mouth_{$rarity}_{$i}.png";
imagepng($img, $filename);
imagedestroy($img);
}
echo "生成嘴巴图层完成\n";
}
public function generateAccessories() {
$items = ['crown', 'hat', 'glasses', 'chain', 'hat_rare', 'crown_legendary'];
foreach ($items as $i => $item) {
$img = imagecreatetruecolor(1000, 1000);
imagesavealpha($img, true);
$transparent = imagecolorallocatealpha($img, 0, 0, 0, 127);
imagefill($img, 0, 0, $transparent);
$color = imagecolorallocate($img, 255, 215, 0);
switch ($item) {
case 'crown':
imagefilledpolygon($img, [400,300, 450,200, 500,300, 550,200, 600,300], 5, $color);
break;
case 'hat':
imagefilledellipse($img, 500, 300, 300, 100, $color);
imagefilledrectangle($img, 420, 250, 580, 380, $color);
break;
case 'glasses':
imagesetthickness($img, 5);
imagearc($img, 400, 400, 100, 100, 0, 360, $color);
imagearc($img, 600, 400, 100, 100, 0, 360, $color);
break;
case 'chain':
imagesetthickness($img, 10);
imageline($img, 400, 700, 600, 700, $color);
imagefilledellipse($img, 500, 700, 30, 30, $color);
break;
case 'hat_rare':
imagefilledellipse($img, 500, 250, 250, 50, $color);
imagefilledrectangle($img, 450, 200, 550, 350, $color);
break;
case 'crown_legendary':
$points = [350,300, 400,150, 450,250, 500,100, 550,250, 600,150, 650,300];
imagefilledpolygon($img, $points, 7, $color);
break;
}
$rarity = strpos($item, 'legendary') !== false ? 'legendary' : (strpos($item, 'rare') !== false ? 'rare' : 'common');
$filename = $this->layersDir . "/accessory/acc_{$rarity}_{$i}.png";
imagepng($img, $filename);
imagedestroy($img);
}
echo "生成装饰品图层完成\n";
}
private function hexToRgb($hex) {
$hex = str_replace('#', '', $hex);
return [hexdec(substr($hex, 0, 2)), hexdec(substr($hex, 2, 2)), hexdec(substr($hex, 4, 2))];
}
private function getStarPoints($points, $radius, $centerX, $centerY) {
$coords = [];
for ($i = 0; $i < $points * 2; $i++) {
$angle = deg2rad($i * 180 / $points);
$r = $i % 2 == 0 ? $radius : $radius * 0.4;
$coords[] = $centerX + $r * cos($angle);
$coords[] = $centerY + $r * sin($angle);
}
return $coords;
}
public function generateAll() {
$this->generateBackgrounds();
$this->generateBodies();
$this->generateEyes();
$this->generateMouths();
$this->generateAccessories();
echo "所有示例图层生成完成!\n";
}
}
// 运行图层生成器
$creator = new LayerCreator();
$creator->generateAll();
?>
使用方法
-
准备环境
# 确保PHP已安装并启用GD库 php -m | grep gd
-
创建目录结构
project/ ├── generate_nft.php # 主生成脚本 ├── create_layers.php # 图层生成脚本 └── layers/ # 图层目录 -
运行脚本
# 1. 先生成示例图层 php create_layers.php
运行NFT生成器
php generate_nft.php
4. **查看输出**
my_nft_collection/ ├── nft_1.png ├── nft_1.json ├── nft_2.png ├── nft_2.json ├── ... ├── collection.json └── ...
## 高级功能
### 1. 自定义元数据格式
```php
// 添加更多属性
$attributes[] = ['display_type' => 'number', 'trait_type' => 'Level', 'value' => rand(1, 100)];
批量大小控制
// 分批次生成 $generator->generateBatch(200); // 先生成200个 $generator->generateBatch(300); // 再生成300个
集成智能合约
// 可以使用 ethers.js 或 web3.js 与合约交互 $whitelist = ['0x...', '0x...']; // 白名单地址
这个脚本为您提供了一个功能完整的NFT生成系统,您可以根据需要调整图层、添加更多属性、集成区块链功能等,记住要合理管理图层资源,确保每个图层都有足够的多样性!
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播