Skip to content

Commit

Permalink
rotate in progress
Browse files Browse the repository at this point in the history
  • Loading branch information
troex committed Mar 4, 2012
1 parent 0af121e commit 54f0d03
Show file tree
Hide file tree
Showing 7 changed files with 161 additions and 33 deletions.
5 changes: 3 additions & 2 deletions css/toolbar.css
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,9 @@
.elfinder-button-icon-help { background-position: 0 -480px; }
.elfinder-button-icon-resize { background-position: 0 -512px; }
.elfinder-button-icon-search { background-position: 0 -561px; }
.elfinder-button-icon-sort { background-position: 0 -577px; }

.elfinder-button-icon-sort { background-position: 0 -577px; }
.elfinder-button-icon-rotate-r { background-position: 0 -625px; }
.elfinder-button-icon-rotate-l { background-position: 0 -641px; }

/* button with dropdown menu*/
.elfinder .elfinder-menubutton { overflow:visible; }
Expand Down
Binary file modified img/toolbar.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
52 changes: 47 additions & 5 deletions js/commands/resize.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,41 @@ elFinder.prototype.commands.resize = function() {
rhandlec = $('<div class="elfinder-resize-handle"/>'),
uiresize = $('<div class="elfinder-resize-uiresize"/>'),
uicrop = $('<div class="elfinder-resize-uicrop"/>'),
uibuttonset = '<div class="ui-widget-content ui-corner-all elfinder-buttonset"/>',
uibutton = '<div class="ui-state-default elfinder-button"/>',
uiseparator = '<span class="ui-widget-content elfinder-toolbar-button-separator"/>',
uirotate = $('<div class="elfinder-resize-rotate"/>'),
uideg270 = $(uibutton).attr('title',fm.i18n('rotate-cw')).append($('<span class="elfinder-button-icon elfinder-button-icon-rotate-l"/>')
.click(function(){
var val = (parseInt(degree.val()) || 0) - 90;
//val = parseInt(val / 90) * 90;
if (val < 0) {
val = 360 + val;
}
degree.val(val);
})),
uideg90 = $(uibutton).attr('title',fm.i18n('rotate-ccw')).append($('<span class="elfinder-button-icon elfinder-button-icon-rotate-r"/>')
.click(function(){
var val = (parseInt(degree.val()) || 0) + 90;
//val = parseInt(val / 90) * 90;
if (val >= 360) {
val = val - 360;
}
degree.val(val);
})),
uiprop = $('<span />'),
reset = $('<div class="ui-state-default ui-corner-all elfinder-resize-reset"><span class="ui-icon ui-icon-arrowreturnthick-1-w"/></div>'),
uitype = $('<div class="elfinder-resize-type"><div class="elfinder-resize-label">'+fm.i18n('mode')+'</div></div>')
.append('<input checked="checked" type="radio" name="type" id="type-resize" value="resize"/><label for="type-resize">'+fm.i18n('resize')+'</label>')
.append('<input type="radio" name="type" id="type-crop" value="crop"/><label for="type-crop">'+fm.i18n('crop')+'</label>'),
.append('<input type="radio" name="type" id="type-resize" value="resize" checked="checked" /><label for="type-resize">'+fm.i18n('resize')+'</label>')
.append('<input type="radio" name="type" id="type-crop" value="crop"/><label for="type-crop">'+fm.i18n('crop')+'</label>')
.append('<input type="radio" name="type" id="type-rotate" value="rotate"/><label for="type-rotate">'+fm.i18n('rotate')+'</label>'),
type = $('input', uitype)
.change(function() {
uiresize.add(uicrop).toggle();
resetView();
resizable(true);
croppable(true);
// TODO rotateable

var val = $('input:checked', uitype).val();
if (val == 'resize') {
Expand Down Expand Up @@ -82,6 +106,7 @@ elFinder.prototype.commands.resize = function() {
pointY = $(input),
offsetX = $(input),
offsetY = $(input),
degree = $('<input type="text" size="3" maxlength="3"/>'),
ratio = 1,
prop = 1,
owidth = 0,
Expand All @@ -95,7 +120,7 @@ elFinder.prototype.commands.resize = function() {

owidth = img.width();
oheight = img.height();
ratio = (owidth/oheight).toFixed(2);
ratio = owidth/oheight;
resize.updateView(owidth, oheight);

rhandle.append(img.show()).show();
Expand Down Expand Up @@ -246,7 +271,7 @@ elFinder.prototype.commands.resize = function() {
}
},
save = function() {
var w, h, x, y;
var w, h, x, y, d;
var mode = $('input:checked', uitype).val();

width.add(height).change();
Expand All @@ -259,6 +284,13 @@ elFinder.prototype.commands.resize = function() {
h = parseInt(offsetY.val()) || 0;
x = parseInt(pointX.val()) || 0;
y = parseInt(pointY.val()) || 0;
} else if (mode = 'rotate') {
w = parseInt(offsetX.val()) || 0;
h = parseInt(offsetY.val()) || 0;
d = parseInt(degree.val()) || 0;
if (d < 0 || d > 360) {
return fm.error('Invalid rotate degree');
}
}

if (w <= 0 || h <= 0) {
Expand All @@ -279,6 +311,7 @@ elFinder.prototype.commands.resize = function() {
height : h,
x : x,
y : y,
degree : d,
mode : mode
},
notify : {type : 'resize', cnt : 1}
Expand Down Expand Up @@ -307,13 +340,22 @@ elFinder.prototype.commands.resize = function() {
uicrop.append($(row).append($(label).text('X')).append(pointX))
.append($(row).append($(label).text('Y')).append(pointY))
.append($(row).append($(label).text(fm.i18n('width'))).append(offsetX))
.append($(row).append($(label).text(fm.i18n('height'))).append(offsetY))
.append($(row).append($(label).text(fm.i18n('height'))).append(offsetY));

uirotate.append($(row)
.append($(label).text(fm.i18n('rotate')))
.append($('<div style="float:left">')
.append(degree)
.append($('<span/>').text(fm.i18n('degree')))
).append($(uibuttonset).append(uideg270).append($(uiseparator)).append(uideg90))
);

dialog.append(uitype);

control.append($(row))
.append(uiresize)
.append(uicrop.hide())
.append(uirotate.hide())
.find('input,select').attr('disabled', 'disabled');

rhandle.append('<div class="'+hline+' '+hline+'-top"/>')
Expand Down
14 changes: 9 additions & 5 deletions js/i18n/elfinder.en.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* English translation
* @author Troex Nevelin <[email protected]>
* @version 2011-07-10
* @version 2012-02-25
*/
if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object') {
elFinder.prototype.i18.en = {
Expand Down Expand Up @@ -101,7 +101,7 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
'cmdup' : 'Go to parent directory',
'cmdupload' : 'Upload files',
'cmdview' : 'View',
'cmdresize' : 'Resize image',
'cmdresize' : 'Resize & Rotate',
'cmdsort' : 'Sort',

/*********************************** buttons ***********************************/
Expand Down Expand Up @@ -226,9 +226,13 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
'scale' : 'Scale',
'width' : 'Width',
'height' : 'Height',
'mode' : 'Mode',
'resize' : 'Resize',
'crop' : 'Crop',
'mode' : 'Mode',
'resize' : 'Resize',
'crop' : 'Crop',
'rotate' : 'Rotate',
'rotate-l90' : '90-degree left rotation',
'rotate-r90' : '90-degree right rotation',
'deg' : 'Deg',

/********************************** mimetypes **********************************/
'kindUnknown' : 'Unknown',
Expand Down
8 changes: 6 additions & 2 deletions js/i18n/elfinder.jp.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* Japanese translation
* @author Tomoaki Yoshida <[email protected]>
* @version 2012-02-22
* @version 2012-02-25
*/
if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object') {
elFinder.prototype.i18.jp = {
Expand Down Expand Up @@ -101,7 +101,7 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
'cmdup' : '親ディレクトリーへ移動',
'cmdupload' : 'ファイルアップロード',
'cmdview' : 'ビュー',
'cmdresize' : 'リサイズ',
'cmdresize' : 'リサイズと回転',
'cmdsort' : 'ソート',

/*********************************** buttons ***********************************/
Expand Down Expand Up @@ -229,6 +229,10 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
'mode' : 'モード',
'resize' : 'リサイズ',
'crop' : '切り抜き',
'rotate' : '回転',
'rotate-l90' : '90度左回転',
'rotate-r90' : '90度右回転',
'deg' : '度',

/********************************** mimetypes **********************************/
'kindUnknown' : '不明',
Expand Down
6 changes: 4 additions & 2 deletions php/elFinder.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class elFinder {
'search' => array('q' => true, 'mimes' => false),
'info' => array('targets' => true),
'dim' => array('target' => true),
'resize' => array('target' => true, 'width' => true, 'height' => true, 'mode' => false, 'x' => false, 'y' => false)
'resize' => array('target' => true, 'width' => true, 'height' => true, 'mode' => false, 'x' => false, 'y' => false, 'degree' => false)
);

/**
Expand Down Expand Up @@ -1020,13 +1020,15 @@ protected function resize($args) {
$x = (int)$args['x'];
$y = (int)$args['y'];
$mode = $args['mode'];
$bg = null;
$degree = (int)$args['degree'];

if (($volume = $this->volume($target)) == false
|| ($file = $volume->file($target)) == false) {
return array('error' => $this->error(self::ERROR_RESIZE, '#'.$target, self::ERROR_FILE_NOT_FOUND));
}

return ($file = $volume->resize($target, $width, $height, $x, $y, $mode))
return ($file = $volume->resize($target, $width, $height, $x, $y, $mode, $bg, $degree))
? array('changed' => array($file))
: array('error' => $this->error(self::ERROR_RESIZE, $volume->path($target), $volume->error()));
}
Expand Down
109 changes: 92 additions & 17 deletions php/elFinderVolumeDriver.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -1601,12 +1601,16 @@ public function archive($hashes, $mime) {
* @param string $hash image file
* @param int $width new width
* @param int $height new height
* @param bool $crop crop image
* @param int $x X start poistion for crop
* @param int $y Y start poistion for crop
* @param string $mode action how to mainpulate image
* @return array|false
* @author Dmitry (dio) Levashov
* @author Alexey Sukhotin
* @author nao-pon
* @author Troex Nevelin
**/
public function resize($hash, $width, $height, $x, $y, $mode = 'resize', $bg='') {
public function resize($hash, $width, $height, $x, $y, $mode = 'resize', $bg = '', $degree = 0) {
if ($this->commandDisabled('resize')) {
return $this->setError(elFinder::ERROR_PERM_DENIED);
}
Expand Down Expand Up @@ -1636,14 +1640,18 @@ public function resize($hash, $width, $height, $x, $y, $mode = 'resize', $bg='')
break;

case 'fitsquare':
$result = $this->imgSquareFit($path, $width, $height, 'center', 'middle', $bg ? $bg : $this->options['tmbBgColor']);
$result = $this->imgSquareFit($path, $width, $height, 'center', 'middle', ($bg ? $bg : $this->options['tmbBgColor']));
break;


case 'rotate':
$result = $this->imgRotate($path, $degree, ($bg ? $bg : $this->options['tmbBgColor']));
break;

default:
$result = $this->imgResize($path, $width, $height, false, true);
break;
}
break;
}

if ($result) {
if (!empty($file['tmb']) && $file['tmb'] != "1") {
$this->rmTmb($file['tmb']);
Expand Down Expand Up @@ -2612,7 +2620,8 @@ protected function createTmb($path, $stat) {
* @param bool $resizeByBiggerSide resize image based on bigger side if true
* @param string $destformat image destination format
* @return string|false
* @author Dmitry (dio) Levashov, Alexey Sukhotin
* @author Dmitry (dio) Levashov
* @author Alexey Sukhotin
**/
protected function imgResize($path, $width, $height, $keepProportions = false, $resizeByBiggerSide = true, $destformat = null) {
if (($s = @getimagesize($path)) == false) {
Expand Down Expand Up @@ -2718,7 +2727,8 @@ protected function imgResize($path, $width, $height, $keepProportions = false, $
* @param bool $y crop top offset
* @param string $destformat image destination format
* @return string|false
* @author Dmitry (dio) Levashov, Alexey Sukhotin
* @author Dmitry (dio) Levashov
* @author Alexey Sukhotin
**/
protected function imgCrop($path, $width, $height, $x, $y, $destformat = null) {
if (($s = @getimagesize($path)) == false) {
Expand Down Expand Up @@ -2793,9 +2803,10 @@ protected function imgCrop($path, $width, $height, $x, $y, $destformat = null) {
* @param string $bgcolor square background color in #rrggbb format
* @param string $destformat image destination format
* @return string|false
* @author Dmitry (dio) Levashov, Alexey Sukhotin
* @author Dmitry (dio) Levashov
* @author Alexey Sukhotin
**/
protected function imgSquareFit($path, $width, $height, $align = 'center', $valign = 'middle', $bgcolor = '#0000ff', $destformat = null) {
protected function imgSquareFit($path, $width, $height, $align = 'center', $valign = 'middle', $bgcolor = '#0000ff', $destformat = null) {
if (($s = @getimagesize($path)) == false) {
return false;
}
Expand All @@ -2808,11 +2819,9 @@ protected function imgSquareFit($path, $width, $height, $align = 'center', $vali

switch ($this->imgLib) {
case 'imagick':

try {
$img = new imagick($path);
} catch (Exception $e) {

return false;
}

Expand Down Expand Up @@ -2856,7 +2865,7 @@ protected function imgSquareFit($path, $width, $height, $align = 'center', $vali
if (!imagecopy($tmp, $img, $x, $y, 0, 0, $s[0], $s[1])) {
return false;
}

if ($destformat == 'jpg' || ($destformat == null && $s['mime'] == 'image/jpeg')) {
$result = imagejpeg($tmp, $path, 100);
} else if ($destformat == 'gif' || ($destformat == null && $s['mime'] == 'image/gif')) {
Expand All @@ -2869,14 +2878,80 @@ protected function imgSquareFit($path, $width, $height, $align = 'center', $vali
imagedestroy($tmp);

return $result ? $path : false;
}
break;
}

return false;
}

/**
* Rotate image
*
* @param string $path image file
* @param int $degree rotete degrees
* @param string $bgcolor square background color in #rrggbb format
* @param string $destformat image destination format
* @return string|false
* @author nao-pon
* @author Troex Nevelin
**/
protected function imgRotate($path, $degree, $bgcolor = '#ffffff', $destformat = null) {
if (($s = @getimagesize($path)) == false) {
return false;
}

$result = false;

switch ($this->imgLib) {
case 'imagick':
try {
$img = new imagick($path);
} catch (Exception $e) {
return false;
}

$img->rotateImage(new ImagickPixel($bgcolor), $degree);
$result = $img->writeImage($path);
return $result ? $path : false;

break;

case 'gd':
if ($s['mime'] == 'image/jpeg') {
$img = imagecreatefromjpeg($path);
} elseif ($s['mime'] == 'image/png') {
$img = imagecreatefrompng($path);
} elseif ($s['mime'] == 'image/gif') {
$img = imagecreatefromgif($path);
} elseif ($s['mime'] == 'image/xbm') {
$img = imagecreatefromxbm($path);
}

$degree = 360 - $degree;
list($r, $g, $b) = sscanf($bgcolor, "#%02x%02x%02x");
$bgcolor = imagecolorallocate($img, $r, $g, $b);
$tmp = imageRotate($img, $degree, (int)$bgcolor);

if ($destformat == 'jpg' || ($destformat == null && $s['mime'] == 'image/jpeg')) {
$result = imagejpeg($tmp, $path, 100);
} else if ($destformat == 'gif' || ($destformat == null && $s['mime'] == 'image/gif')) {
$result = imagegif($tmp, $path, 7);
} else {
$result = imagepng($tmp, $path, 7);
}

imageDestroy($img);
imageDestroy($tmp);

return $result ? $path : false;

break;
}

return false;
}
return false;
}

/**
* Execute shell command
*
Expand Down

0 comments on commit 54f0d03

Please sign in to comment.