With PHP/GD, how do I trim an image?

后端 未结 2 958
时光取名叫无心
时光取名叫无心 2021-01-21 09:56

I want to mimic the trim behavior of Photoshop (crop the area that is covered by the same color on all sides) with GD and PHP but I\'m lacking

相关标签:
2条回答
  • 2021-01-21 10:15

    The easiest solution I can think of is:

    1. Find out the color of the top left pixel.
    2. Go through the image line by line, horizontally and vertically, starting on the top, bottom , left hand, and right hand side respectively. If a line consists of ONLY the color encountered in the top left corner it is trimmable empty space. Omit that line from the resulting image by increasing the x or y coordinate of your imagecopy*() function.

    Untested but might work.

    BTW, ImageMagick can do this out of the box: http://www.imagemagick.org/Usage/crop/#trim

    0 讨论(0)
  • 2021-01-21 10:35

    Here's a sample function (which also can add padding):

    // Trims an image then optionally adds padding around it.
    // $im  = Image link resource
    // $bg  = The background color to trim from the image
    // $pad = Amount of padding to add to the trimmed image
    //        (acts simlar to the "padding" CSS property: "top [right [bottom [left]]]")
    function imagetrim(&$im, $bg, $pad=null){
    
        // Calculate padding for each side.
        if (isset($pad)){
            $pp = explode(' ', $pad);
            if (isset($pp[3])){
                $p = array((int) $pp[0], (int) $pp[1], (int) $pp[2], (int) $pp[3]);
            }else if (isset($pp[2])){
                $p = array((int) $pp[0], (int) $pp[1], (int) $pp[2], (int) $pp[1]);
            }else if (isset($pp[1])){
                $p = array((int) $pp[0], (int) $pp[1], (int) $pp[0], (int) $pp[1]);
            }else{
                $p = array_fill(0, 4, (int) $pp[0]);
            }
        }else{
            $p = array_fill(0, 4, 0);
        }
    
        // Get the image width and height.
        $imw = imagesx($im);
        $imh = imagesy($im);
    
        // Set the X variables.
        $xmin = $imw;
        $xmax = 0;
    
        // Start scanning for the edges.
        for ($iy=0; $iy<$imh; $iy++){
            $first = true;
            for ($ix=0; $ix<$imw; $ix++){
                $ndx = imagecolorat($im, $ix, $iy);
                if ($ndx != $bg){
                    if ($xmin > $ix){ $xmin = $ix; }
                    if ($xmax < $ix){ $xmax = $ix; }
                    if (!isset($ymin)){ $ymin = $iy; }
                    $ymax = $iy;
                    if ($first){ $ix = $xmax; $first = false; }
                }
            }
        }
    
        // The new width and height of the image. (not including padding)
        $imw = 1+$xmax-$xmin; // Image width in pixels
        $imh = 1+$ymax-$ymin; // Image height in pixels
    
        // Make another image to place the trimmed version in.
        $im2 = imagecreatetruecolor($imw+$p[1]+$p[3], $imh+$p[0]+$p[2]);
    
        // Make the background of the new image the same as the background of the old one.
        $bg2 = imagecolorallocate($im2, ($bg >> 16) & 0xFF, ($bg >> 8) & 0xFF, $bg & 0xFF);
        imagefill($im2, 0, 0, $bg2);
    
        // Copy it over to the new image.
        imagecopy($im2, $im, $p[3], $p[0], $xmin, $ymin, $imw, $imh);
    
        // To finish up, we replace the old image which is referenced.
        $im = $im2;
    }
    
    0 讨论(0)
提交回复
热议问题