Difference between #2 and #1 of Image resize on the fly

unchanged
Title
Image resize on the fly
unchanged
Category
How-tos
unchanged
Tags
yii, image-resize
changed
Content
Requirements.
------------

- Yii based application
- Enabled path UrlFormat for UrlManager
- All rewrites rules shout be written (.htaccess or any other conf)
- Image  extension for Yii installed  (
http://www.yiiframework.com/extension/image/ )

How it’s works.
---------------

For example have folder with image resources which are public accessible


~~~
/resources/images/avatars/*
/resources/images/posters/*
/resources/images/photos/*
/resources/images/photos/album1/*
~~~

Ordinary image displaying would be

~~~
[php]
<?php echo CHtml::image("/resoures/images/photos/album1/gh53.jpg");
?>
~~~

If we want to get thumbnail of this picture we just have to change a bit url

~~~
[php]
<?php echo
CHtml::image("/resources/thumbs/images/photos/album1/gh53.jpg_200x300.jpg");
?>

~~~

Pretty simple? Isn't it?

Code
----

To get this working we have to create new Controller with id resources and here
is its code.



~~~
[php]
<?php
 
class ResourcesController extends Controller {
 
    public function actionThumbs() {
 
        $request = str_replace(DIRECTORY_SEPARATOR . 'thumbs', '',
Yii::app()->request->requestUri);
 
        $resourcesPath = Yii::getPathOfAlias('webroot') . $request;
        $targetPath = Yii::getPathOfAlias('webroot') .
Yii::app()->request->requestUri;
 
 
        if (preg_match('/_(\d+)x(\d+).*\.(jpg|jpeg|png|gif)/i', $resourcesPath,
$matches)) {
 
            if (!isset($matches[0]) || !isset($matches[1]) ||
!isset($matches[2]) || !isset($matches[3]))
                throw new CHttpException(400, 'Non valid params');
 
            if (!$matches[1] || !$matches[2]) {
                throw new CHttpException(400, 'Invalid dimensions');
            }
 
            $originalFile = str_replace($matches[0], '', $resourcesPath);
            if (!file_exists($originalFile))
                throw new CHttpException(404, 'File not found');
 
 
            $dirname = dirname($targetPath);
            if (!is_dir($dirname))
                mkdir($dirname, 0775, true);
 
 
            $image = Yii::app()->image->load($originalFile);
            $image->resize($matches[1], $matches[2]);
 
            if ($image->save($targetPath)) {
                if (Yii::app()->request->urlReferrer !=
Yii::app()->request->requestUri)
                    $this->refresh();
            }
 
            throw new CHttpException(500, 'Server error');
        } else {
            throw new CHttpException(400, 'Wrong params');
        }
    }
 
}
~~~


What was it?
------------

After first attempt to thumbthumbnail 
/resources/thumbs/images/photos/album1/gh53.jpg_200x300.jpg — thumb action
will be triggered because file won’t found on disk.

Script will try to find location of the original source file here
/resources/images/photos/album1/gh53.jpg

If source file exists it will be resized and stored here
/resources/thumbs/images/photos/album1/gh53.jpg_200x300.jpg

Then script will refresh the url page and after that browser will open newly
created thumbnail file directly from disk!

Quite easy!

You can extend this script to support only list of dimensions to avoid disk
overflow.

That is all.

**Comments are appreciated. Thanks.**

PS
If you are using Nginx and you want to encrease speed of this script you could
use  

~~~
[php]
header("X-Accel-Redirect: /resources/images****");
~~~

instead of refresh.

 

Write new article
  • Written by: Tpoxa
  • Category: How-tos
  • Yii Version: 1.1
  • Votes: +4
  • Viewed: 10,692 times
  • Created on: Nov 11, 2012
  • Last updated: Nov 11, 2012
  • Tags: yii, image-resize