【问题标题】:Can I swap colors in image using GD library in PHP?我可以在 PHP 中使用 GD 库交换图像中的颜色吗?
【发布时间】:2010-10-02 03:30:32
【问题描述】:

我得到了这样的图像(它是一个图表):


(来源:kitconet.com

我想改变颜色,所以白色是黑色,图形线是浅蓝色等。用GD和PHP可以实现吗?

【问题讨论】:

    标签: php colors gd swap imagefilter


    【解决方案1】:

    这会将白色替换为灰色

    $imgname = "test.gif";
    $im = imagecreatefromgif ($imgname);
    
    $index = imagecolorclosest ( $im,  255,255,255 ); // get White COlor
    imagecolorset($im,$index,92,92,92); // SET NEW COLOR
    
    $imgname = "result.gif";
    imagegif($im, $imgname ); // save image as gif
    imagedestroy($im);
    

    【讨论】:

    • 这个答案在事后也帮助了我! GD 的功能很长,但文档中的实际示例却很短。
    • @IlmariKaronen:谢谢
    【解决方案2】:

    我无法让这个解决方案发挥作用。图像不能是真彩色图像。先用imagetruecolortopalette()进行转换;

    $imgname = "test.gif";
    $im = imagecreatefromgif ($imgname);
    
    imagetruecolortopalette($im,false, 255);
    
    $index = imagecolorclosest ( $im,  255,255,255 ); // get White COlor
    imagecolorset($im,$index,92,92,92); // SET NEW COLOR
    
    $imgname = "result.gif";
    imagegif($im, $imgname ); // save image as gif
    imagedestroy($im);
    

    【讨论】:

      【解决方案3】:

      我知道这已经晚了,但我已经编写了一个脚本,可以在更大的范围内执行此操作。希望看到这篇文章的人可以使用它。它需要许多单色层的源图像(您的选择)。您为其提供源颜色和每一层的色调,脚本会返回一个合成图像(具有完全透明),专门为您提供的十六进制代码着色。

      查看下面的代码。更详细的解释可以在我的blog找到。

      function hexLighter($hex, $factor = 30) {
          $new_hex = '';
      
          $base['R'] = hexdec($hex{0}.$hex{1});
          $base['G'] = hexdec($hex{2}.$hex{3});
          $base['B'] = hexdec($hex{4}.$hex{5});
      
          foreach ($base as $k => $v) {
              $amount = 255 - $v;
              $amount = $amount / 100;
              $amount = round($amount * $factor);
              $new_decimal = $v + $amount;
      
              $new_hex_component = dechex($new_decimal);
      
              $new_hex .= sprintf('%02.2s', $new_hex_component);
          }
      
          return $new_hex;
      }
      
      // Sanitize/Validate provided color variable
      if (!isset($_GET['color']) || strlen($_GET['color']) != 6) {
          header($_SERVER['SERVER_PROTOCOL'] . ' 400 Bad Request', true, 400);
      
          exit(0);
      }
      
      if (file_exists( "cache/{$_GET['color']}.png" )) {
          header( 'Content-Type: image/png' );
          readfile( "cache/{$_GET['color']}.png" );
      
          exit(0);
      }
      
      // Desired final size of image
      $n_width = 50;
      $n_height = 50;
      
      // Actual size of source images
      $width = 125;
      $height = 125;
      
      $image =    imagecreatetruecolor($width, $height);
                  imagesavealpha($image, true);
                  imagealphablending($image, false);
      
      $n_image =  imagecreatetruecolor($n_width, $n_height);
                  imagesavealpha($n_image, true);
                  imagealphablending($n_image, false);
      
      $black = imagecolorallocate($image, 0, 0, 0);
      $transparent = imagecolorallocatealpha($image, 255, 255, 255, 127);
      
      imagefilledrectangle($image, 0, 0, $width, $height, $transparent);
      
      $layers = array();
      $layers_processed = array();
      
      $layers[] = array( 'src' => 'layer01.gif', 'level' => 0 );  // Border
      $layers[] = array( 'src' => 'layer02.gif', 'level' => 35 );     // Background
      $layers[] = array( 'src' => 'layer03.gif', 'level' => 100 );    // White Quotes
      
      foreach ($layers as $idx => $layer) {
          $img = imagecreatefromgif( $layer['src'] );
          $processed = imagecreatetruecolor($width, $height);
      
          imagesavealpha($processed, true);
          imagealphablending($processed, false);
      
          imagefilledrectangle($processed, 0, 0, $width, $height, $transparent);
      
          $color = hexLighter( $_GET['color'], $layer['level'] );
          $color = imagecolorallocate($image,
              hexdec( $color{0} . $color{1} ),
              hexdec( $color{2} . $color{3} ),
              hexdec( $color{4} . $color{5} )
          );
      
          for ($x = 0; $x < $width; $x++)
              for ($y = 0; $y < $height; $y++)
                  if ($black === imagecolorat($img, $x, $y))
                      imagesetpixel($processed, $x, $y, $color);
      
          imagecolortransparent($processed, $transparent);
          imagealphablending($processed, true);
      
          array_push($layers_processed, $processed);
      
          imagedestroy( $img );
      }
      
      foreach ($layers_processed as $processed) {
          imagecopymerge($image, $processed, 0, 0, 0, 0, $width, $height, 100);
      
          imagedestroy( $processed );
      }
      
      imagealphablending($image, true);
      
      imagecopyresampled($n_image, $image, 0, 0, 0, 0, $n_width, $n_height, $width, $height);
      
      imagealphablending($n_image, true);
      
      header( 'Content-Type: image/png' );
      imagepng( $n_image, "cache/{$_GET['color']}.png" );
      imagepng( $n_image );
      
      // Free up memory
      imagedestroy( $n_image );
      imagedestroy( $image );
      

      【讨论】:

        【解决方案4】:

        我自己没有尝试过,但是你可以看看GD库中的函数imagecolorset()它有一个类似颜色填充的效果,可以帮助处理白色背景。

        【讨论】:

          【解决方案5】:

          您可以尝试使用 imagefilter 功能 http://lv.php.net/imagefilter - 但这不会让您直接访问将一种颜色替换为另一种颜色,只需更改 r/g/b 组件。

          可以使用 imagesetpixel http://nl2.php.net/imagesetpixel 设置新的像素值来实现非常低级的解决方案。

          【讨论】:

            【解决方案6】:

            IMG_FILTER_NEGATE:反转图像的所有颜色。

            http://www.php.net/manual/en/function.imagefilter.php

            这会是一个解决方案吗?

            【讨论】:

              【解决方案7】:

              缓慢但可靠的方法,遍历每个像素。

              function ReplaceColour($img, $r1, $g1, $b1, $r2, $g2, $b2)
              {
                  if(!imageistruecolor($img))
                      imagepalettetotruecolor($img);
                  $col1 = (($r1 & 0xFF) << 16) + (($g1 & 0xFF) << 8) + ($b1 & 0xFF);
                  $col2 = (($r2 & 0xFF) << 16) + (($g2 & 0xFF) << 8) + ($b2 & 0xFF);
              
                  $width = imagesx($img); 
                  $height = imagesy($img);
                  for($x=0; $x < $width; $x++)
                      for($y=0; $y < $height; $y++)
                      {
                          $colrgb = imagecolorat($img, $x, $y);
                          if($col1 !== $colrgb)
                              continue; 
                          imagesetpixel ($img, $x , $y , $col2);
                      }   
              }
              

              【讨论】:

                【解决方案8】:

                我不知道有任何现成的功能。但我想你可以遍历图像的每个像素并改变它的颜色......

                【讨论】:

                  猜你喜欢
                  • 2010-10-17
                  • 2016-05-12
                  • 2015-09-12
                  • 2010-12-02
                  • 1970-01-01
                  • 2011-02-11
                  • 2018-06-10
                  • 2012-12-19
                  • 1970-01-01
                  相关资源
                  最近更新 更多