Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CodeIgniter Resizing And Cropping With Axis

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,

like image 610
Arda Avatar asked Feb 19 '23 09:02

Arda


1 Answers

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();
like image 190
Wesley Murch Avatar answered Feb 26 '23 19:02

Wesley Murch