Crop whitespace from image in PHP

Viewed 35887

Is it possible to remove the whitespace surrounding an image in PHP?

NOTE: to clarify I mean something like photoshops trim feature.

Thanks.

8 Answers

PHP's gd library has the imagecropauto function (PHP version 5.5+):

<?php 
$img=imagecreatefrompng("tux.png"); // Load and instantiate the image
if($img) {
  $cropped=imagecropauto($img,IMG_CROP_DEFAULT); // Auto-crop the image

  imagedestroy($img); // Clean up as $img is no longer needed

  header("Content-type: image/png"); // Set the appropriate header so the browser
                                     // knows how to present it
  imagepng($cropped); // Return the newly cropped image
}

By default imagecropauto will try to crop using transparency, and then fall back on using the 4 corners of the image to attempt to detect the background to crop; I have also had success with the following constants in place of IMG_CROP_AUTO in the example above:

  • IMG_CROP_BLACK - Useful for images with a black background
  • IMG_CROP_WHITE - Useful for images with a white background
  • IMG_CROP_THRESHOLD - Allows you to set a colour and threshold to use when cropping

Lets say you have image with border color 0x212121. You want to automatically trim this border with PHP. You can do it with such code:

// Load image
$img1='input.png';
$finfo = getimagesize($img1);
$image_old = $finfo['mime']=='image/png'?imagecreatefrompng($img1):imagecreatefromjpeg($img1);
// !! REMOVE BORDER !!
$cropped = imagecropauto($image_old , IMG_CROP_THRESHOLD, 1, 0x212121);
// Save image
imagepng($cropped, 'output.png');

I use strategy of gnud, but rewrite logic because in my case it doesn't work. My version:

class CutBackgroundGdImage
{

    protected $strip_colors = array(0xFFFFFF);

    public function setStripColors(array $strip_colors) {
      $this->strip_colors = $strip_colors;
      return $this;
    }

    /**
     * @param GdImage $image
     * @return GdImage
     */
    public function cutImage($image) {
      $top_edge = $this->findTopEdge($image);
      $bottom_edge = $this->findBottomEdge($image);
      $right_edge = $this->findRightEdge($image);
      $left_edge = $this->findLeftEdge($image);

      $cutted_image = imagecreatetruecolor(
        (imagesx($image) - $left_edge) - (imagesx($image) - $right_edge),
        (imagesy($image) - $top_edge) - (imagesy($image) - $bottom_edge)
      );

      imagecopy($cutted_image, $image, 0, 0, $left_edge, $top_edge, imagesx($cutted_image), imagesy($cutted_image));

      return $cutted_image;
    }

    public function findTopEdge($image) {
      for ($y = 0; $y < imagesy($image); $y++) {
        for ($x = 0; $x < imagesx($image); $x++) {
          if (!in_array(imagecolorat($image, $x, $y), $this->strip_colors)) {
            break 2;
          }
        }
      }
      return $y;
    }

    public function findBottomEdge($image) {
      for ($y = imagesy($image) - 1; $y > 0; $y--) {
        for ($x = 0; $x < imagesx($image); $x++) {
          if (!in_array(imagecolorat($image, $x, $y), $this->strip_colors)) {
            break 2;
          }
        }
      }
      return $y;
    }

    public function findLeftEdge($image) {
      for ($x = 0; $x < imagesx($image); $x++) {
        for($y = 0; $y < imagesy($image); $y++) {
          if (!in_array(imagecolorat($image, $x, $y), $this->strip_colors)) {
            break 2;
          }
        }
      }
      return $x;
    }

    public function findRightEdge($image) {
      for ($x = imagesx($image) - 1; $x > 0; $x--) {
        for ($y = 0; $y < imagesy($image); $y++) {
          if (!in_array(imagecolorat($image, $x, $y), $this->strip_colors)) {
            break 2;
          }
        }
      }
      return $x;
    }

}

$cut_gd_image = new CutBackgroundGdImage();
$cutted_image = $cut_gd_image->cutImage($gd_image);
Related