Get image color

前端 未结 1 1175
一生所求
一生所求 2020-11-27 18:44

I want to display images inside divs or tables as backgrounds. If they images aren\'t large enough, I\'m going to need to find the outer most color of that image and apply

相关标签:
1条回答
  • 2020-11-27 19:18

    Check out the GD functions.

    Here's a solution of looping through the pixels to find the most common color. However, you could just resize the image to 1 pixel - that should be the average color - right?

    An example of the 1px method (now including test page):

    <?php
      $filename = $_GET['filename'];    
      $image = imagecreatefromjpeg($filename);
      $width = imagesx($image);
      $height = imagesy($image);
      $pixel = imagecreatetruecolor(1, 1);
      imagecopyresampled($pixel, $image, 0, 0, 0, 0, 1, 1, $width, $height);
      $rgb = imagecolorat($pixel, 0, 0);
      $color = imagecolorsforindex($pixel, $rgb);
    ?>
    <html>
      <head>
        <title>Test Image Average Color</title>
      </head>
      <body style='background-color: rgb(<?php echo $color['red'] ?>, <?php echo $color['green'] ?>, <?php echo $color['blue'] ?>)'>
        <form action='' method='get'>
          <input type='text' name='filename'><input type='submit'>
        </form>
        <img src='<?php echo $filename ?>'>
      </body>
    </html>
    

    Here's some example code for finding the average border color, similar to the first link. For your use this may work better (I know this code is inefficient, but hopefully it's easy to follow):

    <?php
      $filename = $_GET['filename'];    
      $image = imagecreatefromjpeg($filename);
      $width = imagesx($image);
      $height = imagesy($image);
    
      for($y = 0; $y < $height; $y++){
        $rgb = imagecolorat($image, 0, $y);
        $color = imagecolorsforindex($image, $rgb);
        $red += $color['red'];
        $green += $color['green'];
        $blue += $color['blue'];
    
        $rgb = imagecolorat($image, $width -1, $y);
        $color = imagecolorsforindex($image, $rgb);
        $red += $color['red'];
        $green += $color['green'];
        $blue += $color['blue'];
      }
    
      for($x = 0; $x < $height; $x++){
        $rgb = imagecolorat($image, $x, 0);
        $color = imagecolorsforindex($image, $rgb);
        $red += $color['red'];
        $green += $color['green'];
        $blue += $color['blue'];
    
        $rgb = imagecolorat($image, $x, $height -1);
        $color = imagecolorsforindex($image, $rgb);
        $red += $color['red'];
        $green += $color['green'];
        $blue += $color['blue'];
      }
    
      $borderSize = ($height=$width)*2;
      $color['red'] = intval($red/$borderSize);
      $color['green'] = intval($green/$borderSize);
      $color['blue'] = intval($blue/$borderSize);
    
    ?>
    

    Update: I put some more refined code on github. This includes both averaging the border, and averaging the entire image. It should be noted that resizing to 1px is far more resource friendly than scanning every pixel (although I haven't run any real time tests), but the code does show the three different methods.

    0 讨论(0)
提交回复
热议问题