4
votes

I have a image cropper on my project in CodeIgniter, which crops the images like picresize.com does (I'm using jCrop). It works great with vanilla code given below:

<?php
$save_to = $this->config->item('images_gallery_thumb_folder').$data['photo_image'];

$targ_w = $this->config->item('gallery_thumb_width');
$targ_h = $this->config->item('gallery_thumb_height');
$src = $this->config->item('images_gallery_folder').$data['photo_image'];

$types = array(1 => 'gif', 'jpeg', 'png');
list($width,$height,$type) = getimagesize($src);

switch ($types[$type]) {
    case 'jpeg':
        $img_r = imagecreatefromjpeg($src);
        break;
    case 'gif':
        $img_r = imagecreatefromgif($src);
        break;

    case 'png':
        $img_r = imagecreatefrompng($src);
        break;

    default:
        $img_r = imagecreatefromjpeg($src);
        break;
}

$dst_r = ImageCreateTrueColor($targ_w,$targ_h );

imagecopyresampled($dst_r,$img_r,0,0,$_POST['x'],$_POST['y'],
    $targ_w,$targ_h,$_POST['w'],$_POST['h']);


switch ($types[$type]) {
    case 'jpeg':
        imagejpeg($dst_r, $save_to, 90); //90 = jpeg quality
        break;
    case 'gif':
        imagegif($dst_r, $save_to);
        break;
    case 'png':
        imagepng($dst_r, $save_to);
        break;
    default:
        imagejpeg($dst_r, $save_to, 90); //90 = jpeg quality
        break;
}


imagedestroy($dst_r);
?>

But I wanna do this the CodeIgniter way.

This is what I came up with so far:

<?php
$img_config = array(
    'source_image'      => $src,
    'new_image'         => $save_to,
    'maintain_ratio'    => false,
    'width'             => $targ_w,
    'height'            => $targ_h,
    'x_axis'            => $_POST['x'],
    'y_axis'            => $_POST['y']
);

$this->load->library('image_lib',$img_config);
//$this->image_lib->resize();
$this->image_lib->crop();
?>

The thing is, it crops from positions, but it does not resize (think like I've set a bigger crop square). It only crops from given position.

I'm also using image_moo library on the project, but I couldn't also succeed with it.

Edit: In Image_moo, here is the code what I've come up with so far:

$this->image_moo
                ->load($src)
                ->crop($_POST['x'],$_POST['y'],($_POST['x']+$_POST['w']),($_POST['y']+$_POST['h']))
                ->resize($targ_w,$targ_h)
                ->save($save_to,true);

The thing is that, it when I use resize parameter, it ignores the crop line altogether and resizes the whole image. If I resize before and call crop later, it just fails. I can overcome it with using two image_moo calling, which I would not prefer.

This does not work either:

$this->image_moo
                ->load($src)
                ->crop($_POST['x'],$_POST['y'],($_POST['x']+$_POST['w']),($_POST['y']+$_POST['h']))
                //->resize($targ_w,$targ_h)
                ->save($save_to,true)
                ->resize($targ_w,$targ_h)
                ->save($save_to,true);

E.g: this way it works:

$this->image_moo
                ->load($src)
                ->crop($_POST['x'],$_POST['y'],($_POST['x']+$_POST['w']),($_POST['y']+$_POST['h']))
                //->resize($targ_w,$targ_h)
                ->save($save_to,true);
            $this->image_moo
                ->load($save_to)
                ->resize($targ_w,$targ_h)
                ->save($save_to,true);

So how do I resize+crop with given x/y offsets with CodeIgniter (or image_moo) way with one calling of image_moo or CI image_lib?

You should be probably asking why I'm concerned calling it twice. Well, the PQ is important, and I'm concerned because calling it twice will reduce the image quality.

Thanks in advance,

1
You would have to do a crop first, to get the correct ratio, and then do a resize. In Codeigniter they are split into separate functions. - Jeemusu
is your crop script works...... - Ankur Saxena
@Jeemusu - the thing is that I couldn't manage it. Should I make a bigger thumbnail first, then resize it to desired width/height you mean ? Can you please be more specific ? - Arda
@AnkurSaxena - Its working itself, but it is not enough. Not every PHP installations have GD2 etc (I'm not gonna have management rights to the server which this script is gonna be on, so.). CodeIgniter manages it all at the background. That is one of the reasons I want it the CI way. Plus having everything CI way in a CI script is better if you'd ask me. - Arda
sorry my friend don't mind.i also work on image processing through gd lib.i don't have crop code. - Ankur Saxena

1 Answers

8
votes

Your given Codeigniter code is OK except for one piece of logic: You're operating on and outputting to the same image file twice, so your output file gets overwritten by the last change to the original file.

I believe this is a limitation of CI's Image_Lib class, as each operation is done separately - there is no way to "resize and crop" in one go.

You have to reinitialize the Image_Lib class between each action to make sure the next action gets called on the output file of the last operation.

$img_config = array(
    'source_image'      => $src,
    'new_image'         => $save_to,
    'maintain_ratio'    => false,
    'width'             => $targ_w,
    'height'            => $targ_h,
    'x_axis'            => $_POST['x'],
    'y_axis'            => $_POST['y']
);

$this->load->library('image_lib', $img_config);
$this->image_lib->resize();

// Now change the input file to the one that just got resized
// See also $this->image_lib->clear()
$img_config['source_image'] = $save_to;
$this->image_lib->initialize($img_config); 

$this->image_lib->crop();

You could also use two different config arrays:

$this->load->library('image_lib');

$this->image_lib->initialize(array(
    'source_image'      => $src,
    'new_image'         => $save_to,
    'maintain_ratio'    => false,
    'width'             => $targ_w,
    'height'            => $targ_h,
));
$this->image_lib->resize();

$this->image_lib->clear();

$this->image_lib->initialize(array(
    'source_image'      => $save_to,
    'x_axis'            => $_POST['x'],
    'y_axis'            => $_POST['y']
));
$this->image_lib->crop();

Alternatively, you could create the copy of the image file first and then operate on that in each call to the image lib class, saving you the hassle of reinitializing with a new source_image:

copy($src, $save_to);
$this->load->library('image_lib', array(
    'source_image'      => $save_to,
    'maintain_ratio'    => false,
    'width'             => $targ_w,
    'height'            => $targ_h,
    'x_axis'            => $_POST['x'],
    'y_axis'            => $_POST['y']
));
$this->image_lib->resize();
$this->image_lib->crop();