LuckyCoinkydink/include/functions_images_crop.inc.php
2006-08-02 10:07:34 +00:00

451 lines
18 KiB
PHP

<?php
/**************************************************
* imgedit.inc.php
* 2003-10-17
* www.sonnd.com / www.supergarv.de
*
* COPYRIGHT (C) BY sonnd / Garvin Hicking
* Published as LGPL. Copyright notice has to stay in effect.
**************************************************/
class imgedit {
// Needed variables.
var $orientation_available;
var $real_img_name, $real_img_info, $real_img_width, $real_img_height, $http_img_name;
var $img_width, $img_height, $img_name;
var $zoombox_width;
var $area_border, $area_width, $area_height, $inner_area_x, $inner_area_y;
var $harea_width, $harea_height, $harea_img_name, $harea_visibility;
var $varea_width, $varea_height, $varea_img_name, $varea_visibility;
var $ratio;
var $overlay_clip_top, $overlay_clip_bottom, $overlay_clip_left, $overlay_clip_right;
var $slice_from_x, $slice_from_y, $slice_to_x, $slice_to_y;
var $output_template = '';
var $imgedit_smarty = array();
// Helper function to cycle through an array. Strips of "_x" and "_y" coordinates if an 'input type="image"'
// variable has been submitted.
function makeImgComp(&$array) {
foreach($array AS $key => $val) {
if (is_array($val)) {
$this->makeImgComp($array[$key]);
} elseif (preg_match('@^.*_(x|y)$@', $key)) {
$array[preg_replace('@^(.*)_(x|y)$@', '\1', $key)] = $val;
}
}
return true;
}
// Constructor.
function imgedit($img_name, $http_img_name) {
global $serendipity;
$this->makeImgComp($_REQUEST);
// Store the given variables
$this->real_img_name = $this->img_name = $img_name;
$this->real_img_info = getimagesize($this->real_img_name);
$this->real_img_width = $this->real_img_info[0];
$this->real_img_height = $this->real_img_info[1];
$this->http_img_name = $http_img_name;
// Set even more variables
$this->setDefaults();
return true;
}
// The main logic
function main() {
// 1. Parse the $_REQUEST vars.
$this->parseRequest();
// 2. Get the current size of the cropping area
$this->getCurrentArea();
// 3. Parse any actions
$this->parseRequestActions();
// 4. Valide the results of any actions
$this->validateCoordinates();
// 5. Populate the template
$this->setVars();
return true;
}
// Sets default vars.
function setDefaults() {
$this->orientation_available = true;
$this->img_width = $this->real_img_width;
$this->img_height = $this->real_img_height;
$this->img_name = $this->real_img_name;
$this->zoombox_width = 100;
$this->area_border = 6;
// Set values if they haven't been submitted yet.
if (!isset($_REQUEST['area_orientation']) || ($_REQUEST['area_orientation'] != 'h' && $_REQUEST['area_orientation'] != 'v')) {
$_REQUEST['area_orientation'] = 'h';
}
if (!isset($_REQUEST['autoguess_clicked'])) {
$_REQUEST['autoguess_clicked'] = 'false';
}
if (!isset($_REQUEST['zoombox_x'])) {
$_REQUEST['zoombox_x'] = -$this->area_border;
}
if (!isset($_REQUEST['zoombox_y'])) {
$_REQUEST['zoombox_y'] = -$this->area_border;
}
if (!isset($_REQUEST['move_increase'])) {
$_REQUEST['move_increase'] = 8;
} else {
$_REQUEST['move_increase'] = intval($_REQUEST['move_increase']);
}
return true;
}
// Parse the $_REQUEST vars
function parseRequest() {
if (isset($_REQUEST['toggle_area_orientation'])) {
if ($_REQUEST['area_orientation'] == 'h') {
$_REQUEST['area_orientation'] = 'v';
} else {
$_REQUEST['area_orientation'] = 'h';
}
}
if (isset($_REQUEST['zoombox_factor'])) {
$_REQUEST['zoombox_factor'] = floatval($_REQUEST['zoombox_factor']);
} else {
$_REQUEST['zoombox_factor'] = 1;
}
if (isset($_REQUEST['action']['enlarge'])) {
$_REQUEST['zoombox_factor'] += 0.1;
} elseif (isset($_REQUEST['action']['reduce'])) {
$_REQUEST['zoombox_factor'] -= 0.1;
}
if ($_REQUEST['zoombox_factor'] > 3) {
$_REQUEST['zoombox_factor'] = 3;
} elseif ($_REQUEST['zoombox_factor'] < 0.1) {
$_REQUEST['zoombox_factor'] = 0.1;
}
if (isset($_REQUEST['action']['moveup'])) {
$_REQUEST['zoombox_y'] -= $_REQUEST['move_increase'];
} elseif (isset($_REQUEST['action']['movedown'])) {
$_REQUEST['zoombox_y'] += $_REQUEST['move_increase'];
} elseif (isset($_REQUEST['action']['moveleft'])) {
$_REQUEST['zoombox_x'] -= $_REQUEST['move_increase'];
} elseif (isset($_REQUEST['action']['moveright'])) {
$_REQUEST['zoombox_x'] += $_REQUEST['move_increase'];
}
return true;
}
// Fit an image inside the cropping area.
function imgFit($orientation) {
if ($orientation == 'height') {
$this->imgFitHeight();
} else {
$this->imgFitWidth();
}
$_REQUEST['zoombox_factor'] = $this->ratio;
$_REQUEST['autoguess_clicked'] = 'true';
$_REQUEST['zoombox_x'] = -$this->area_border;
$_REQUEST['zoombox_y'] = -$this->area_border;
return true;
}
// Fit an image, using height as fixed value
function imgFitHeight() {
$this->img_height = $this->inner_area_y - $this->area_border;
$this->ratio = round($this->img_height / $this->real_img_height, 3);
$this->img_width = intval(round($this->real_img_width * $this->ratio));
return true;
}
// Fit an image, using width as fixed value
function imgFitWidth() {
$this->img_width = $this->inner_area_x - $this->area_border;
$this->ratio = round($this->img_width / $this->real_img_width, 3);
$this->img_height = intval(round($this->real_img_height * $this->ratio));
return true;
}
// Parse actions that were submitted
function parseRequestActions() {
global $serendipity;
if (isset($_REQUEST['autoscale'])) {
if ($this->real_img_width > $this->real_img_height) {
// The image is a horizontal one. Resize height to fit.
$this->imgFit('height');
} else {
// The image is a vertical one. Resize width to fit.
$this->imgFit('width');
}
} elseif (isset($_REQUEST['scale'])) {
if ($this->real_img_width > $this->real_img_height) {
// The image is a horizontal one. Resize width to fit.
$this->imgFit('width');
} else {
// The image is a vertical one. Resize height to fit.
$this->imgFit('height');
}
} else {
$this->img_width = intval(round($this->real_img_width * $_REQUEST['zoombox_factor']));
$this->img_height = intval(round($this->real_img_height * $_REQUEST['zoombox_factor']));
}
// Check which template to use
if (isset($_REQUEST['crop'])) {
$this->output_template = 'admin/media_imgedit_done.tpl';
} else {
$this->output_template = 'admin/media_imgedit.tpl';
if ($this->orientation_available) {
$this->imgedit_smarty['orientation_available'] = true;
}
}
// The final action. Cropping will take place.
if (isset($_REQUEST['crop'])) {
$new_img_name = $this->img_name . '.tmp';
if ($this->img_width <= $this->area_width && $this->img_height <= $this->area_height) {
$this->imgedit_smarty['image_no_cut'] = true;
$new_img_width = $this->img_width;
$new_img_height = $this->img_height;
} else {
$this->imgedit_smarty['image_cut'] = true;
$new_img_width = $this->area_width - $this->area_border - $this->area_border;
$new_img_height = $this->area_height - $this->area_border - $this->area_border;
}
$this->slice_from_x = ($this->area_border + $_REQUEST['zoombox_x']) / $_REQUEST['zoombox_factor'];
$this->slice_from_y = ($this->area_border + $_REQUEST['zoombox_y']) / $_REQUEST['zoombox_factor'];
$slice_width = $new_img_width / $_REQUEST['zoombox_factor'];
$slice_height = $new_img_height / $_REQUEST['zoombox_factor'];
$this->slice_to_x = $this->slice_from_x + $this->slice_width;
$this->slice_to_y = $this->slice_from_y + $this->slice_height;
// TODO:
// - Operate also on PNG, TIFF etc.
// - Support image magick
// - Save file as new image!
// - Optionally ask whether to only make a thumbnail from the extracted portion
// PHP: int imagecopyresampled ( resource dst_im, resource src_im, int dstX, int dstY, int srcX, int srcY, int dstW, int dstH, int srcW, int srcH)
// Open the user's image.
$img_res = imagecreatefromjpeg($this->img_name);
// Init a blank picture to save the cropped image in.
$new_img_res = imagecreatetruecolor($new_img_width, $new_img_height);
// Crop the image based on user input, save the resulting image. If either action fails, report an error.
if (!imagecopyresampled($new_img_res, $img_res, 0, 0, $this->slice_from_x, $this->slice_from_y, $new_img_width, $new_img_height, $slice_width, $slice_height) ||
!imageJpeg($new_img_res, $new_img_name, 90)) {
$this->imgedit_smarty['image_error'] = true;
}
$backup = $this->increment($this->img_name);
rename($this->img_name, $backup . '.backup');
rename($new_img_name, $this->img_name);
$http_new_file = preg_replace('@^' . preg_quote($serendipity['serendipityPath'] . $serendipity['uploadPath']) . '@', '', $this->img_name);
serendipity_makeThumbnail(basename($http_new_file), dirname($http_new_file) . '/');
$this->img_name = $new_img_name;
$this->img_width = $new_img_width;
$this->img_height = $new_img_height;
}
return true;
}
function increment($fullfile) {
$d = dirname($fullfile) . '/';
$f = basename($fullfile);
$f = time() . '.' . $f;
return $d . $f;
}
// Checks if any coordinates are out of allowed range
function validateCoordinates() {
if ($this->img_width > $this->area_width) {
$c_img_width = $this->img_width;
$ca_img_width = $this->area_width;
$x_area_border = $this->area_border;
} else {
$c_img_width = $this->area_width;
$ca_img_width = $this->img_width;
$x_area_border = -$this->area_border;
}
if ($this->img_height > $this->area_height) {
$c_img_height = $this->img_height;
$ca_img_height = $this->area_height;
$y_area_border = $this->area_border;
} else {
$c_img_height = $this->area_height;
$ca_img_height = $this->img_height;
$y_area_border = -$this->area_border;
}
if ($_REQUEST['zoombox_x'] < (0 - $this->area_border)) {
$_REQUEST['zoombox_x'] = 0 - $this->area_border;
} elseif ($_REQUEST['zoombox_x'] > ($this->img_width - $ca_img_width + $x_area_border)) {
$_REQUEST['zoombox_x'] = $this->img_width - $ca_img_width + $x_area_border;
}
if ($_REQUEST['zoombox_y'] < (0 - $this->area_border)) {
$_REQUEST['zoombox_y'] = 0 - $this->area_border;
} elseif ($_REQUEST['zoombox_y'] > ($this->img_height - $ca_img_height + $y_area_border)) {
$_REQUEST['zoombox_y'] = $this->img_height - $ca_img_height + $y_area_border;
}
$this->overlay_clip_top += $_REQUEST['zoombox_y'];
$this->overlay_clip_bottom += $_REQUEST['zoombox_y'];
$this->overlay_clip_left += $_REQUEST['zoombox_x'];
$this->overlay_clip_right += $_REQUEST['zoombox_x'];
return true;
}
// Sets the sizes of the cropping area
function setArea($img_name, $orientation = 'h') {
global $serendipity;
$fimg = serendipity_getTemplateFile('admin/img/' . $img_name, 'serendipityPath');
$hfimg = serendipity_getTemplateFile('admin/img/' . $img_name, 'serendipityHTTPPath');
$img_info = getImageSize($fimg);
if ($orientation == 'h') {
$this->harea_width = $img_info[0];
$this->harea_height = $img_info[1];
$this->harea_img_name = $hfimg;
} else {
$this->varea_width = $img_info[0];
$this->varea_height = $img_info[1];
$this->varea_img_name = $hfimg;
}
return true;
}
// Get the size of the selected cropping area
function getCurrentArea() {
if ($_REQUEST['area_orientation'] == 'h') {
$this->area_width = $this->harea_width;
$this->area_height = $this->harea_height;
$this->varea_visibility = 'hidden';
$this->harea_visibility = 'visible';
} else {
$this->area_width = $this->varea_width;
$this->area_height = $this->varea_height;
$this->varea_visibility = 'visible';
$this->harea_visibility = 'hidden';
}
$this->inner_area_x = $this->area_width - $this->area_border;
$this->inner_area_y = $this->area_height - $this->area_border;
$this->overlay_clip_top = $this->area_border;
$this->overlay_clip_right = $this->area_width - $this->area_border;
$this->overlay_clip_bottom = $this->area_height - $this->area_border;
$this->overlay_clip_left = $this->area_border;
return true;
}
// Set the template variables
function setVars() {
$this->imgedit_smarty['zoombox_width'] = $this->zoombox_width;
$this->imgedit_smarty['zoombox_padding'] = $this->zoombox_width + 20;
$this->imgedit_smarty['area_width'] = $this->area_width;
$this->imgedit_smarty['area_height'] = $this->area_height;
$this->imgedit_smarty['varea_width'] = $this->varea_width;
$this->imgedit_smarty['varea_height'] = $this->varea_height;
$this->imgedit_smarty['varea_img_name'] = $this->varea_img_name;
$this->imgedit_smarty['varea_visibility'] = $this->varea_visibility;
$this->imgedit_smarty['harea_width'] = $this->harea_width;
$this->imgedit_smarty['harea_height'] = $this->harea_height;
$this->imgedit_smarty['harea_img_name'] = $this->harea_img_name;
$this->imgedit_smarty['harea_visibility'] = $this->harea_visibility;
$this->imgedit_smarty['area_border'] = $this->area_border;
$this->imgedit_smarty['refresh_line'] = time();
$this->imgedit_smarty['real_img_width'] = $this->real_img_width;
$this->imgedit_smarty['real_img_height'] = $this->real_img_height;
$this->imgedit_smarty['real_img_name'] = $this->real_img_name;
$this->imgedit_smarty['http_img_name'] = $this->http_img_name;
$this->imgedit_smarty['img_width'] = $this->img_width;
$this->imgedit_smarty['img_height'] = $this->img_height;
$this->imgedit_smarty['zoom_img_width'] = $this->img_width;
$this->imgedit_smarty['zoom_img_height'] = $this->img_height;
$this->imgedit_smarty['img_name'] = $this->img_name;
$this->imgedit_smarty['overlay_clip_top'] = $this->overlay_clip_top;
$this->imgedit_smarty['overlay_clip_bottom'] = $this->overlay_clip_bottom;
$this->imgedit_smarty['overlay_clip_left'] = $this->overlay_clip_left;
$this->imgedit_smarty['overlay_clip_right'] = $this->overlay_clip_right;
$this->imgedit_smarty['slice_from_x'] = $this->slice_from_x;
$this->imgedit_smarty['slice_from_y'] = $this->slice_from_y;
$this->imgedit_smarty['slice_to_x'] = $this->slice_to_x;
$this->imgedit_smarty['slice_to_y'] = $this->slice_to_y;
$this->imgedit_smarty['zoombox_x'] = $_REQUEST['zoombox_x'];
$this->imgedit_smarty['zoombox_y'] = $_REQUEST['zoombox_y'];
$this->imgedit_smarty['zoombox_factor'] = $_REQUEST['zoombox_factor'];
$this->imgedit_smarty['php_self'] = $_SERVER['PHP_SELF'];
$this->imgedit_smarty['area_orientation'] = $_REQUEST['area_orientation'];
$this->imgedit_smarty['move_increase'] = $_REQUEST['move_increase'];
$this->imgedit_smarty['autoguess_clicked'] = $_REQUEST['autoguess_clicked'];
$this->imgedit_smarty['my_url'] = htmlspecialchars($_SERVER['REQUEST_URI']);
if ($_REQUEST['autoguess_clicked'] == 'true') {
$this->imgedit_smarty['scale_visibility'] = 'visible';
} else {
$this->imgedit_smarty['scale_visibility'] = 'hidden';
}
return true;
}
}
?>