CodeIgniter resizing and cropping images on the fly
One of the more popular articles on my blog was "Codeigniter: resizing and cropping images on the fly". At the time I wrote the article I wanted to create a code that would be really easy to use. However, there is a huge downside in the implementation. All the images are resized in 1 execution cycle of your controller. This means that when your code is executed, it will have to wait until each image is resized until it can go any further and send the complete output to the user.
A better solution would be to create a separate controller that only handles the resizing and cropping. This way your code will execute faster and each image will be requested separately to that specific controller. At first you might think this is a bit overkill because the CodeIgniter framework will have to load for each requested image. This is true, but there is an easy way around this.
Think of it this way, if you request an existing image from your media folder, it is loaded without any CodeIgniter interaction. This is because the .htaccess will only activate CodeIgniter if a non-file is requested. Now, if you would create a controller with the same name as your media folder, and you would request a non existing image, that controller will be activated. This way you can activate the controller for each image that is requested for the first time, all the following request will be taken directly to the generated image.
Download the files from github and place them in their corresponding folder.
- Make sure you are using the .htaccess mod_rewrite
- Rename the controller and the media folder to your liking. (must be the same name)
- Add a custom route to your config/routes.php file. This will redirect all "non-existing-file" request to the media controller's resize method:
$route['media/(:any)'] = 'media/resize/$1';
- Optional: autoload the image_helper by adding it to $autoload['helper'] array in your config/autoload.php file.
First you need to specify what preset sizes you will be using for your images in the config/images.php file:
$config["image_sizes"]["square"] = array(400, 400); $config["image_sizes"]["rectangle"] = array(600, 400); $config["image_sizes"]["long"] = array(200, 600); $config["image_sizes"]["wide"] = array(600, 200); $config["image_sizes"]["small"] = array(300, 0); $config["image_sizes"]["medium"] = array(500, 0); $config["image_sizes"]["large"] = array(800, 0);
Each preset has a width and a height. If one of the dimensions are equal to 0, it will automatically calculate a matching width or height to maintain the original ratio. A preset of (200, 0) will generate:
Now the cool stuff, if you specify both dimensions it will automatically crop the resulting image so that it fits those dimensions. A preset of (200, 200) will generate:
If you do not want the image to be cropped from the center axis you can specify your own axis by using the default $config['x_axis'] and $config['y_axis']
To resize and crop the images to the preset sizes you need to load the image_helper. This helper has a function image($path, $preset) that will translate a preset to a generated path that contains the dimensions for the controller or that will take you directly to the image if it has already been resized.
Use this helper in your view files like this:
<img src="<?php echo image("media/smiles.png", "wide"); ?>" alt="smiles" />
This will eventually translate into:
<img src="media/smiles-600x200.png" alt="smiles" />
The reason I add the dimensions to the original filename instead of the preset name is because when you would change the preset's dimensions, it would still load images with the old dimensions that were already generated instead of the new dimensions.
The resize and crop logic is grouped in a library that extends CodeIgniter's 'image_lib' and adds a 'fit' function. You can use this library to resize and crop an image to fit the specified dimensions like this:
$config["source_image"] = '/path/to/image/mypic.jpg'; $config['new_image'] = '/path/to/new/image/newpic.jpg'; $config["width"] = 100; $config["height"] = 100; $this->load->library('image_lib', $config); $this->image_lib->fit();
The function will return TRUE on sucess or FALSE on failure. Error messages can be read like the normal library with the display_errors() method.
This is a way more efficient way of resizing and cropping your images "on the fly" than the the one in my first article. The output is send to the user without having to wait until all images are resized and there is less interaction with CodeIgniter when the images are already generated.
I hope you enjoy this "snippet". If you encounter any problems, feel free to contact me.