Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I trim just the left and right side of an image using Imagemagick in PHP?

I'm trying to trim a variable amount of whitespace in an image only the left and right side using ImageMagick and PHP. Does anyone know how to do this (perhaps using something other than imagemagick?)?

Here's an example.

I have these two images:
Test
Test Again
Each has a variable amount of text that is dynamically created in a fixed width image. What I need to do is trim the background off the right and left side so the images come out like this:
TestResult
Test Again Result

If ImageMagick can't do it, I am willing to use something else, but I will need help on how exactly because I am not much of a programmer. Thanks!

Here's my current code that trims all sides of an image:

<?php
/* Create the object and read the image in */
$i = '3';
$im = new Imagick("test".$i.".png");

/* Trim the image. */
$im->trimImage(0);

/* Ouput the image */
//header("Content-Type: image/" . $im->getImageFormat());
//echo $im;
/*** Write the trimmed image to disk ***/
$im->writeImage(dirname(__FILE__) . '/test'.$i.'.png');
/*Display Image*/
echo $img = "<img src=\"test".$i.".png\">";
?>
like image 553
Nathan Avatar asked Oct 21 '11 20:10

Nathan


2 Answers

I think you are on the right track with ImageMagick's -trim operator 1), but the trick would be to get it tell you what it would do without actually doing it, and then modify that to do what you really want...

So, to get the trim-box ImageMagick calculates for your first image, you do this:

convert -fuzz 10% image.jpg -format "%@" info:
60x29+21+31

That is a 60x29 pixel rectangle, offset 21 across and 31 down from the top left corner. Now, we want to get these values into bash variables, so I set the IFS (Input Field Separator) to split fields on spaces, x and also + signs:

#!/bin/bash
IFS=" x+" read a b c d < <(convert -fuzz 10% image.jpg -format "%@" info:)

echo $a $b $c $d
60 29 21 31

Now I can ignore the 29 and the 31 because we are only interested in cropping the width, and crop like this:

convert image.jpg -crop "${a}x+${c}+0" out.jpg

So, for your 2 images, I get these:

enter image description hereenter image description here

and the full procedure is this:

#!/bin/bash
IFS=" x+" read a b c d < <(convert -fuzz 10% image.jpg -format "%@" info:)
convert image.jpg -crop "${a}x+${c}+0" out.jpg

Notes

1) The -format %@ is just a shorthand for the -trim operator, which would be this in full

convert image.jpg -trim info:
image.jpg JPEG 72x40 200x100+16+24 8-bit sRGB 0.000u 0:00.000
like image 116
Mark Setchell Avatar answered Oct 07 '22 00:10

Mark Setchell


From what I can see in the ImageMagick docs on cropping and borders, it doesn't seem to be possible.

you can't specify an edge for "intelligent" cropping (known as-trim on the command line), and all the cropping methods that accept a geometry argument need a fixed number for cropping.

The only idea that comes to mind is to get the colour of the shaved area in a separate call, run trimImage, and add the lost areas back using -border.

Edit: The IM manual is suggesting something similar. Check out Trimming Just One Side of an Image. I'm not familiar with IM's PHP extension to translate the code into PHP calls but it should be half-way straightforward.

like image 33
Pekka Avatar answered Oct 07 '22 01:10

Pekka