Recently I was working with UPS Dispatch Labels, I built a neat system which would get back the label URL from the API and then pull out the image data from the document (the image being just the label itself).
Unfortunately there was some whitespace on the label which was affecting a A4 instruction sheet I was producing so needed to trim off the whitespace from the image, I was surprised to discover there is no inbuilt function in GD that does this for you!
After searching around the internet for a simple method that was fast and efficient I decided to write my own function, using the best ideas.
If you need to trim whitespace from an image in GD then the below code will be highly useful for you:
<?php // Trims an image then optionally adds padding around it. // $im = Image link resource // $bgcol = The background color to trim from the image (using imagecolorallocate in gd) // $pad = Amount of padding to add to the trimmed image // (acts similar to the "padding" CSS property: "top [right [bottom [left]]]") function imagetrim($im, $bgcol, $pad=null){ // Calculate padding for each side. if (isset($pad)){ $pada = explode(' ', $pad); if (isset($pada[3])){ $p = array((int) $pada[0], (int) $pada[1], (int) $pada[2], (int) $pada[3]); }else if (isset($pada[2])){ $p = array((int) $pada[0], (int) $pada[1], (int) $pada[2], (int) $pada[1]); }else if (isset($pada[1])){ $p = array((int) $pada[0], (int) $pada[1], (int) $pada[0], (int) $pada[1]); }else{ $p = array_fill(0, 4, (int) $pada[0]); } }else{ $p = array_fill(0, 4, 0); } // Get the width and height of the image. $imw = imagesx($im); $imh = imagesy($im); // Set the X variables. $xmin = $imw; $xmax = 0; // find the endges. for ($iy=0; $iy<$imh; $iy++) { $first = true; for ($ix=0; $ix<$imw; $ix++) { $ndx = imagecolorat($im, $ix, $iy); if ($ndx != $bgcol) { 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. $bgcol2 = imagecolorallocate($im2, ($bgcol >> 16) & 0xFF, ($bgcol >> 8) & 0xFF, $bgcol & 0xFF); imagefill($im2, 0, 0, $bgcol2); // Copy it over to the new image. imagecopy($im2, $im, $p[3], $p[0], $xmin, $ymin, $imw, $imh); // To finish up, return the new image. return $im2; } ?>
Add the above function to your function references file, or alternatively build it into your OOP structure how you wish, below is an example on how to call the function and get the result you are looking for:
<?php $myim = imagecreatefromgif('image path'); $myim = imagetrim($myim, imagecolorallocate($myim, 0xFF, 0xFF, 0xFF), 10); //$myim now holds the new image which has had white trimmed and a padding of 10px around the image added. ?>
How does it work?
Its quite simple really, the function takes the colour you wish to trim and then begins scanning every pixel of the image to see where the X1,Y1 and X2,Y2 positions are (the outer edges of the image). it then knows to trim anything outside of this region.
Unfortunately this could mean quite allot of processing time for really large images, so I would suggest you use GD to resize the image down to an appropriate size before you perform the trim, however it should be able to process large images quite well – could someone let me know if they have any issues with large images?
TIP: you should always resize first anyway as any pixels that are shaded for anti-aliasing purposes will be cut harshly if you trim the image first as the bleed from the resize may go over the edge of the image dimensions.





