Skip to content

Image Resize and Crop Function

I thought I would share this function with the PHP community, as it seems to be working pretty well. I created it as part of a page for creating screensaver images for the Amazon Kindle. It accepts the path to a JPEG image file and the desired width and height, then returns a PHP image resource of the resized image, which can then be displayed, saved, or otherwise modified. (In the linked page, it is also converted to a gray-scale image.

An obvious enhancement possibility would be to add support for other image types, which I may do soon as I would also like to add the ability to fetch the resulting image as a PNG file instead of JPEG. So feel free to use and modify it as desired, and let me know if you come up with any useful mods.

/**
* Resize image to specific dimension, cropping as needed
* @return resource Resized image resource, or boolean false on failure
* @param string $imgFile Path to image to be resized
* @param int $width
* @param int $height
* @param string $error Error message
*/
function resize($imgFile, $width, $height, &$error = null)
{
   $attrs = @getimagesize($imgFile);
   if($attrs == false or $attrs[2] != IMG_JPEG)
   {
      $error = "Uploaded image is not JPEG or is not readable by this page.";
      return false;
   }
   if($attrs[0] * $attrs[1] > 3000000)
   {
      $error = "Max pixels allowed is 3,000,000. Your {$attrs[0]} x " .
               "{$attrs[1]} image has " . $attrs[0] * $attrs[1] . " pixels.";
      return false;
   }
   $ratio = (($attrs[0] / $attrs[1]) < ($width / $height)) ?
            $width / $attrs[0] : $height / $attrs[1];
   $x = max(0, round($attrs[0] / 2 - ($width / 2) / $ratio));
   $y = max(0, round($attrs[1] / 2 - ($height / 2) / $ratio));
   $src = imagecreatefromjpeg($imgFile);
   if($src == false)
   {
      $error = "Unknown problem trying to open uploaded image.";
      return false;
   }
   $resized = imagecreatetruecolor($width, $height);
   $result = imagecopyresampled($resized, $src, 0, 0, $x, $y, $width, $height,
             round($width / $ratio, 0), round($height / $ratio));
   if($result == false)
   {
      $error = "Error trying to resize and crop image.";
      return false;
   }
   else
   {
      return $resized;
   }
}

Expressing the Difference Between 2 Dates/Times

In an effort to consolidate some things I’ve posted on my site in a less organized manner, here is a reprint of a function I came up with a few years ago for expressing the difference between two UNIX timestamp values (such as returned from the time() and mktime() functions). The result is an array of years, months, weeks, days, hours, minutes, and seconds.


<?php
/**
* Get difference between timestamps broken down into years/months/weeks/etc.
* @return array
* @param int $t1 UNIX timestamp
* @param int $t2 UNIX timestamp
*/
function timeDiff($t1$t2)
{
   if($t1 $t2)
   {
      $time1 $t2;
      $time2 $t1;
   }
   else
   {
      $time1 $t1;
      $time2 $t2;
   }
   $diff = array(
      'years' => 0,
      'months' => 0,
      'weeks' => 0,
      'days' => 0,
      'hours' => 0,
      'minutes' => 0,
      'seconds' =>0
   );
   foreach(array('years','months','weeks','days','hours','minutes','seconds')
         as $unit)
   {
      while(TRUE)
      {
         $next strtotime("+1 $unit"$time1);
         if($next $time2)
         {
            $time1 $next;
            $diff[$unit]++;
         }
         else
         {
            break;
         }
      }
   }
   return($diff);
}

Here’s a sample usage:


<?php
$start strtotime('2007-01-15 07:35:55');
$end strtotime('2009-11-09 13:01:00');
$diff timeDiff($start$end);
$output "The difference is:";
foreach($diff as $unit => $value)
{
   echo " $value $unit,";
}
$output trim($output',');
echo $output;
?>

It would output:

The difference is: 2 years, 9 months, 3 weeks, 4 days, 5 hours, 25 minutes, 4 seconds

Undoing Magic Quotes

The often maligned (and rightfully so) magic_quotes_gpc “feature” of PHP can be problematic, especially if you are trying to develop scripts for general consumption on any platform. A brief example of the sort of problem it can cause is that if it is turned on and you do not undo its addition of back-slash escape characters, then if you apply a function such as mysql_real_escape_string() to prepare external data for use in a query, you will end up escaping the magic quotes backslashes and including them in the actual data.

To repair this potential “damage”, my solution is simply to test to see if the feature is turned on, and if it is, to recursively walk through the affected arrays, $_GET, $_POST, $_COOKIE (thus the “gpc”), via the array_walk_recursive() function. My function makes use of an “anonymous function” via the create_function() function. Then all that needs to be done in any script is to run the following function before otherwise using any of those three super-global arrays.

Continue reading ‘Undoing Magic Quotes’ »

Book Review: CodeIgniter 1.7 Professional Development

I was recently provided a review copy of CodeIgniter 1.7 Professional Development by Adam Griffith (Packt Publishing). It claims that it will help the reader “Become a CodeIgniter expert with professional tools, techniques and extended libraries.” As someone who has used CodeIgniter and found it to be very useful, I was looking forward to learning more and becoming a CI power user. However, I cannot say that my wish was fulfilled.

While some of the second half of the book introduced me to a few CI features I did not know about or at least had not yet used, most of the book was either about things I already knew or things I didn’t really care much about.

Most of the first half of the book essentially reiterated things you can find in the CI documentation, and that documentation is one of the strong points of CI. Also, some of the organization of the material was odd, such as detailing the image manipulation library before discussing a basic functionality such as session data handling. Some of the code samples seemed to be less than optimal as good examples of object-oriented PHP, such as the large switch/case block in the “Rest” class in Chapter 8.

My overall response to this book is therefore that it might be of use to intermediate-level PHP users who are new to CodeIgniter (with the caveat that it is not necessarily a good source for learning good OOP practices), but the experienced CodeIgniter user probably will find little in this book to make it worth purchasing. I’d probably only give it 2-1/2 stars out of 5.

Object Iteration in PHP 5

PHP 5 gives us the ability to iterate through objects much as we can with arrays, such as with the foreach() loop construct. I knew this ability existed but had not really looked into it or made use of it. However as a result of a thread at PHPBuilder.com, I thought this might be a good solution.

The key here is that while the default behavior of object iteration is to access each of the object’s public properties, you can override that behavior via the Iterator interface, defining custom methods to iterate what you specifically want from the object.

Continue reading ‘Object Iteration in PHP 5’ »

Good News / Bad News

The good news: PHP has lots and lots of useful built-in functions for all sorts of things.

The bad news: PHP has lots and lots of useful built-in functions I don’t know about.

Sometimes it’s almost an embarrassment of riches. You think you know PHP pretty well and know how to write some pretty slick code. In a thread at PHPBuilder.com I threw together a bit of code to build a CSV file from a database query. I figured I was being fairly clever using the uniqid() function to create a unique file name I could use for temporary storage of the CSV data, fopen()-ing it and then eventually using readfile() to output it to the user, followed by an unlink() of the file once it’s done.

Then fellow moderator “Weedpacket” pointed out to me the tmpfile() function, which I’d never run into before, and which makes it easy to open up a temporary file. It returns a file handle similarly to the fopen() function. The nice part is that you do not have to worry at all about generating a unique name, and the file is automatically deleted upon script completion (or when you fclose() it should you choose to).

It serves as a slightly humbling reminder that when working with PHP, before you write code to do something that someone else has likely had to do in the past, it is probably worth your while to scan through the function lists of applicable sections of the manual to see if there is already a built-in function which does what you need. It is often worth the time to make that search, as the built-in functions are likely to be faster than your own user-defined functions, plus hopefully they should be more robust.

Tourney Time Again

I’ve posted my 2010 NCAA Men’s Basketball Tournament randomized bracket generator. It’s a quick way to pick winners for your bracket pools. It simply weights each game by the teams’ tournament seedings. It ain’t fancy, but if you’re tired of spending hours trying to pick the winners only to find you’re out of the competition by the first Friday, well, this way at least you won’t have wasted as much time.