0

我想创建一种“灰度除红色以外的一切”效果。为此,我有此代码

<?php
    header('content-type: image/png');
    $image = imagecreatefrompng('a.png');
    imagefilter($image, IMG_FILTER_GRAYSCALE);
    imagepng($image);
    imagedestroy($image);
?>

从这里开始,我计划循环遍历原始的 a.png 像素,并在过滤后在其上设置任何红色阴影。

4

2 回答 2

2

您是在问如何判断像素是否为红色?您可以使用imagecolorat

$col = imagecolorat($image, $x, $y);

这是 RGB 中的颜色,所以 '($col >> 16) & 0xFF' 是红色分量。现在您不能只检查红色组件,因为其他组件可能会将其更改为更紫色或橙色,这取决于您想要走多远,但如果红色多于绿色或蓝色,则类似这样的事情将是真实的:

$r = ($col >> 16) & 0xFF;
$g = ($col >> 8) & 0xFF;
$b = $col & 0xFF;

$limit = 2; // Aim for 2 times more red 

$is_red = ($r / $limit) > ($g + $b);

你可以玩$limit或尝试不同的逻辑。

可能已经有一个 GD 过滤器可以做到这一点,但我不熟悉过滤器。

编辑

这看起来将来可能会派上用场,所以我敲了一个小函数来做到这一点:

function colorInGreyFilter($im, $limit = 1.5, $rgb_choice = 0) { 

  $sx = imagesx($im); 
  $sy = imagesy($im); 

  for ($x = 0; $x < $sx; $x++ ) {
    for ($y = 0; $y < $sy; $y++ ) {

      // Get the color and split the RGB values into an array 
      $col = imagecolorat($im, $x, $y);
      $rgb = array( ($col >> 16) & 0xFF, ($col >> 8) & 0xFF, $col & 0xFF );

      // Get the rgb value we're intested in;
      $trg_col = $rgb[$rgb_choice]; 

      // If the value of the target color is more than $limit times
      // the sum of the other colors then we use that pixel so 
      // we only greyscale the pixel if it's less ...
      if (($trg_col / $limit) < (array_sum($rgb) - $trg_col)) {

        // Use the average of the values as the setting 
        // for the grey scale RGB values
        $avg = (array_sum($rgb) / 3) & 0xFF;;
        $col = ($avg <<16) + ($avg << 8) + $avg;
        imagesetpixel($im, $x, $y, $col);

      }
      /* 
       else { 
         Could have the option of taking a target image that's already 
     filtered, so here we would copy the pixel to the target 
       }
      */
    }
  }
}

这将获取一张图像并将灰度算法应用于除符合标准的像素之外的所有内容。您可以更改限制并选择使用红色、绿色或蓝色作为主要颜色:

colorInGreyFilter($im);        // Greyscale with red highlights (the default)
colorInGreyFilter($im, .5, 1); // Greyscale with lots of green left
colorInGreyFilter($im,  2, 2); // Greyscale with only the bluest blue left

它使用 RGB 值的简单平均值进行灰度化——这可以,但不如 GD 过滤器那么精细——所以一个好的扩展是可选地允许预过滤的目标图像。

于 2013-09-20T03:49:10.550 回答
0

句法

int imagecolorat ( resource $image , int $x , int $y )

返回image指定的图像中指定位置的像素颜色的索引

如果 PHP 是针对 GD 库 2.0 或更高版本编译的,并且图像是真彩色图像,则此函数以整数形式返回该像素的 RGB 值。使用位移和掩码来访问不同的红色、绿色和蓝色分量值

例子:

<?php
$im = imagecreatefrompng("php.png");
$rgb = imagecolorat($im, 10, 15);
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;

var_dump($r, $g, $b);
?>
于 2013-09-20T03:48:57.460 回答