如何在PHP中绘制稍微倾斜的渐变填充?

3
我发现以下函数可以在PHP中绘制垂直渐变。然而,许多网页设计师喜欢将渐变的光源设置为左上角,以使渐变看起来更加逼真。那么,如何稍微改变垂直渐变的角度,使其成为轻微的渐变呢?我不想完全过度,只是在垂直渐变向下进行时稍微向右移动一点。
<?php

function hex2rgb($sColor) {
    $sColor = str_replace('#','',$sColor);
    $nLen = strlen($sColor) / 3;
    $anRGB = array();
    $anRGB[]=hexdec(str_repeat(substr($sColor,0,$nLen),2/$nLen));
    $anRGB[]=hexdec(str_repeat(substr($sColor,$nLen,$nLen),2/$nLen));
    $anRGB[]=hexdec(str_repeat(substr($sColor,2*$nLen,$nLen),2/$nLen));
    return $anRGB;
}

$nWidth = 960;
$nHeight = 250;
$sStartColor = '#2b8ae1';
$sEndColor = '#0054a1';
$nStep = 1;

$hImage = imagecreatetruecolor($nWidth,$nHeight);
$nRows = imagesy($hImage);
$nCols = imagesx($hImage);
list($r1,$g1,$b1) = hex2rgb($sStartColor);
list($r2,$g2,$b2) = hex2rgb($sEndColor);
$nOld_r = 0; $nOld_g = 0; $nOld_b = 0;
for ( $i = 0; $i < $nRows; $i=$i+1+$nStep ) {
    $r = ( $r2 - $r1 != 0 ) ? intval( $r1 + ( $r2 - $r1 ) * ( $i / $nRows ) ): $r1;
    $g = ( $g2 - $g1 != 0 ) ? intval( $g1 + ( $g2 - $g1 ) * ( $i / $nRows ) ): $g1;
    $b = ( $b2 - $b1 != 0 ) ? intval( $b1 + ( $b2 - $b1 ) * ( $i / $nRows ) ): $b1;
    if ( "$nOld_r,$nOld_g,$nOld_b" != "$r,$g,$b") {
        $hFill = imagecolorallocate( $hImage, $r, $g, $b );
    }
    imagefilledrectangle($hImage, 0, $i, $nCols, $i+$nStep, $hFill);
    $nOld_r= $r;
    $nOld_g= $g;
    $nOld_b= $b;
}
header("Content-type: image/png");
imagepng($hImage);
2个回答

1

我不会做几何运算 - 但是可以创建垂直渐变作为一个更大的图像,然后旋转和裁剪它:

...
$degrees = -5;
$newImage = imagecreatetruecolor($nWidth, $nHeight);
$rotated = imagerotate($hImage, $degrees, 0);
imagecopy($newImage, $rotated, 0, 0, $x, $y, $width, $height)

在我的PHP 5.2.4中没有imagerotate()函数。php.net页面上说,这个函数是GD库函数之一,有内存泄漏问题,并且不包含在Ubuntu中(这是我正在使用的操作系统)。还有其他选择吗? - Volomike
我从未使用过这个函数,但有人发布了一个替代的imageRotate函数来解决这个问题,看起来非常有前途。 - thetaiko
我尝试了很多种方法,发现imagerotateEquivalent()起作用了!谢谢thetaiko。 - Volomike
只是想补充一下thetaiko的建议,如果我在代码开头将$nWidth和$nHeight的值加倍,然后将$x设置为25,$y设置为171,在他的代码中将$width和$height设置为$nWidth和$nHeight的一半,使用imagerotateEquivalent函数可以完全解决这个问题。 - Volomike
这不是线程安全的,但如果安装了ImageMagick,PHP可以在Linux上调用并执行此命令:convert -size 1000x400 gradient:#bfb-#4b4 -rotate -5 +repage -crop '960x250+25+100' greenbar.png。然而,PHP确实有一个ImageMagick扩展来在内部执行此操作。 - Volomike

1
以下代码片段比GD库快得多,而且没有那么复杂。不过你需要安装PHP的ImageMagick扩展。
$oImage = new Imagick();
$oImage->newPseudoImage(1000, 400, 'gradient:#09F-#048' );
$oImage->rotateImage(new ImagickPixel(), -3);
$oImage->cropImage(960, 250, 25, 100);
$oImage->setImageFormat('png');
header( "Content-Type: image/png" );
echo $oImage;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接