2014-03-18 148 views
3

在我的網站上,我有一個PHP腳本,它基於$_GET查詢將​​變成同一圖像的重新着色版本。查詢爲07a的示例爲available here透明png上的漸變疊加

這裏是PHP腳本,做這樣的:

<?php 

    if (isset($_GET['color']) && $_GET['color'] !== "") $color = preg_match('/^([a-fA-F0-9]{3}|[a-fA-F0-9]{6})$/',$_GET['color']) ? $_GET['color'] : '777777'; 
    else $color = '000000'; 

    if (strlen($color) === 3) $color = $color[0].$color[0].$color[1].$color[1].$color[2].$color[2]; 

    $color = str_split($color,2); 
    foreach ($color as $k=>$m){ $color[$k] = intval($color[$k],16); } 

    $img = imageCreateFromPng('splat-base.png'); 
    $background = imagecolorallocate($img, 0, 0, 0); 
    imagecolortransparent($img, $background); 
    imagealphablending($img, false); 
    imagesavealpha($img, true); 

    imagefilter($img, IMG_FILTER_COLORIZE, intval($color[0] - 255 ,16), $color[1], $color[2]); 

    header('Content-type: image/png'); 
    imagePng($img); 
    imagedestroy($img); 
    exit; 
?> 

的實際工作是由imagefilter函數完成,剩下的只是保持透明度。我想要做的是,通過$_GET發送2個顏色值,並使用給定的顏色值創建應用於圖像的從上到下的漸變。下面是與值是08f0a7一個例子(較淺的顏色將總是第一個):

gradient splat

的一種可能的解決方案,我認爲是產生相同大小的圖像作爲我splat-base.png(1000× 1000像素)與漸變,然後用一些欺騙適用於圖示圖像,但我不知道如何去產生該漸變圖像或如何將其應用於splat圖像。

我沒有像ImageMagick那樣安裝PHP擴展的能力,所以我必須使用PHP和只使用這些庫的內置函數。

回答

1

所以,我googled如何在PHP中創建圖像漸變。這個想法是,你定義了開始和結束顏色,並且定義了一個步長$stepSize = ($end-$start)/($imgHeight)。您製作一個for循環,並在循環的每個步驟中,創建一個與圖像一樣寬的1像素高的矩形,並將其顏色設置爲$start+$i*$stepSize。這個想法和代碼,我發現這裏:

http://www.geekthis.net/blog/87/php-gradient-images-rectangle-gd

這代碼創建一個線性漸變的新形象。對於你的情況,我運行這個基本的想法:從你的源圖像中刪除1個像素行,並將IMG_FILTER_COLORIZE每行刪除漸變的顏色。

下面是代碼:

<?php 

//move alpha preserving code to its own function 
//since it is used several times 
function preserveAlpha(&$img) { 
    $background = imagecolorallocate($img, 0, 0, 0); 
    imagecolortransparent($img, $background); 
    imagealphablending($img, false); 
    imagesavealpha($img, true); 
} 

$img = imagecreatefrompng('splat-base.png'); 
preserveAlpha($img); 
//grab width and height 
$width = imagesx($img); 
$height = imagesy($img); 

//the final image 
$final = imagecreatetruecolor($width, $height); 

preserveAlpha($final); 

//start and end values of the gradient 
$start = $_GET['start']; 
$end = $_GET['end']; 

//convert 3 color codes to 6 
if (strlen($start) == 3) { 
    $start = $start[0] . $start[0] . $start[1] . $start[1] . $start[2] . $start[2]; 
} 

if (strlen($end) == 3) { 
    $end = $end[0] . $end[0] . $end[1] . $end[1] . $end[2] . $end[2]; 
} 


//make sure the lighter color is first 

$starthex = intval($start, 16); 
$endhex = intval($end, 16); 
if ($endhex > $starthex) { 
    //then we need to flip 
    $temp = $end; 
    $end = $start; 
    $start = $temp; 
} 

//convert from hex to rgb 
$s = array(
    hexdec(substr($start, 0, 2)), 
    hexdec(substr($start, 2, 2)), 
    hexdec(substr($start, 4, 2)) 
); 
$e = array(
    hexdec(substr($end, 0, 2)), 
    hexdec(substr($end, 2, 2)), 
    hexdec(substr($end, 4, 2)) 
); 

//the for loop. go through each 1 pixel row of the image, 
//shave it off, apply a filter, and append it to our new image 

for ($i = 0; $i < $height; $i++) { 
    //grab the $ith row off of the image 
    $pixelRow = imagecreatetruecolor($width, 1); 
    preserveAlpha($pixelRow); 
    imagecopy($pixelRow, $img, 0, 0, 0, $i, $width, 1); 
    //calculate the next color in the gradient 
    $r = intval($s[0] - ((($s[0] - $e[0])/$height) * $i)); 
    $g = intval($s[1] - ((($s[1] - $e[1])/$height) * $i)); 
    $b = intval($s[2] - ((($s[2] - $e[2])/$height) * $i)); 
    //apply the filter 
    imagefilter($pixelRow, IMG_FILTER_COLORIZE, $r - 255, $g, $b); 
    //append it to our new iamge 
    imagecopy($final, $pixelRow, 0, $i, 0, 0, $width, 1); 
} 

header('Content-Type: image/png'); 
imagepng($final); 


/* Some Cleanup */ 
imagedestroy($final); 

exit; 
?> 
+1

這似乎是一個可行的解決方案。謝謝你的回答! – SeinopSys