最近看到不少大公司都開始作寵物鍊形式多樣化,最特別的是寵物分有多種部位而後再不一樣組合並生成出對應的寵物圖片,看起來比較高大尚,不過發現有些是使用SVG矢量圖片,這類圖片理論上無失真能夠隨意放大性能略受影響,編輯方便容易調整,但操做麻煩,若是直接使用圖片那麼操做會容易些。php
php的GD庫提供了不少基礎圖片操做功能,能夠分爲兩大類:ide
真彩圖操做:支持直接透明圖片處理,但不支持顏色變換,容許畫入新內容。
調色板圖操做:支持指定顏色爲透明,而且支持顏色變換,容許畫入新內容。函數
兩種類型的圖片能夠相互轉換,若是原圖片有透明塊儘量避免直接轉爲調色板圖(透明塊容易出現未知異常)但能夠合併到調色板圖中從而保留了原圖的透明,若是在調色板圖中指定了某個色值爲透明則在生成圖片後這個色值爲透明的。性能
若是隻使用GD庫在不須要變換圖片顏色的時候基本上不須要使用調色板,相反須要有變換圖片顏色時則只能使用調色板。測試
這裏以生成小怪物爲目標來操做變換小怪物的顏色:code
首先須要準備5個基本圖片元素:blog
圖片要求:索引
下面給一個生成不一樣顏色寵物的示例代碼:圖片
$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 因此代碼中座標值都比較大,還有顏色替換會有鋸齒這是由於像素點爲矩形形成的當圖片有必定大小時不會影響太多美觀。圖片處理
執行結果以下: