设为首页 收藏本站
查看: 813|回复: 0

[经验分享] php使用GD库合并简单图片并变动部分颜色

[复制链接]

尚未签到

发表于 2018-12-12 09:42:46 | 显示全部楼层 |阅读模式
  最近看到很多大公司都开始做宠物链形式多样化,最特别的是宠物分有多种部位然后再不同组合并生成出对应的宠物图片,看起来比较高大尚,不过发现有些是使用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)); //修改颜色
// 这段处理非常重要,如果直接转换为真彩图会造成后续有透明图片合并异常
// 如果直接使用 **imagepalettetotruecolor**  函数也会有异常,可能是调色板数据未清除造成的
// 如同把图片写到文件再读取一样,得到真彩图
$_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); //合并
imagetruecolortopalette($image, false, 256); //转换为调色板图像,只有调色板才能换颜色
$color_index = imagecolorat($image, 385, 925); //获取颜色索引值(斑纹颜色)
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;
/* 体型阴影处理 */
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'); //取斑纹图片
imagetruecolortopalette($image, false, 256); //转换为调色板图像,只有调色板才能换颜色
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)); //修改颜色
// 如同把图片写到文件再读取一样,得到真彩图,与上面一样,如果不这样处理后续的透明图合并将会有异常
$_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;
//添加背景
$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 所以代码中坐标值都比较大,还有颜色替换会有锯齿这是因为像素点为矩形造成的当图片有一定大小时不会影响太多美观。
  执行结果如下:





运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-650400-1-1.html 上篇帖子: CentOS6安装配置PHP5.6(LNMP环境) 下篇帖子: php函数simplexml_load_string转xml的小坑
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表