2014-03-18 40 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