最近看到很多大公司都开始做宠物链形式多样化, 最特别的是宠物分有多种部位然后再不同组合并生成出对应的宠物图片, 看起来比较高大尚, 不过发现有些是使用 SVG 矢量图片, 这类图片理论上无失真可以随意放大性能略受影响, 编辑方便容易调整, 但操作麻烦, 如果直接使用图片那么操作会容易些
php 的 GD 库提供了很多基础图片操作功能, 可以分为两大类:
真彩图操作: 支持直接透明图片处理, 但不支持颜色变换, 允许画入新内容
调色板图操作: 支持指定颜色为透明, 并且支持颜色变换, 允许画入新内容
两种类型的图片可以相互转换, 如果原图片有透明块尽可能避免直接转为调色板图 (透明块容易出现未知异常) 但可以合并到调色板图中从而保留了原图的透明, 如果在调色板图中指定了某个色值为透明则在生成图片后这个色值为透明的
如果只使用 GD 库在不需要变换图片颜色的时候基本上不需要使用调色板, 相反需要有变换图片颜色时则只能使用调色板
这里以生成小怪物为目标来操作变换小怪物的颜色:
首先需要准备 5 个基本图片元素:
图片要求:
所有图片最好全新画的(最好使用矢量图生成的)
eyes.png 除了眼睛体外全部透明化处理
fleck.png 除了斑纹休外全部透明化处理
mouth.png 除了嘴巴体外全部透明化处理
shadow.png 体型内无颜色透明化处理, 体型外全部使用白色
shape.png 不要有透明内容
所有需要替换颜色的色值在其它所所部位最好都不要出现
下面给一个生成不同颜色宠物的示例代码:
- $image = imagecreatefrompng(shape.png); // 取体型图片
- list($src_w, $src_h) = getimagesize(shape.png); // 获取宽高度
- imagetruecolortopalette($image, false, 256); // 转换为调色板图像
- $color_index = imagecolorat($image, 276, 621); // 获取颜色索引值(体型颜色)
- imagecolorset($image, $color_index, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255)); // 修改颜色
- $color_index = imagecolorat($image, 450, 780); // 获取颜色索引值(肚皮颜色)
- imagecolorset($image, $color_index, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255)); // 修改颜色
- // 这段处理非常重要, 如果直接转换为真彩图会造成后续图片合并异常
- $_image = imagecreatetruecolor($src_w, $src_h); // 创建真彩图
- $color = imagecolorallocate($_image, 255, 255, 255); // 分配颜色
- imagefill($_image, 0, 0, $color); // 填充
- imagecopyresampled($_image, $image, 0, 0, 0, 0, $src_w, $src_h, $src_w, $src_h); // 合并修改后的图片
- $image = $_image;
- /* 斑纹处理 */
- $image_fleck = imagecreatefrompng(fleck.png); // 取斑纹图片
- imagecopyresampled($image, $image_fleck, 0, 0, 0, 0, $src_w, $src_h, $src_w, $src_h); // 合并
- $color_index = imagecolorat($image, 385, 925); // 获取颜色索引值(斑纹颜色)
- imagecolorset($image, $color_index, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255)); // 修改颜色
- /* 体型阴影处理 */
- imagecopyresampled($image, imagecreatefrompng(test1/shadow.png), 0, 0, 0, 0, $src_w, $src_h, $src_w, $src_h);
- /* 嘴巴处理 */
- imagecopyresampled($image, imagecreatefrompng(test1/mouth.png), 0, 0, 0, 0, $src_w, $src_h, $src_w, $src_h);
- /* 眼睛处理 */
- $image_eyes = imagecreatefrompng(eyes.png); // 取斑纹图片
- imagecopyresampled($image, $image_eyes, 0, 0, 0, 0, $src_w, $src_h, $src_w, $src_h); // 合并
- $color_index = imagecolorat($image_eyes, 285, 335); // 获取颜色索引值(眼睛颜色)
- imagecolorset($image, $color_index, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255)); // 修改颜色
- // 添加背景
- $color_index = imagecolorat($image, 435, 300); // 获取颜色索引值(背景颜色)
- imagefilltoborder($image, 0, 0, $color_index, imagecolorallocate($image, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255)));
- imagesavealpha($image, true); // 保存 alpha 通道信息
- header(Content-type:image/png);
- imagepng($image, null, 9);
- imagedestroy($image);
注意: 替换图片颜色时需要取出调色板颜色的索引值函数 imagecolorat 就是取颜色的索引值(想获取哪个颜色给出颜色的任意坐标值即可), 由于我测试时图片 1304 X 1412 所以代码中坐标值都比较大
执行结果如下:
来源: http://www.bubuko.com/infodetail-2544121.html