php怎么合并图片并变动部分颜色
admin
2023-06-14 06:22:10
0

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

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

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

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

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

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

php怎么合并图片并变动部分颜色

图片要求:

  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怎么合并图片并变动部分颜色

相关内容

热门资讯

中国驻朝鲜大使馆:跨境赌博举报... 跨境赌博严重危害人民群众合法权益,严重危害经济安全、社会稳定和国家形象。希望广大海外中国公民认清跨境...
最高法发布典型案例,对虐待残害... 为推动家庭保护关口前移,督促监护人履职尽责,今天,最高人民法院发布防范和惩治家庭内部侵害未成年人合法...
新闻1+1丨在轨驻留延长至一年... 神二十三发射圆满成功,航天员乘组顺利进驻“天宫”。此番出征,他们肩负着怎样的新任务?首位香港航天员黎...
漳州杨梅被“封杀”背后 5月24日晚,福建漳州龙海区的问责通报,为一场持续发酵近十天的杨梅危机,写下了一个阶段性的注脚。6个...
洛阳入选!中央财政支持实施城市... 近日,财政部办公厅、住房城乡建设部办公厅联合发布通知,开展2026年度中央财政支持实施城市更新行动。...
日本“狮子”号渔船非法进入中国... 中国海警局新闻发言人姜略表示,5月26日,日本“狮子”号渔船非法进入中国钓鱼岛领海,中国海警舰艇依法...
日专家:日菲加强军事合作旨在牵... 据凤凰卫视报道,菲律宾总统马科斯自5月26日起对日本展开正式访问,日菲两国预计就强化安保合作深入交换...
伊朗伊斯兰革命卫队称击落一架美... 伊朗伊斯兰革命卫队公共关系部门26日发表声明称,革命卫队在波斯湾的伊朗领空击落一架美军MQ-9型“死...
伊朗最高领袖称美国在中东将不再... △伊朗最高领袖穆杰塔巴·哈梅内伊(资料图)据伊朗方面5月26日消息,伊朗最高领袖穆杰塔巴·哈梅内伊当...
韩国首尔一高架桥拆除现场发生坍... 据韩联社报道,当地时间5月26日下午2时32分许,韩国首尔市内一座高架桥拆除现场发生坍塌事故,已造成...