How can I modify this image manipulation function done in codeigniter to be more efficient - codeigniter

I think this function isn't as efficient as it should be. I'd appreciate some suggestions on how I can structure it to be faster and take less memory. This is what the code does:
checks to see if the image was uploaded
add details about it (tags, name, details) to the database
if the variable $orientation was set, rotate the image
if the image is wider than 600px, resize it
create a thumbnail
I think the inefficiencies come from having steps 3,4,5 all separate. Is there any way to consolidate them? Thanks!
function insert()
{
$config['upload_path'] = './uploads/';
$config['allowed_types'] = 'jpg';
$config['max_size'] = '5000';
$config['max_width'] = '4096';
$config['max_height'] = '4096';
$this->load->library('upload', $config);
if (!$this->upload->do_upload())
{
$data = array('error' => $this->upload->display_errors());
$data['title'] = "Add Photo | Mark The Dark";
$this->load->view('photo_add_view', $data);
}
else
{
//get uploaded image info
$data = array('upload_data' => $this->upload->data());
//clean the data
$data = $this->input->xss_clean($data);
//get orientation info and erase it from POST variable
//$orientation = $_POST['orientation'];
//unset($_POST['orientation']);
//grab the tags
$tags = $_POST['tags'];
unset($_POST['tags']);
//add in some other stuff
$_POST['time'] = date('YmdHis');
$_POST['author'] = $this->dx_auth->get_user_id();
//insert it in the database
$this->db->insert('photos', $_POST);
$photo_id = $this->db->insert_id();
//add stuff to tags table
/*
$tags_array = preg_split('/[\s,;]+/', $tags);
foreach($tags_array as $tag)
{
if($tag != "" || $tag != null)
$this->db->insert('tags', array('id' => $photo_id, 'word' => $tag));
}*/
//CXtags
/*$tags_array = preg_split('/[\s,;]+/', $tags);
foreach($tags_array as $tag)
{
if($tag == "" || $tag == null)
{unset($tags_array[$tag]);}
}
*/
$tags_array = $this->CXTags->comma_to_array($tags);
foreach($tags_array as $tag)
{$tags_array[$tag] = $this->CXTags->make_safe_tag($tag);}
$topass = array(
'table' => 'photos',
'tags' => $tags_array,
'row_id' => $photo_id,
'user_id' => $_POST['author']
);
$this->CXTags->add_tags($topass);
//rename the file to the id of the record in the database
rename("./uploads/" . $data['upload_data']['file_name'], "./uploads/" . $photo_id . ".jpg");
list($width, $height, $type, $attr) = getimagesize("./uploads/" . $photo_id . '.jpg');
if (($orientation == 1) || ($orientation == 2))
{
//echo $orientation;
//rotate image
$config['image_library'] = 'GD2';
$config['source_image'] = './uploads/' . $photo_id . '.jpg';
if ($orientation == 1)
{
$config['rotation_angle'] = 270;
}
elseif ($orientation == 2)
{
$config['rotation_angle'] = 90;
}
$this->load->library('image_lib', $config);
$this->image_lib->initialize($config);
if(!$this->image_lib->rotate())
{
echo $this->image_lib->display_errors();
}
}
$this->load->library('image_lib');
if ($width > 600)
{
//resize image
$config['image_library'] = 'GD2';
$config['source_image'] = './uploads/' . $photo_id . '.jpg';
$config['new_image'] = './uploads/photos/' . $photo_id . '.jpg';
$config['create_thumb'] = FALSE;
$config['maintain_ratio'] = TRUE;
$config['width'] = 600;//180
$config['height'] = 480;
$config['master_dim'] = 'width';
$this->image_lib->initialize($config);
$this->load->library('image_lib', $config);
if(!$this->image_lib->resize())
{
echo $this->image_lib->display_errors();
}
}
else
{
$source = './uploads/' . $photo_id . '.jpg';
$destination = './uploads/photos/' . $photo_id . '.jpg';
rename($source, $destination);
/*//buggy php???
$result = copy($source, $destination);
echo "HO" . $result;
*/
}
//create thumbnail
$config['image_library'] = 'GD2';
$config['source_image'] = './uploads/photos/' . $photo_id . '.jpg';
$config['new_image'] = './uploads/thumbnails/' . $photo_id . '.jpg';
$config['create_thumb'] = TRUE;
$config['thumb_marker'] = '_thumb';
$config['maintain_ratio'] = TRUE;
$config['width'] = 180;//180
$config['height'] = 100;
$config['master_dim'] = 'width';
$this->image_lib->initialize($config);
$this->load->library('image_lib', $config);
$this->image_lib->resize();
redirect('photo/show/' . $photo_id);
}
//redirect('photo/photo_add/');
}

Well, I can answer part of your question - you can rotate images which carry the exif rotation using Codeigniter.
Firstly:
Detect the uploaded images exif data.
Look at the $exif array and handle the Orientation item.
Pass the required rotation degrees to codeigniters image_lib->rotate() function.
EG:
public function auto_rotate_image($upload_data){//iphone rotation fix
$path = $upload_data['full_path'];
$exif = exif_read_data($path);
if(isset($exif['Orientation'])){
$rotate = false;
switch($exif['Orientation']){//only really interested in the rotation
case 1: // nothing
break;
case 2:// horizontal flip
break;
case 3: // 180 rotate left
$rotate = 180;
break;
case 4: // vertical flip
break;
case 5: // vertical flip + 90 rotate right
break;
case 6: // 90 rotate right
$rotate = 270;
break;
case 7: // horizontal flip + 90 rotate right
break;
case 8: // 90 rotate left
$rotate = 90;
break;
}
if($rotate){
$config=array();
$config['image_library'] = 'gd2';
$config['source_image'] = $path;
$config['rotation_angle'] = $rotate;
$config['overwrite'] = TRUE;
$this->load->library('image_lib',$config);
if(!$this->image_lib->rotate()){
echo $this->image_lib->display_errors();
}
}
}
}

For all the work required to do your image manipulation using the objects that code igniter exposes for you, you may want to look into doing this yourself strictly with the gd functions in php. I have not used code igniter, but I've done a lot of stuff with image manipulation in php, and it's not terribly difficult.
Just by looking at your code, and I'm assuming this is the code igniter way, I see you calling image_lib->initialize() and load->library() for each individual manipulation. I'd have a look inside those methods and the rotate() and resize() methods you're using and see if they're creating and destroying the image resource with each manipulation. If you use the gd library, you can reuse the same image resource for each step and then just write it to file when you're ready (re-use the same image resource to create the thumbnail). This would probably make a huge performance gain in both execution speed and memory used.
GD Functions in PHP

You could store your configs elsewhere per codeigniter documentation, that would tighten the code up. I don't know how you could chain those events.

Related

Can't Resize Photo in Codeigniter

I need to resize photo when uploaded into path, but the photo can't resize, please correct me about my code here:
private function _do_upload()
{
$config['upload_path'] = './uploads/';
$config['allowed_types'] = '*';
$config['file_name'] = slug($this->input->post('judul')).'_'.time();
$config['image_library'] = 'gd2';
$config['quality'] = '20%';
$config['remove_space'] = TRUE;
$config['create_thumb'] = TRUE;
$config['maintain_ratio'] = TRUE;
$config['width'] = 75;
$config['height'] = 50;
$this->load->library('image_lib', $config);
$this->image_lib->initialize($config);
$this->image_lib->resize();
$this->load->library('upload',$config);
if (!$this->upload->do_upload('photo')) {
$this->session->set_flashdata('msg', $this->upload->display_errors('',''));
redirect('backoffice/tambah_video');
}
return $this->upload->data('file_name');
}
Please specify new image path and try to save.
$config['new_image'] = '/path/to/new_image.jpg';
Also make sure that you have GD library enabled.
You need to do resize() after do_upload(), and separate the configs for the image_lib and upload libraries, now they are mixed.
Try this:
private function _do_upload()
{
// step 1: upload
$upload_config['upload_path'] = './uploads/';
$upload_config['allowed_types'] = '*';
$upload_config['file_name'] = slug($this->input->post('judul')).'_'.time();
$this->load->library('upload', $upload_config);
if (!$this->upload->do_upload('photo')) {
$this->session->set_flashdata('msg', $this->upload->display_errors('',''));
redirect('backoffice/tambah_video');
}
// step 2: resize
$resize_config['source_image'] = $this->upload->upload_path . $this->upload->file_name; // uploaded file path
$resize_config['image_library'] = 'gd2';
$resize_config['quality'] = '20%';
$resize_config['remove_space'] = TRUE;
$resize_config['create_thumb'] = TRUE;
$resize_config['maintain_ratio'] = TRUE;
$resize_config['width'] = 75;
$resize_config['height'] = 50;
$this->load->library('image_lib', $resize_config);
$this->image_lib->resize();
return $this->upload->data('file_name');
}
If $resize_config['create_thumb'] = TRUE; the name of the small image will be suffixed _thumb. If you need to overwrite the uploaded image, do $resize_config['create_thumb'] = FALSE;. See also the thumb_marker and new_image configs in the official documentation.

resizing images not working with me in codeigniter

i want to resize image in codeigniter in one function
i called Image_lib and upload libraries on my controller
the images folder gets read/write .
That is my controller.
public function update(){
$config['upload_path']="./images/";
$config['allowed_types']='jpg|jpeg|png';
$config['encrypt_name']=TRUE;
$config['max_size']='1024';
$this->load->library('upload',$config);
if(!$this->upload->do_upload()){
$this->load->view('settings_v',array(
'userdata'=>$this->user->userdata(),
'c_data'=>$this->Settings_m->index(),
'error'=>$this->upload->display_errors(),
));
} else{
$image=$this->Settings_m->image(); // get current image to remove it
if(!empty($image)){
$path='images/'.$image;
unlink($path);
}
$config['image_library'] = 'gd2';
$config['source_image'] = '.images/'.$filename;
$config['new_image'] = '.images/'.$filename;
$config['create_thumb'] = TRUE;
$config['maintain_ratio'] = TRUE;
$config['width'] = 30;
$config['height'] = 30;
$this->load->library('image_lib', $config);
$this->image_lib->resize();
$file_data=$this->upload->data();
$filename=$file_data['file_name'];
$this->Settings_m->update($filename);
//redirect('Settings','refresh');
}
}
Thanks ,
Change '.images/ to './images/' also you never defined $filename before using it in image lib config.
$file_data = $this->upload->data();
$filename = $file_data['file_name'];
$config['image_library'] = 'gd2';
$config['source_image'] = './images/' . $filename;
$config['new_image'] = './images/' . $filename;
$config['create_thumb'] = TRUE;
$config['maintain_ratio'] = TRUE;
$config['width'] = 30;
$config['height'] = 30;
$this->load->library('image_lib', $config);
$this->image_lib->resize();
$this->Settings_m->update($filename);
//redirect('Settings','refresh');
Also if you just want to resize the source image and not have a separate resized image you should remove $config['new_image'] and $config['create_thumb'] as per the docs. Otherwise just use create_thumb or new_image (with a different path/filename than the original) but not both.
Notes regarding this preference:
If neither of the two preferences listed above (create_thumb, and
new_image) are used, the resizing method will instead target the
original image for processing.

How to make CI image to thumbs

again I Throw a problems. How Can i find new_image (Thumb) name.
In Controller
//Insert image .............................
$config['upload_path'] = './img/placeholders/blog';
$config['allowed_types'] = 'gif|jpg|png';
$config['encrypt_name'] = TRUE;
$config['remove_spaces'] = TRUE;
$this->upload->initialize($config);
$this->upload->do_upload('blog_images');
//Thumb Image-----------------------------
$image_des = $this->upload->data();
$config['image_library'] = 'gd2';
$config['source_image'] = './img/placeholders/blog/' . $image_des['file_name'];
$config['maintain_ratio'] = TRUE;
$config['create_thumb'] = TRUE;
$config['new_image'] = './img/placeholders/blog/thumb/' . $image_des['file_name'];
$config['width'] = 220;
$config['height'] = 140;
$this->image_lib->initialize($config);
$this->image_lib->resize();
$image_dev = $this->upload->data();
// How Can i find new image name.
$data['blog_img'] = 'img/placeholders/' . $image_des['file_name'];
$data['blog_thumbs'] = ?
after convert,
blog_img name is "e7da891c90586f7c4e89ef5724891a15.jpg"
blog_thumbs is "e7da891c90586f7c4e89ef5724891a15_thumb.jpg"
How Can i find new_image (Thumb) name. like $image_des['file_name']
But you already have it right!
$image_des['raw_name'] = 'e7da891c90586f7c4e89ef5724891a15'; //File name without extension.
$image_des['file_ext'] = '.jpg'; //The file extension with period
$data['blog_thumbs'] = 'your/preceding/path/'.
$image_des['raw_name'].'_thumb'.$image_des['file_ext'];
Refer file uploading class for explanation about return array value of $this->upload->data().

Codeigniter image resize() thumbnail name issue

When I resize an image keeping $config['create_thumb'] = true Codeigniter adds the string "_thumb" in the end of the name of resized image.
What I want ask is, is it possible to add the suffix "_thumb" in the beginning of the image name
example:
original_name.jpg
after resizing:
original_name_thumb.jpg
What I want:
thumb_original_name.jpg
Any kind of help is appreciated!
You can try this:
$data = $this->upload->data();
$config['create_thumb'] = false;
$config['new_image'] = 'thumb_'.$data['file_name'];
And if you have other problems with CI image manipulation library, maybe you can try ImageMoo.
If u don't want to add the suffix _thumb in thumbnail file name then
use $config['thumb_marker'] = false;
this can be achieved by following way
$data = $this->upload->data();
$config['create_thumb'] = false;
$config['new_image'] = 'thumb_'.$data['file_name'];
for more information about re-size image check out following Code.
function special_resize($oldFile, $width, $height)
{
$obj =& get_instance();
$info = pathinfo($oldFile);
out($info);
$tempFile = '/public/files/files/temp/' . $info['filename'] . '-' . $width . 'x' . $height . '.' . $info['extension'];
$newFile = '/public/files/files/cache/' . $info['filename'] . '-' . $width . 'x' . $height . '.' . $info['extension'];
//if image already exists, use it
if(file_exists('.' .$newFile))
return $newFile;
//math for resize/crop without loss
$o_size = _get_size( '/' . $info['dirname'] . '/' . $info['basename']);
$master_dim = ($o_size['width']-$width < $o_size['height']-$height?'width':'height');
$perc = max( (100*$width)/$o_size['width'] , (100*$height)/$o_size['height'] );
$perc = round($perc, 0);
$w_d = round(($perc*$o_size['width'])/100, 0);
$h_d = round(($perc*$o_size['height'])/100, 0);
// end math stuff
/*
* Resize image
*/
$config['image_library'] = 'gd2';
$config['source_image'] = $oldFile;
$config['new_image'] = '.' . $tempFile;
$config['maintain_ratio'] = TRUE;
$config['master_dim'] = $master_dim;
$config['width'] = $w_d + 1;
$config['height'] = $h_d + 1;
$obj->image_lib->initialize($config);
$obj->image_lib->resize();
$size = _get_size($tempFile);
unset($config); // clear $config
/*
* Crop image in weight, height
*/
$config['image_library'] = 'gd2';
$config['source_image'] = '.' . $tempFile;
$config['new_image'] = '.' . $newFile;
$config['maintain_ratio'] = FALSE;
$config['width'] = $width;
$config['height'] = $height;
$config['y_axis'] = round(($size['height'] - $height) / 2);
$config['x_axis'] = 0;
$obj->image_lib->clear();
$obj->image_lib->initialize($config);
if ( ! $obj->image_lib->crop())
{
echo $obj->image_lib->display_errors();
}
$info = pathinfo($newFile);
out($info);
return $newFile;
}

CodeIgniter Upload and Resize Problem

I have spent days trying to make this work based on the examples in the documentation but I am missing something or I am just STUPID!
I have a CMS application where users upload an image for display in a very fixed layout. We do not want to limit the file size of the uploaded image but would rather "process" it after it arrives.
The image needs to be 615px wide but some of the images uploaded directly from digital cameras are 2500X2000 and bigger so this is CRITICAL.
I pieced together the code from the manual and the image is successfully being uploaded to a folder within the CMS app. However, the image is NOT being resized.
If I ever get it to re-size, my plan is to present the image to the user for cropping using jCrop (the final image HAS to be 615X275 and it probably has to be cropped for height after resizing) and then use codeigniter to FTP the image to their site's amenities folder using the original name.
I will appreciate any help in this matter!
Here's my code:
function do_feature_upload() {
$imageName = $this->uri->segment(3);
//echo $imageName;
// Where the file is going to be placed
$config['upload_path'] = "./uploads/".$_SESSION['dbPropNumber'];
$config['allowed_types'] = 'jpg|jpeg';
$config['max_size'] = '0';
$config['file_name'] = $imageName.'.jpg';
$config['overwrite'] = 'TRUE';
$this->load->library('upload', $config);
if ( ! $this->upload->do_upload()) {
$error = array('error' => $this->upload->display_errors());
$error['propertyDropdown'] = $_SESSION['propertyDropdown'];
$error['username'] = $_SESSION['username'];
$error['dbPropNumber'] = $_SESSION['dbPropNumber'];
$error['propertyName'] = $this->content->getPropertyName($_SESSION['dbPropNumber']);
$this->load->view('upload_AmenityImage', $error);
} else {
$image_data = $this->upload->data();
$origWidth = $image_data['image_width'];
$origHeight = $image_data['image_height'];
$newWidth = 615;
$newHeight = $newWidth*$origHeight/$origWidth;
$resize = array(
'image_library'=>'gd2',
'source_image'=>base_url().'uploads/'.$_SESSION['dbPropNumber'].'/'.$imageName.'.jpg',
'new_image'=>base_url().'uploads/'.$_SESSION['dbPropNumber'].'/'.$imageName.'1.jpg',
'create_thumb' => FALSE,
'maintain_ratio'=>FALSE,
'width'=>$newWidth,
'height'=>$newHeight
);
$this->load->library('image_lib',$resize);
$this->image_lib->resize();
$data = array('upload_data' => $this->upload->data());
$data['propertyDropdown'] = $_SESSION['propertyDropdown'];
$data['username'] = $_SESSION['username'];
$data['dbPropNumber'] = $_SESSION['dbPropNumber'];
$data['propertyName'] = $this->content->getPropertyName($_SESSION['dbPropNumber']);
//Present jCrop option after image is resized
// FTP to final destination
$this->load->view('upload_success', $data);
} // end if
} // end function
I'm not entirely sure what's going wrong with your code, but here's a model function I wrote for resizing images to fit an exact target height and target width. Read through it and see if you can't figure out the solution.
$this->prefix is a property in my class that I use so I don't have to keep writing out the directory of the file. It looks like this:
$this->prefix = FCPATH.'uploads'.DIRECTORY_SEPARATOR;
Image resizer
/**
* Resizes an image to fit exact dimensions
*
* #param string filename
* #param int target_width
* #param int target_height
*
* #return array('success' ? null : 'error')
*/
function resizeImageToDimensions($filename, $target_width=700, $target_height=399)
{
$file_type = $this->getFileType($this->prefix.$filename);
if (!$file_type || $file_type != 'image')
return array('success'=>false, 'error'=>"This file doesn't exist or isn't an image");
$this->load->library('image_lib');
list($width, $height) = getimagesize($this->prefix.$filename);
$current_ratio = $width/$height;
$target_ratio = $target_width/$target_height;
$config['source_image'] = $this->prefix.$filename;
if ($current_ratio > $target_ratio)
{
//resize first to height, maintain ratio
$config['height'] = $target_height;
$config['width'] = $target_height * $current_ratio;
$this->image_lib->initialize($config);
if (!$this->image_lib->resize())
return array('success'=>false, 'error'=>"There was an error while resizing this image");
//then crop off width
$config['width'] = $target_width;
$config['maintain_ratio'] = false;
$this->image_lib->initialize($config);
if ($this->image_lib->crop())
return array('success'=>true);
else
return array('success'=>false, 'error'=>"There was an error while cropping this image");
}
else if ($current_ratio < $target_ratio)
{
//resize first to width, maintain ratio
$config['width'] = $target_width;
$config['height'] = $target_width / $current_ratio;
$this->image_lib->initialize($config);
if (!$this->image_lib->resize())
return array('success'=>false, 'error'=>"There was an error while resizing this image");
//then crop off height
$config['height'] = $target_height;
$config['maintain_ratio'] = false;
$this->image_lib->initialize($config);
if ($this->image_lib->crop())
return array('success'=>true);
else
return array('success'=>false, 'error'=>"There was an error while cropping this image");
}
else {
$config['width'] = $target_width;
$config['height'] = $target_height;
$this->image_lib->initialize($config);
if ($this->image_lib->resize())
return array('success'=>true);
else
return array('success'=>false, 'error'=>"There was an error while resizing this image");
}
}
I had the same problem a few months back and sadly, I wasn't able to figure it out. I've posted the same question here and in CodeIgniter's forums but no one could help me.
I ended up using timthumb script, which is great, but nowhere near ideal :(
So, if you're in a rush, I'd strongly recommend using timthumb. If you have some time to invest on it, I wish you the best and please, share!

Resources