Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/246.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用PHP将一个漂亮的径向透明渐变应用于图像?_Php_Image_File Upload_Gd_Gradient - Fatal编程技术网

如何使用PHP将一个漂亮的径向透明渐变应用于图像?

如何使用PHP将一个漂亮的径向透明渐变应用于图像?,php,image,file-upload,gd,gradient,Php,Image,File Upload,Gd,Gradient,如何指定一个图像并在其径向淡出的位置应用径向透明渐变。我没有安装Imagemagick 边缘示例: 简介 我认为您应该安装Imagemagick,因为您需要的是一个简单的渐晕效果,您可以轻松地使用(convert input.jpg-background black-vignette 70x80 output.png)而不必循环每个像素,在处理大型图像时可能会非常慢 原始图像 $file = __DIR__ . "/golf.jpg"; 效果1 $image = new imagick($f

如何指定一个图像并在其径向淡出的位置应用径向透明渐变。我没有安装Imagemagick

边缘示例:


简介

我认为您应该安装Imagemagick,因为您需要的是一个简单的
渐晕
效果,您可以轻松地使用(
convert input.jpg-background black-vignette 70x80 output.png
)而不必循环每个像素,在处理大型图像时可能会非常慢

原始图像

$file = __DIR__ . "/golf.jpg";

效果1

$image = new imagick($file);
$image->vignetteImage(20, 20, 40, - 20);
header("Content-Type: image/png");
echo $image;

效果2

$image = new imagick($file);
$image->vignetteImage(100, 100, 200, 200);
header("Content-Type: image/png");
echo $image;

带有GD的渐晕图

如果你被迫使用GB。。。你可以用这个

唯一的缺点是图像必须与遮罩大小相同,才能使效果看起来很酷

结论


如果这就是你所说的“径向透明梯度”(radial transparent gradient),那么我建议你使用
ImageMagic
,如果不是至少是女士的话,那么这幅画很可爱。

多亏了@Baba链接的功能,我能够修改脚本,以实现半透明的渐晕效果

<?php
class PhotoEffect
{
  private $_photoLocation;
  private $_width;
  private $_height;
  private $_type;

  private $_originalImage;
  private $_afterImage;

  /**
   * Load image URL in constructor
   */
  final public function __construct($photoLocation)
  {
    $this->_photoLocation = $photoLocation;
    if (!$size = @getimagesize($this->_photoLocation)){
      throw new Exception('Image cannot be handled');
    }
    $this->_width = $size[0];
    $this->_height = $size[1];
    $this->_type = $size[2];


    switch ( $this->_type ) {
      case IMAGETYPE_GIF:
        $this->_originalImage = imagecreatefromgif($this->_photoLocation);
      break;
      case IMAGETYPE_JPEG:
        $this->_originalImage = imagecreatefromjpeg($this->_photoLocation);
      break;
      case IMAGETYPE_PNG:
        $this->_originalImage = imagecreatefrompng($this->_photoLocation);
      break;
      default:
        throw new Exception('Unknown image type');
    }
  }

  /**
   * Destroy created images
   */
  final private function __destruct() {
     if (!empty($this->_originalImage))
     {
       imagedestroy($this->_originalImage);
     }

     if (!empty($this->_afterImage))
     {
       imagedestroy($this->_afterImage);
     }
   }

  /**
   * Apply vignette effect
   */
  final public function Vignette($sharp=0.4, $level=1, $alpha=1)
  {
    if (empty($this->_originalImage))
    {
      throw new Exception('No image');
    }

    if (!is_numeric($sharp) || !($sharp>=0 && $sharp<=10))
    {
      throw new Exception('sharp must be between 0 and 10');            
    }

    if (!is_numeric($level) || !($level>=0 && $level<=1))
    {
      throw new Exception('level must be between 0 and 10');            
    }

    if (!is_numeric($alpha) || !($alpha>=0 && $alpha<=10))
    {
      throw new Exception('alpha must be between 0 and 1');         
    }

    $this->_afterImage = imagecreatetruecolor($this->_width, $this->_height);
    imagesavealpha($this->_afterImage, true);
    $trans_colour = imagecolorallocatealpha($this->_afterImage, 0, 0, 0, 127);
    imagefill($this->_afterImage, 0, 0, $trans_colour);


    for($x = 0; $x < $this->_width; ++$x){
      for($y = 0; $y < $this->_height; ++$y){  
        $index = imagecolorat($this->_originalImage, $x, $y);
        $rgb = imagecolorsforindex($this->_originalImage, $index);

        $l = sin(M_PI / $this->_width * $x) * sin(M_PI / $this->_height * $y);
        $l = pow($l, $sharp);

        $l = 1 - $level * (1 - $l);

        $rgb['red'] *= $l;
        $rgb['green'] *= $l;
        $rgb['blue'] *= $l;
        $rgb['alpha'] = 127 - (127 * ($l*$alpha));


        $color = imagecolorallocatealpha($this->_afterImage, $rgb['red'], $rgb['green'], $rgb['blue'], $rgb['alpha']);

        imagesetpixel($this->_afterImage, $x, $y, $color);  
      }
    }

  }


  /**
   * Ouput PNG with correct header
   */
  final public function OutputPng()
  {
    if (empty($this->_afterImage))
    {
      if (empty($this->_originalImage))
      {
        throw new Exception('No image');
      }
      $this->_afterImage = $this->_originalImage;
    }

    header('Content-type: image/png');
    imagepng($this->_afterImage);
  }

  /**
   * Save PNG
   */
  final public function SavePng($filename)
  {
    if (empty($filename)) {
        throw new Exception('Filename is required');
    }

    if (empty($this->_afterImage))
    {
      if (empty($this->_originalImage))
      {
        throw new Exception('No image');
      }
      $this->_afterImage = $this->_originalImage;
    }

    imagepng($this->_afterImage, $filename);
  }

}


/**
 * How to use
 */
$effect = new PhotoEffect('test.jpg');
$effect->Vignette();
$effect->OutputPng();
?>


我在他们的服务器上只能找到一个图像,所以没有那么大。

我知道这是一个与PHP相关的问题,但是使用javascript和html5画布元素可以实现很好的透明渐变

所以我写了一个小脚本:

  • 检测支持canvas元素的浏览器,如果浏览器不支持canvas(幸运的是只剩下少数用户),则显示完整图像
  • 创建画布并在图像后附加元素
  • 可以为自定义形状更改create_gradient()函数中的参数
  • 它适用于所有流行的图像格式(使用.jpg、.bmp、.gif、.png测试)
  • 您可以添加更多的“ColorStop”(
    grd.addColorStop()
    )来更改渐变流
脚本

window.onload = function() {
    if ( typeof CanvasRenderingContext2D !== 'function' ) {
        document.getElementById('gradient-image').style.visibility = "visible";
        return;
    }

    var image = document.getElementById('gradient-image');

    // these are the default values, change them for custom shapes
    create_gradient( image, image.width/2, image.height/2, image.height/4, image.width/2, image.height/2, image.height/2 );
}

function create_gradient( image, start_x, start_y, start_r, end_x, end_y, end_r ){

    var canvas = document.createElement('canvas');

    var parent = image.parentNode;
    if ( parent.lastchild == image ) parent.appendChild(canvas);
    else parent.insertBefore(canvas, image.nextSibling);

    canvas.width  = image.width;
    canvas.height = image.height;

    var context = canvas.getContext('2d');

    var grd = context.createRadialGradient( start_x, start_y, start_r, end_x, end_y, end_r );
    grd.addColorStop(0, 'rgba(0,0,0,1)' );
    // grd.addColorStop(0.2, 'rgba(0,0,0,0.8)' );
    grd.addColorStop(1, 'rgba(0,0,0,0)' );

    context.fillStyle = grd;
    context.fillRect(0, 0, image.width, image.height);

    var grd_data = context.getImageData(0, 0, image.width, image.height);

    context.drawImage( image, 0, 0);
    var img_data = context.getImageData(0, 0, image.width, image.height);

    var grd_pixel = grd_data.data;
    var img_pixel = img_data.data;
    var length = img_data.data.length

    for ( i = 3; i < length; i += 4 ) {
        img_pixel[i] = grd_pixel[i];
    }
    context.putImageData(img_data, 0, 0);
}

这个php库中还有一个vignette过滤器,它只使用GD:


使用CSS:更糟糕的情况是,您可以使用GD原语绘制PNG圆形渐变,但不应用颜色偏移,而是应用不透明度偏移。然后,将该PNG覆盖在当前图像上。我没有这方面的任何代码,但它可能会给你一些搜索短语的新想法。哈哈,真的,谢谢你的回复,但图像渐变正在淡出白色,不透明。难道这根本不可能吗?如果你注意到文章中的边缘图像可以淡出任何背景。你可以很容易地在GB版本中更改背景。。。。你能使用Imagemagic吗?考虑到这篇文章(已经有几个月了,但仍然),IE8或更低版本上仍然有超过25%的内容。所以,即使我怀疑已经发生了大幅下降到15%的情况,你也在告诉很多人,他们对你的网站来说还不够好。考虑到canvas/javascript在android设备和较旧的iOS设备上的速度非常慢,我绝对不会使用javascript来处理类似的事情。我不确定是否会被否决。我已经将整个代码更新为一个类。我这样做是为了能够添加其他效果,还尝试了一个常规的PNG文件,得到了以下结果:
PHP致命错误:未捕获异常“exception”,消息为“Image cannot handled”
,当
@getimagesize($this->\u photoLocation)
失败时会发生这种情况。这是一个常规的PHP函数,所以您确定输入了正确的路径吗?你可以去掉@来看看真正的警告哦是的是的,真可怜。明亮的我尝试使用
file\u put\u contents
但未成功,我如何将其保存到png文件或其他文件中?
<?php
class PhotoEffect
{
  private $_photoLocation;
  private $_width;
  private $_height;
  private $_type;

  private $_originalImage;
  private $_afterImage;

  /**
   * Load image URL in constructor
   */
  final public function __construct($photoLocation)
  {
    $this->_photoLocation = $photoLocation;
    if (!$size = @getimagesize($this->_photoLocation)){
      throw new Exception('Image cannot be handled');
    }
    $this->_width = $size[0];
    $this->_height = $size[1];
    $this->_type = $size[2];


    switch ( $this->_type ) {
      case IMAGETYPE_GIF:
        $this->_originalImage = imagecreatefromgif($this->_photoLocation);
      break;
      case IMAGETYPE_JPEG:
        $this->_originalImage = imagecreatefromjpeg($this->_photoLocation);
      break;
      case IMAGETYPE_PNG:
        $this->_originalImage = imagecreatefrompng($this->_photoLocation);
      break;
      default:
        throw new Exception('Unknown image type');
    }
  }

  /**
   * Destroy created images
   */
  final private function __destruct() {
     if (!empty($this->_originalImage))
     {
       imagedestroy($this->_originalImage);
     }

     if (!empty($this->_afterImage))
     {
       imagedestroy($this->_afterImage);
     }
   }

  /**
   * Apply vignette effect
   */
  final public function Vignette($sharp=0.4, $level=1, $alpha=1)
  {
    if (empty($this->_originalImage))
    {
      throw new Exception('No image');
    }

    if (!is_numeric($sharp) || !($sharp>=0 && $sharp<=10))
    {
      throw new Exception('sharp must be between 0 and 10');            
    }

    if (!is_numeric($level) || !($level>=0 && $level<=1))
    {
      throw new Exception('level must be between 0 and 10');            
    }

    if (!is_numeric($alpha) || !($alpha>=0 && $alpha<=10))
    {
      throw new Exception('alpha must be between 0 and 1');         
    }

    $this->_afterImage = imagecreatetruecolor($this->_width, $this->_height);
    imagesavealpha($this->_afterImage, true);
    $trans_colour = imagecolorallocatealpha($this->_afterImage, 0, 0, 0, 127);
    imagefill($this->_afterImage, 0, 0, $trans_colour);


    for($x = 0; $x < $this->_width; ++$x){
      for($y = 0; $y < $this->_height; ++$y){  
        $index = imagecolorat($this->_originalImage, $x, $y);
        $rgb = imagecolorsforindex($this->_originalImage, $index);

        $l = sin(M_PI / $this->_width * $x) * sin(M_PI / $this->_height * $y);
        $l = pow($l, $sharp);

        $l = 1 - $level * (1 - $l);

        $rgb['red'] *= $l;
        $rgb['green'] *= $l;
        $rgb['blue'] *= $l;
        $rgb['alpha'] = 127 - (127 * ($l*$alpha));


        $color = imagecolorallocatealpha($this->_afterImage, $rgb['red'], $rgb['green'], $rgb['blue'], $rgb['alpha']);

        imagesetpixel($this->_afterImage, $x, $y, $color);  
      }
    }

  }


  /**
   * Ouput PNG with correct header
   */
  final public function OutputPng()
  {
    if (empty($this->_afterImage))
    {
      if (empty($this->_originalImage))
      {
        throw new Exception('No image');
      }
      $this->_afterImage = $this->_originalImage;
    }

    header('Content-type: image/png');
    imagepng($this->_afterImage);
  }

  /**
   * Save PNG
   */
  final public function SavePng($filename)
  {
    if (empty($filename)) {
        throw new Exception('Filename is required');
    }

    if (empty($this->_afterImage))
    {
      if (empty($this->_originalImage))
      {
        throw new Exception('No image');
      }
      $this->_afterImage = $this->_originalImage;
    }

    imagepng($this->_afterImage, $filename);
  }

}


/**
 * How to use
 */
$effect = new PhotoEffect('test.jpg');
$effect->Vignette();
$effect->OutputPng();
?>
window.onload = function() {
    if ( typeof CanvasRenderingContext2D !== 'function' ) {
        document.getElementById('gradient-image').style.visibility = "visible";
        return;
    }

    var image = document.getElementById('gradient-image');

    // these are the default values, change them for custom shapes
    create_gradient( image, image.width/2, image.height/2, image.height/4, image.width/2, image.height/2, image.height/2 );
}

function create_gradient( image, start_x, start_y, start_r, end_x, end_y, end_r ){

    var canvas = document.createElement('canvas');

    var parent = image.parentNode;
    if ( parent.lastchild == image ) parent.appendChild(canvas);
    else parent.insertBefore(canvas, image.nextSibling);

    canvas.width  = image.width;
    canvas.height = image.height;

    var context = canvas.getContext('2d');

    var grd = context.createRadialGradient( start_x, start_y, start_r, end_x, end_y, end_r );
    grd.addColorStop(0, 'rgba(0,0,0,1)' );
    // grd.addColorStop(0.2, 'rgba(0,0,0,0.8)' );
    grd.addColorStop(1, 'rgba(0,0,0,0)' );

    context.fillStyle = grd;
    context.fillRect(0, 0, image.width, image.height);

    var grd_data = context.getImageData(0, 0, image.width, image.height);

    context.drawImage( image, 0, 0);
    var img_data = context.getImageData(0, 0, image.width, image.height);

    var grd_pixel = grd_data.data;
    var img_pixel = img_data.data;
    var length = img_data.data.length

    for ( i = 3; i < length; i += 4 ) {
        img_pixel[i] = grd_pixel[i];
    }
    context.putImageData(img_data, 0, 0);
}
<img id="gradient-image"src="">
#gradient-image {
    position: absolute;
    visibility: hidden;
}