php使用GD库合并简单图片并变更部分颜色

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

php的GD库提供了不少基础图片操做功能,能够分为两大类:ide

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

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

若是只使用GD库在不须要变换图片颜色的时候基本上不须要使用调色板,相反须要有变换图片颜色时则只能使用调色板。测试

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

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

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库合并简单图片并变更部分颜色

相关文章
相关标签/搜索