Thursday, July 9, 2009

Image crop component for CakePHP

\app\controllers\components\images.php

<?php
/**
* Images component for CakePHP.
* @author Amit Chavda <amit.chavda@gmail.com>
* @copyright Amit Chavda
* @link http://www.cakephp.org CakePHP
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.

* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

class ImagesComponent extends Object {
/**
* The Upload Directory
* @access public
* @var string
*/
var $upload_dir = "";

/**
* The Upload Directory Path
* @access public
* @var string
*/
var $upload_path = "";

/**
* New name of the large image & New name of the thumbnail image
* @access public
* @var string
*/
var $large_image_name = "resized_pic.jpg";
var $thumb_image_name = "thumbnail_pic.jpg";

/**
* The Max File Size. Approx 1MB
* @access public
* @var string
*/
var $max_file = "1148576";

/**
* The Max width allowed for the large image
* @access public
* @var string
*/
var $max_width = "500";

/**
* The Width of thumbnail image
* @access public
* @var string
*/
var $thumb_width = "100";

/**
* The Height of thumbnail image
* @access public
* @var string
*/
var $thumb_height = "100";

//Image functions
//You do not need to alter these functions
function resizeImage($image,$width,$height,$scale) {
$newImageWidth = ceil($width * $scale);
$newImageHeight = ceil($height * $scale);
$newImage = imagecreatetruecolor($newImageWidth,$newImageHeight);
$source = imagecreatefromjpeg($image);
imagecopyresampled($newImage,$source,0,0,0,0,$newImageWidth,$newImageHeight,$width,$height);
imagejpeg($newImage,$image,90);
chmod($image, 0777);
return $image;
}

//You do not need to alter these functions
function resizeThumbnailImage($thumb_image_name, $image, $width, $height, $start_width, $start_height, $scale){
$newImageWidth = ceil($width * $scale);
$newImageHeight = ceil($height * $scale);
$newImage = imagecreatetruecolor($newImageWidth,$newImageHeight);
$source = imagecreatefromjpeg($image);
imagecopyresampled($newImage,$source,0,0,$start_width,$start_height,$newImageWidth,$newImageHeight,$width,$height);
imagejpeg($newImage,$thumb_image_name,90);
chmod($thumb_image_name, 0777);
return $thumb_image_name;
}

//You do not need to alter these functions
function getHeight($image) {
$sizes = getimagesize($image);
$height = $sizes[1];
return $height;
}

//You do not need to alter these functions
function getWidth($image) {
$sizes = getimagesize($image);
$width = $sizes[0];
return $width;
}
}
?>



\app\controllers\images_controller.php

<?php
class ImagesController extends AppController {

var $components = array('Images');
var $helpers = array('Html', 'Form', 'Ajax');

function index() {
$error = '';
$this->Images->upload_dir = WWW_ROOT . 'files' . DS . 'upload_pic' . DS;
//Image Locations
$large_image_location = $this->Images->upload_dir.$this->Images->large_image_name;
$thumb_image_location = $this->Images->upload_dir.$this->Images->thumb_image_name;

//Create the upload directory with the right permissions if it doesn't exist
if(!is_dir($this->Images->upload_dir)){
mkdir($this->Images->upload_dir, 0777);
chmod($this->Images->upload_dir, 0777);
}

//Check to see if any images with the same names already exist
if (file_exists($large_image_location)){
if(file_exists($thumb_image_location)){
$thumb_photo_exists = 'files/upload_pic/'.$this->Images->thumb_image_name;
}else{
$thumb_photo_exists = "";
}
$large_photo_exists = 'files/upload_pic/'. $this->Images->large_image_name;
$this->set('current_large_image_width', $this->Images->getWidth($large_image_location));
$this->set('current_large_image_height', $this->Images->getHeight($large_image_location));
} else {
$thumb_photo_exists = '';
$large_photo_exists = '';
}
$this->set('large_photo_exists', $large_photo_exists);
$this->set('thumb_photo_exists', $thumb_photo_exists);
$this->set('thumb_width', $this->Images->thumb_width);
$this->set('thumb_height', $this->Images->thumb_height);

if(!empty($this->data)) {

if(isset($this->data['Image']['image'])) {
//Get the file information
$userfile_name = $this->data['Image']['image']['name'];
$userfile_tmp = $this->data['Image']['image']['tmp_name'];
$userfile_size = $this->data['Image']['image']['size'];
$filename = basename($this->data['Image']['image']['name']);
$file_ext = substr($filename, strrpos($filename, '.') + 1);

//Only process if the file is a JPG and below the allowed limit
if((!empty($this->data['Image']["image"])) && ($this->data['Image']['image']['error'] == 0)) {
if (($file_ext!="jpg") && ($userfile_size > $this->Images->max_file)) {
$error= "ONLY jpeg images under 1MB are accepted for upload";
}
}else{
$error= "Select a jpeg image for upload";
}
//Everything is ok, so we can upload the image.
if (strlen($error)==0){
if (isset($this->data['Image']['image']['name'])){

move_uploaded_file($userfile_tmp, $large_image_location);
chmod($large_image_location, 0777);

$width = $this->Images->getWidth($large_image_location);
$height = $this->Images->getHeight($large_image_location);
//Scale the image if it is greater than the width set above
if ($width > $this->Images->max_width){
$scale = $this->Images->max_width/$width;
$uploaded = $this->Images->resizeImage($large_image_location,$width,$height,$scale);
}else{
$scale = 1;
$uploaded = $this->Images->resizeImage($large_image_location,$width,$height,$scale);
}
//Delete the thumbnail file so the user can create a new one
if (file_exists($thumb_image_location)) {
unlink($thumb_image_location);
}
}
//Refresh the page to show the new uploaded image
$this->redirect(array('controller' => "images", 'action' => 'index'));
}
}

if(isset($this->data['Image']['x1'])) {
//Get the new coordinates to crop the image.
$x1 = $this->data['Image']["x1"];
$y1 = $this->data['Image']["y1"];
$x2 = $this->data['Image']["x2"];
$y2 = $this->data['Image']["y2"];
$w = $this->data['Image']["w"];
$h = $this->data['Image']["h"];
//Scale the image to the thumb_width set above
$scale = $this->Images->thumb_width/$w;
$cropped = $this->Images->resizeThumbnailImage($thumb_image_location, $large_image_location,$w,$h,$x1,$y1,$scale);
$this->redirect(array('controller' => "images", 'action' => 'index'));
}
$this->set('error', $error);
}
}

function deleteImage() {
$this->Images->upload_dir = WWW_ROOT . 'files' . DS . 'upload_pic' . DS;
//$large_image_location = $this->Images->upload_dir.$this->Images->large_image_name;
$thumb_image_location = $this->Images->upload_dir.$this->Images->thumb_image_name;

/*if (file_exists($large_image_location)) {
unlink($large_image_location);
}*/
if (file_exists($thumb_image_location)) {
unlink($thumb_image_location);
}
$this->redirect(array('controller' => "images", 'action' => 'index'));
}
}
?>


\app\models\image.php

<?php
class Image extends AppModel {
var $name = 'Image';
var $useTable = false;
}
?>

\app\views\images\index.ctp


<?php
echo $javascript->link('jquery-pack');
echo $javascript->link('jquery.imgareaselect-0.3.min');
?>
<?php
//Only display the javacript if an image has been uploaded
if(strlen($large_photo_exists)>0){
//$current_large_image_width = getWidth($large_image_location);
//$current_large_image_height = getHeight($large_image_location);?>
<script type="text/javascript">
function preview(img, selection) {
var scaleX = <?php echo $thumb_width;?> / selection.width;
var scaleY = <?php echo $thumb_height;?> / selection.height;

$('#thumbnail + div > img').css({
width: Math.round(scaleX * <?php echo $current_large_image_width;?>) + 'px',
height: Math.round(scaleY * <?php echo $current_large_image_height;?>) + 'px',
marginLeft: '-' + Math.round(scaleX * selection.x1) + 'px',
marginTop: '-' + Math.round(scaleY * selection.y1) + 'px'
});
$('#x1').val(selection.x1);
$('#y1').val(selection.y1);
$('#x2').val(selection.x2);
$('#y2').val(selection.y2);
$('#w').val(selection.width);
$('#h').val(selection.height);
}

$(document).ready(function () {
$('#save_thumb').click(function() {
var x1 = $('#x1').val();
var y1 = $('#y1').val();
var x2 = $('#x2').val();
var y2 = $('#y2').val();
var w = $('#w').val();
var h = $('#h').val();
if(x1=="" || y1=="" || x2=="" || y2=="" || w=="" || h==""){
alert("You must make a selection first");
return false;
}else{
return true;
}
});
});

$(window).load(function () {
$('#thumbnail').imgAreaSelect({ aspectRatio: '1:1', onSelectChange: preview });
});

function checkform(){
document.getElementById('ImageX1').value = document.getElementById('x1').value;
document.getElementById('ImageY1').value = document.getElementById('y1').value;
document.getElementById('ImageX2').value = document.getElementById('x2').value;
document.getElementById('ImageY2').value = document.getElementById('y2').value;
document.getElementById('ImageW').value = document.getElementById('w').value;
document.getElementById('ImageH').value = document.getElementById('h').value;
//alert(document.getElementById('x1').value);
return true;
}

</script>
<?php }?>
<h1>Photo Upload and Crop</h1>
<?php
//Display error message if there are any
if(isset($error) and strlen($error)>0){
echo "<ul><li><strong>Error!</strong></li><li>".$error."</li></ul>";
}
if(strlen($large_photo_exists)>0 && strlen($thumb_photo_exists)>0){
echo "<p><strong>NOTE:</strong> If the thumbnail image looks the same as the previous one, just hit refresh a couple of times.</p>";
echo '<img src="'.$large_photo_exists.'" style="float: left; margin-right: 10px;" id="thumbnail" alt="Main" /> <img src="'.$thumb_photo_exists.'" style="float: left; margin-right: 10px;" id="thumbnail" alt="Thumbnail" />';
echo "<p>".$html->link('Delete Images', array('controller'=>'images', 'action'=>'deleteImage'))."</p>";
}else{
if(strlen($large_photo_exists)>0){?>
<h2>Create Thumbnail</h2>
<div align="center">
<img src="<?php echo $large_photo_exists;?>" style="float: left; margin-right: 10px;" id="thumbnail" alt="Create Thumbnail" />
<div style="float:left; position:relative; overflow:hidden; width:<?php echo $thumb_width;?>px; height:<?php echo $thumb_height;?>px;">
<img src="<?php echo $large_photo_exists;?>" style="position: relative;" alt="Thumbnail Preview" />
</div>
<br style="clear:both;"/>
<?php echo $form->create('Image', array('action' => 'index', 'name'=>'thumbnail', 'onsubmit'=>'return checkform()'))?>
<?php echo $form->hidden('x1');?>
<?php echo $form->hidden('y1');?>
<?php echo $form->hidden('x2');?>
<?php echo $form->hidden('y2');?>
<?php echo $form->hidden('w');?>
<?php echo $form->hidden('h');?>

<input type="hidden" name="x1" value="" id="x1" />
<input type="hidden" name="y1" value="" id="y1" />
<input type="hidden" name="x2" value="" id="x2" />
<input type="hidden" name="y2" value="" id="y2" />
<input type="hidden" name="w" value="" id="w" />
<input type="hidden" name="h" value="" id="h" />
<!--<input type="submit" name="upload_thumbnail" value="Save Thumbnail" id="save_thumb" />-->
<?php echo $form->submit('Save Thumbnail', array('div' => false));?>
<?php echo $form->end(); ?>
</div>
<hr />
<?php } ?>
<h2>Upload Photo</h2>
<?php echo $form->create('Image', array('action' => 'index', 'name'=>'photo', 'type'=>'file'))?>
Photo <?php echo $form->file('image');?> <?php echo $form->submit('Upload', array('div' => false));?>
<?php echo $form->end(); ?>
<?php } ?>

All The Best,
Amit Chavda