PHP使用GD库合并简单图片并变动部分颜色

栏目: PHP · 发布时间: 6年前

内容简介:最近看到很多大公司都开始做宠物链形式多样化,最特别的是宠物分有多种部位然后再不同组合并生成出对应的宠物图片,看起来比较高大尚,不过发现有些是使用SVG矢量图片,这类图片理论上无失真可以随意放大性能略受影响,编辑方便容易调整,但操作麻烦,如果直接使用图片那么操作会容易些。php的GD库提供了很多基础图片操作功能,可以分为两大类:真彩图操作:支持直接透明图片处理,但不支持颜色变换,允许画入新内容。

最近看到很多大公司都开始做宠物链形式多样化,最特别的是宠物分有多种部位然后再不同组合并生成出对应的宠物图片,看起来比较高大尚,不过发现有些是使用SVG矢量图片,这类图片理论上无失真可以随意放大性能略受影响,编辑方便容易调整,但操作麻烦,如果直接使用图片那么操作会容易些。

php的GD库提供了很多基础图片操作功能,可以分为两大类:

真彩图操作:支持直接透明图片处理,但不支持颜色变换,允许画入新内容。

调色板图操作:支持指定颜色为透明,并且支持颜色变换,允许画入新内容。

两种类型的图片可以相互转换,如果原图片有透明块尽可能避免直接转为调色板图(透明块容易出现未知异常)但可以合并到调色板图中从而保留了原图的透明,如果在调色板图中指定了某个色值为透明则在生成图片后这个色值为透明的。

如果只使用GD库在不需要变换图片颜色的时候基本上不需要使用调色板,相反需要有变换图片颜色时则只能使用调色板。

这里以生成小怪物为目标来操作变换小怪物的颜色:

首先需要准备5个基本图片元素:

PHP使用GD库合并简单图片并变动部分颜色

图片要求:

1.所有图片最好全新画的(最好使用矢量图生成的),所有需要变色的原颜色与其它颜色连接处不能有过渡,否则替换颜色后原连接过渡颜色将被保留,影响美观。

2.eyes.png 除了眼睛体外全部透明化处理。

3.fleck.png 除了斑纹休外全部透明化处理。

4.mouth.png 除了嘴巴体外全部透明化处理。

5.shadow.png 体型内无颜色透明化处理,体型外全部使用白色。

6.shape.png 不要有透明内容。

7.所有需要替换颜色的色值在其它所所部位最好都不要出现。

下面给一个生成不同颜色宠物的示例代码:

$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 所以代码中坐标值都比较大,还有颜色替换会有锯齿这是因为像素点为矩形造成的当图片有一定大小时不会影响太多美观。

执行结果如下:

PHP使用GD库合并简单图片并变动部分颜色

Linux公社的RSS地址https://www.linuxidc.com/rssFeed.aspx

本文永久更新链接地址: https://www.linuxidc.com/Linux/2018-09/154487.htm


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

数学与生活(修订版)

数学与生活(修订版)

[日] 远山启 / 吕砚山、李诵雪、马杰、莫德举 / 人民邮电出版社 / 2014-10 / 42.00元

数学是高等智慧生物的共有思维,是对真理的探索,对矛盾的怀疑,但它绝非一门晦涩难懂的学问,非应试目的的数学是纯粹而朴实的智慧。《数学与生活》为日本数学教育改革之作,旨在还原被考试扭曲的数学,为读者呈现数学的真正容颜,消除应试教学模式带来的数学恐惧感。 本书既包含了初等数学的基础内容,又包含了微分、积分、微分方程、费马定理、欧拉公式等高等数学的内容。作者运用了多个学科的知识。结合日常生活和东西方......一起来看看 《数学与生活(修订版)》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

MD5 加密
MD5 加密

MD5 加密工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具