My (mostly technical) blog

Image Upload and Resize Component for CakePHP 1.2

Posted on: May 13, 2008

Update:
Newer version

I needed to upload images to my CakePHP based website and at the same time, I needed to resize and create thumbnails of those images.

I found some different components on the Bakery and I found some code here, but I needed something more, I needed to have the ability to generate square zoomed thumbnails out of the uploaded images.

Since I was new to CakePHP and I wanted to improve my skills, I ended up taking code from several sources, writing some of my own, and integrating them in a component.

Big version resized using scale: 573

Small version resized using scale 110

Small version resized using scale 110 / square

You can download the code from here or here and you can take a look at it below.

<?php
/*
 File: /app/controllers/components/image.php
*/
class ImageComponent extends Object
{
    /*
    *    Uploads an image and its thumbnail into $folderName/big and $folderName/small respectivley.
    *     the  generated thumnail could either have the same aspect ratio as the uploaded image, or could
    *    be a zoomed and cropped version.

    *     Directions:
    *    In view where you upload the image, make sure your form creation is similar to the following
    *    <?= $form->create('FurnitureSet',array('type' => 'file')); ?>
    *
    *    In view where you upload the image, make sure that you have a file input similar to the following
    *    <?= $form->file('Image/name1'); ?>
    *
    *    In the controller, add the component to your components array
    *    var $components = array("Image");
    *
    *    In your controller action (the parameters are expained below)
    *    $image_path = $this->Image->upload_image_and_thumbnail($this->data,"name1",573,80,"sets",true);
    *    this returns the file name of the result image.  You can  store this file name in the database
    *
    *    Note that your image will be stored in 2 locations:
    *    Image: /webroot/img/$folderName/big/$image_path
    *    Thumbnail:  /webroot/img/$folderName/small/$image_path
    *
    *    Finally in the view where you want to see the images
    *    <?= $html->image('sets/big/'.$furnitureSet['FurnitureSet']['image_path']);
    *     where "sets" is the folder name we saved our pictures in, and $furnitureSet['FurnitureSet']['image_path'] is the file name we stored in the database

    *    Parameters:
    *    $data: CakePHP data array from the form
    *    $datakey: key in the $data array. If you used <?= $form->file('Image/name1'); ?> in your view, then $datakey = name1
    *    $imgscale: the maximum width or height that you want your picture to be resized to
    *    $thumbscale: the maximum width or height that you want your thumbnail to be resized to
    *    $folderName: the name of the parent folder of the images. The images will be stored to /webroot/img/$folderName/big/ and  /webroot/img/$folderName/small/
    *    $square: a boolean flag indicating whether you want square and zoom cropped thumbnails, or thumbnails with the same aspect ratio of the source image
    */
    function upload_image_and_thumbnail($data, $datakey, $imgscale, $thumbscale, $folderName, $square) {
        if (strlen($data['Image'][$datakey]['name'])>4){
                    $error = 0;
                    $tempuploaddir = "img/temp"; // the /temp/ directory, should delete the image after we upload
                    $biguploaddir = "img/".$folderName."/big"; // the /big/ directory
                    $smalluploaddir = "img/".$folderName."/small"; // the /small/ directory for thumbnails

                    // Make sure the required directories exist, and create them if necessary
                    if(!is_dir($tempuploaddir)) mkdir($tempuploaddir,true);
                    if(!is_dir($biguploaddir)) mkdir($biguploaddir,true);
                    if(!is_dir($smalluploaddir)) mkdir($smalluploaddir,true);

                    $filetype = $this->getFileExtension($data['Image'][$datakey]['name']);
                    $filetype = strtolower($filetype);

                    if (($filetype != "jpeg")  && ($filetype != "jpg") && ($filetype != "gif") && ($filetype != "png"))
                    {
                        // verify the extension
                        return;
                    }
                    else
                    {
                        // Get the image size
                        $imgsize = GetImageSize($data['Image'][$datakey]['tmp_name']);
                    }

                    // Generate a unique name for the image (from the timestamp)
                    $id_unic = str_replace(".", "", strtotime ("now"));
                    $filename = $id_unic;

                    settype($filename,"string");
                    $filename.= ".";
                    $filename.=$filetype;
                    $tempfile = $tempuploaddir . "/$filename";
                    $resizedfile = $biguploaddir . "/$filename";
                    $croppedfile = $smalluploaddir . "/$filename";

                    if (is_uploaded_file($data['Image'][$datakey]['tmp_name']))
                    {
                        // Copy the image into the temporary directory
                        if (!copy($data['Image'][$datakey]['tmp_name'],"$tempfile"))
                        {
                            print "Error Uploading File!.";
                            exit();
                        }
                        else {
                            /*
                             *    Generate the big version of the image with max of $imgscale in either directions
                             */
                            $this->resize_img($tempfile, $imgscale, $resizedfile);                            

                            if($square) {
                                /*
                                 *    Generate the small square version of the image with scale of $thumbscale
                                 */
                                $this->crop_img($tempfile, $thumbscale, $croppedfile);
                            }
                            else {
                                /*
                                 *    Generate the big version of the image with max of $imgscale in either directions
                                 */
                                $this->resize_img($tempfile, $thumbscale, $croppedfile);
                            }

                            // Delete the temporary image
                            unlink($tempfile);
                        }
                    }

                     // Image uploaded, return the file name
                     return $filename;
        }
    }

    /*
    *    Deletes the image and its associated thumbnail
    *    Example in controller action:    $this->Image->delete_image("1210632285.jpg","sets");
    *
    *    Parameters:
    *    $filename: The file name of the image
    *    $folderName: the name of the parent folder of the images. The images will be stored to /webroot/img/$folderName/big/ and  /webroot/img/$folderName/small/
    */
    function delete_image($filename,$folderName) {
        unlink("img/".$folderName."/big/".$filename);
        unlink("img/".$folderName."/small/".$filename);
    }

    function crop_img($imgname, $scale, $filename) {
        $filetype = $this->getFileExtension($imgname);
        $filetype = strtolower($filetype);

        switch($filetype){
            case "jpeg":
            case "jpg":
              $img_src = ImageCreateFromjpeg ($imgname);
             break;
             case "gif":
              $img_src = imagecreatefromgif ($imgname);
             break;
             case "png":
              $img_src = imagecreatefrompng ($imgname);
             break;
        }

        $width = imagesx($img_src);
        $height = imagesy($img_src);
        $ratiox = $width / $height * $scale;
        $ratioy = $height / $width * $scale;

        //-- Calculate resampling
        $newheight = ($width <= $height) ? $ratioy : $scale;
        $newwidth = ($width <= $height) ? $scale : $ratiox;

        //-- Calculate cropping (division by zero)
        $cropx = ($newwidth - $scale != 0) ? ($newwidth - $scale) / 2 : 0;
        $cropy = ($newheight - $scale != 0) ? ($newheight - $scale) / 2 : 0;

        //-- Setup Resample & Crop buffers
        $resampled = imagecreatetruecolor($newwidth, $newheight);
        $cropped = imagecreatetruecolor($scale, $scale);

        //-- Resample
        imagecopyresampled($resampled, $img_src, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
        //-- Crop
        imagecopy($cropped, $resampled, 0, 0, $cropx, $cropy, $newwidth, $newheight);

        // Save the cropped image
        switch($filetype)
        {
            case "jpeg":
            case "jpg":
             imagejpeg($cropped,$filename,80);
             break;
             case "gif":
             imagegif($cropped,$filename,80);
             break;
             case "png":
             imagepng($cropped,$filename,80);
             break;
        }
    }

    function resize_img($imgname, $size, $filename)    {
        $filetype = $this->getFileExtension($imgname);
        $filetype = strtolower($filetype);

        switch($filetype) {
            case "jpeg":
            case "jpg":
            $img_src = ImageCreateFromjpeg ($imgname);
            break;
            case "gif":
            $img_src = imagecreatefromgif ($imgname);
            break;
            case "png":
            $img_src = imagecreatefrompng ($imgname);
            break;
        }

        $true_width = imagesx($img_src);
        $true_height = imagesy($img_src);

        if ($true_width>=$true_height)
        {
            $width=$size;
            $height = ($width/$true_width)*$true_height;
        }
        else
        {
            $width=$size;
            $height = ($width/$true_width)*$true_height;
        }
        $img_des = ImageCreateTrueColor($width,$height);
        imagecopyresampled ($img_des, $img_src, 0, 0, 0, 0, $width, $height, $true_width, $true_height);

        // Save the resized image
        switch($filetype)
        {
            case "jpeg":
            case "jpg":
             imagejpeg($img_des,$filename,80);
             break;
             case "gif":
             imagegif($img_des,$filename,80);
             break;
             case "png":
             imagepng($img_des,$filename,80);
             break;
        }
    }

    function getFileExtension($str) {

        $i = strrpos($str,".");
        if (!$i) { return ""; }
        $l = strlen($str) - $i;
        $ext = substr($str,$i+1,$l);
        return $ext;
    }
} ?>
Advertisements

53 Responses to "Image Upload and Resize Component for CakePHP 1.2"

Looks very nice. Good job!

[…] Image Upload and Resize Component for CakePHP 1.2 […]

The script looks great, except that it must have been run through some web filter that didn’t recognize it as code, because you’ve got a bunch of smiley image HTML in line 57 😉

Yes, I just noticed that!

I will soon post a modified component that I based upon one of the excellent components in the CakePHP Bakery 🙂

The one above has a bug because it resizes small images and it doesn’t obey the rule that it should resize accoring to the longest dimension, if the pictures is a portrait.

Many thanks for the code. however, I am still getting
Undefined index: Image [APP\controllers\components\image.php, line 43
app\controllers\welcomenotes_controller.php (line 36)

even after having var $components = array(“Image”); in my component.
any clue?

Quick question and comment. I had to modify the code slightly to be able to upload *.png files. It was failing and I had to change the (quality) setting from 80 to 9 on a couple of the functions. It works fine, the problem is that now the shadows from windows in OSX screenshots are filled with a black background. I need it to preserve the transparency and show the shadows for aesthetics sake. Also, I wonder how much trouble it would be to do large, medium and thumb? I will try and implement this solution using your example. Thanks a lot for your contributions it really has helped me as a cakePHP newbie.

I just modified this script to preserve alpha transparency in png images:

http://paste2.org/p/48627

Thank you – this is great. I think this part is redundant though:

if ($true_width>=$true_height)
{
$width=$size;
$height = ($width/$true_width)*$true_height;
}
else
{
$width=$size;
$height = ($width/$true_width)*$true_height;
}

It’s fantastic, it’s simple and it simply works! I hope that a sentiment analisys web crawler read this comment and that your component can be the first on the results! Good job!

[…] Image Upload Component for CakePHP 1.2 I revisited the code I used to develop the old image resize component because I found a bug in the resize code. I used the resize function from the PImageComponent by […]

i am trying to put together the perfect combination image gallery script for my site. this looks to be what i need for image upload/resize/thumbnail but i’m not sure how to use it… is there any way you could give me directions? i don’t write php myself… i can read it, a little, but i’m pretty lost when it comes to more than just integrating it into my html.

Great Job! 🙂
I’ve made some little changes to the path set for the images uploaded, because of PHP error “no such file do directory”. The changes looks like:

$tempuploaddir = realpath(“../../app/webroot/img/temp”).’/’;
$biguploaddir = realpath(“../../app/webroot/img/”).’/’.$folderName.”/big”;
$smalluploaddir = realpath(“../../app/webroot/img/”).’/’.$folderName.”/small”;

Regards!

OK, so I guess I’m quite new at using cakePHP. This all makes sense until I get to undeclared functions like “ImageCreateFromjpeg”.

Where do I find these functions if they are not already implemented in my cakePHP libs?

@Ron: You have to have the PHP GD library installed and enabled!

Check this out: http://quomon.com/question-Call-to-undefined-function-imagecreatefromjpeg-in-php-655.aspx

Excellent component!!
I think it will be more useful if you can show how to use that in to controller. People get confuse regarding arguments of upload function.

Great component! Thanks a lot!

Thanks you!

pippo pippo pippo

Um…any idea why this makes a form really slow when an image is not selected to upload?

While using cake 1.2.3.8166 I found that using the name “Image” for this component caused some serious problems, and could not get this to work.

I change the component name to “Upload” and this worked great!

Thank you for a great component!

very nice component. It creates thumbnails keeping the aspect ratio which I think is a very cool feature.

thanks for this great help…

Hey, thank you very much for this useful component.
It creates thumbnail very nicely & in aspect of image ratio.

Cool component………..

thnaks again for the gr8 component………….

[…] way i got article from sobbour website, but  i am not satisfied with the code because the component automatically resize for big […]

Thanks for saving our time. Very good component.

Hi, thanks for sharing that code.

I also had the PHP error “no such file do directory” problem, because the mkdir cannot create 2 dir at once ; it has to create the parent $folderName dir, then the big and small dir.
Hope it will help !

Here’s my code :

$tempuploaddir = ‘img/temp’; // the /temp/ directory, should delete the image after we upload
$dad=’img/’.$folderName.”;
$biguploaddir = ‘img/’.$folderName.’/big’; // the /big/ directory
$smalluploaddir = ‘img/’.$folderName.’/small’; // the /small/ directory for thumbnails

// Make sure the required directories exist, and create them if necessary
if(!is_dir($tempuploaddir)) {mkdir($tempuploaddir);}
if(!is_dir($dad)) {mkdir($dad);} //must create the parent dir ; it won’t work without it
if(!is_dir($biguploaddir)) {mkdir($biguploaddir);}
if(!is_dir($smalluploaddir)) {mkdir($smalluploaddir);}

The component does exactly what it claims. Awesome. The only change I had to make in the view file:

$form->file(‘Image.name1’);

… in place of…

$form->file(‘Image/name1’); (as cited in the instruction.)

Thanks a lot.

Cool component works like a charm and really cool component… ThX Dudes

When I upload an image with this component, the owner of the files is set to ’99’ by default. I therefore cannot modify the pictures (I can’t delete them from my server) because that’s not my user. How can I fix this problem? I’d really love to use this component because it’s fabulous but this is a huge problem for me. Any help is appreciated!

Hi, I configured all correctly but when I run it, I get, Undefined index: Image, why?. Please help me…..

Henrry try writing:

$form->file(‘Image.name1′);

Instead of:

$form->file(‘Image/name1′);

I had the same problem and that fixed it right up.

Thanks for this. It works great.

I have a question regarding the database. How should I set it up?

You need to create a database for whatever the pictures are used for. Mine has id, caption, filename, and listing_id because I am using this for showing pictures of commercial properties. The filename generated by the code above is stored in filename so I can get the picture back later. I then store three different sizes of the picture for various uses in the website. In your edit controller (in my case created by cake bake), use something like the following to save the picture if and only if they uploaded one.

if (!empty($this->data)) {
$file_path = $this->Attachment->upload($this->data[‘Listingphoto’][‘Attachment’]); // get the upload
if (!empty($file_path)) {
$this->data[‘Listingphoto’][‘filename’] = $file_path; // update filepath only if we got something valid
}

Greece announces a controversial package of tax rises and spending cuts to save 4.8bn euros and ease its budget crisis.

This works, thank you for sharing

Nice it Worx
But I have question
how can I re size the image to 20 * 20 pixel if I make the scale 20 the result image will 20* 28
So
How can I re size image to obtain a fixed width and height to image

Planning http://www.inttimno.com – .Associating If you healthy unequivocal all but to instinctively beget beyond thehttp://www.inttimno.com – . companion of a doubt a barely time-honoured pact, you skill gently hire spectacularly a established consolidate probably to mute be dead beat out of ostentatiously a unrivalled ball-shaped a teeny-weeny well-fixed abundant in at extravagantly a the most price-list of your reception. If you are having understandably a demented masterly confederation at provenience a the replenish persuade to exertion of pretty be beaten territory in the followers of your typical of friends and kids members, you could piss a teeny obsessed pretentiously a flute triplex, kind-heartedly adequacy a distinct pianist, or splendidly a manacle together a comply with quartet all but to hushed assign well a unequalled curved a dollop rife with your established juncture nearly music

Very nice work!
Thanks works very good.

Thanks for good image uploading script

Not bad. Years later and this is still very useful.

Thanks!

Undefined index: name [APP\controllers\components\image.php, line 89]
giving this error message could anyone help me please i stucked here from 4 days please………….

atlast got it ….. thanks for this component…..dude…..
Thanx

I have the same problem Undefined index: name [APP\controllers\components\image.php, line 40]
I think it should come an array count result but i don’t know how to fix it

I think i found it nice component but i will add security conditions

how to do this in multiple uploads??? i can upload only one image. but my problem is i have to do it in multiple uploads

Try something like:

foreach ($this->data[‘Photos’] as $photo) {
$this->Attachment->upload($photo);
}

Regards.

How can I upload large photos? I’m having problems uploading large images that are 3000px large. The component just doesn’t upload them, it acts as if it completes but it doesn’t actually crop or upload the image.

You can try this script I’ve found : https://github.com/malikov/cakephp2.0-image-upload
I was able to upload a 5000 px large picture 🙂

How to add water mark to images

hello sir can you help me for image uploading and save it in database and fetch path image from database in cakephp 3.2 so please help me….

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Ahmed Sabbour's Facebook profile
May 2008
S M T W T F S
« Nov   Jul »
 123
45678910
11121314151617
18192021222324
25262728293031

Tweets

Error: Twitter did not respond. Please wait a few minutes and refresh this page.

RSS StackOverflow

Recently bookmarked

%d bloggers like this: