Skip to content

Commit

Permalink
Implemented image cropping
Browse files Browse the repository at this point in the history
  • Loading branch information
malamalca committed Jan 28, 2019
1 parent 2fe53d7 commit 9df7be9
Show file tree
Hide file tree
Showing 7 changed files with 191 additions and 33 deletions.
29 changes: 28 additions & 1 deletion src/Controller/AttachmentsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class AttachmentsController extends AppController
*/
public function isAuthorized($user)
{
if (in_array($this->getRequest()->getParam('action'), ['edit', 'delete', 'add'])) {
if (in_array($this->getRequest()->getParam('action'), ['edit', 'delete', 'add', 'crop'])) {
return $this->currentUser->get('lvl') <= constant('LVL_EDITOR');
}

Expand Down Expand Up @@ -112,6 +112,33 @@ public function view($id = null)
$this->set('attachment', $attachment);
}

/**
* Crop method
*
* @param string|null $id Attachment id.
* @return \Cake\Http\Response|void
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
*/
public function crop($id = null)
{
$this->getRequest()->allowMethod(['post']);
$attachment = $this->Attachments->get($this->getRequest()->getData('attachment_id'));

if ($this->Attachments->crop(
$attachment,
(int)$this->getRequest()->getData('x'),
(int)$this->getRequest()->getData('y'),
(int)$this->getRequest()->getData('width'),
(int)$this->getRequest()->getData('height')
)) {
$this->Flash->success(__('The attachment has been cropped.'));
} else {
$this->Flash->error(__('The attachment could not be cropped. Please, try again.'));
}

return $this->redirect(base64_decode($this->getRequest()->getData('referer')));
}

/**
* Add method
*
Expand Down
64 changes: 62 additions & 2 deletions src/Model/Table/AttachmentsTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,8 @@ public function processUpload($entity, $tmpFilename, $method = 'uploaded')

$moveResult = ($method == 'uploaded') ? move_uploaded_file($tmpFilename, $dir->path . DS . 'original') : rename($tmpFilename, $dir->path . DS . 'original');
if ($moveResult) {
$image->resize(640, 480, 'inside')->saveToFile($dir->path . DS . 'large', $entity->ext);
$this->processOriginalImage($image, $entity->ext, $entity->id);
/*$image->resize(640, 480, 'inside')->saveToFile($dir->path . DS . 'large', $entity->ext);
$image->resize(200, 200, 'inside')->saveToFile($dir->path . DS . 'medium', $entity->ext);
$thumb = $image->resize(75, 75, 'outside');
Expand All @@ -241,13 +242,72 @@ public function processUpload($entity, $tmpFilename, $method = 'uploaded')
} elseif ($thumb->getWidth() < $thumb->getHeight()) {
$thumb = $thumb->crop(0, floor(($thumb->getHeight() - 75) / 2), 75, 75);
}
$thumb->saveToFile(Configure::read('sourceFolders.thumbs') . $entity->id . '.png', null, 9);
$thumb->saveToFile(Configure::read('sourceFolders.thumbs') . $entity->id . '.png', null, 9);*/
}
unset($image);
}
}
}

/**
* Create large+medium images and thumbnail
*
* @param \WideImage\Image $original Original image.
* @param string $ext Image extension
* @param string $id Attachment id
* @return void
*/
public function processOriginalImage($original, $ext, $id)
{
$dir = new Folder(Configure::read('sourceFolders.attachments') . $id, true);

$original->resize(640, 480, 'inside')->saveToFile($dir->path . DS . 'large', $ext);
$original->resize(200, 200, 'inside')->saveToFile($dir->path . DS . 'medium', $ext);

$thumb = $original->resize(75, 75, 'outside');
if ($thumb->getWidth() > $thumb->getHeight()) {
$thumb = $thumb->crop(floor(($thumb->getWidth() - 75) / 2), 0, 75, 75);
} elseif ($thumb->getWidth() < $thumb->getHeight()) {
$thumb = $thumb->crop(0, floor(($thumb->getHeight() - 75) / 2), 75, 75);
}
$thumb->saveToFile(Configure::read('sourceFolders.thumbs') . $id . '.png', null, 9);
}

/**
* Crop attachment
*
* @param \App\Model\Entity\Attachment $attachment Attachment entity.
* @param int $cropX X position.
* @param int $cropY Y position.
* @param int $cropW Width.
* @param int $cropH Height.
* @return bool
*/
public function crop($attachment, $cropX, $cropY, $cropW, $cropH)
{
$filenameOriginal = Configure::read('sourceFolders.attachments') . DS . $attachment->id . DS . 'original';
if (file_exists($filenameOriginal)) {
$largeSize = $this->getImageSize($attachment->id, 'large');
$originalSize = $this->getImageSize($attachment->id, 'original');

$scaleFactor = $originalSize['width'] / $largeSize['width'];
$x = (int)round($cropX * $scaleFactor);
$y = (int)round($cropY * $scaleFactor);
$width = (int)round($cropW * $scaleFactor);
$height = (int)round($cropH * $scaleFactor);

$image = WideImage::loadFromFile($filenameOriginal, $attachment->ext);
$image = $image->crop($x, $y, $width, $height);
$image->saveToFile($filenameOriginal, $attachment->ext);

$this->processOriginalImage($image, $attachment->ext, $attachment->id);

return true;
}

return false;
}

/**
* Extract image area from specified attachment and create new image
*
Expand Down
70 changes: 68 additions & 2 deletions src/Template/Attachments/view.ctp
Original file line number Diff line number Diff line change
Expand Up @@ -118,16 +118,42 @@ if (!empty($attachment->description)) {
echo ' ' . __('or') . ' <span class="link" id="CancelNoteLink">' . __('Cancel') . '</span>';
echo '</div>';
echo $this->Form->end();
?>
</div>
<div id="CropForm" class="form">
<?php
echo $this->Form->Create(null, ['url' => ['controller' => 'Attachments', 'action' => 'crop']]);
echo '<fieldset>';
echo '<legend>' . __('Crop') . '</legend>';
echo $this->Form->hidden('attachment_id', ['type' => 'hidden', 'value' => $attachment->id]);
echo $this->Form->hidden('user_id', ['type' => 'hidden', 'value' => $this->currentUser->get('id')]);
echo $this->Form->hidden('referer', ['type' => 'hidden', 'value' => base64_encode($this->Url->build(null, true))]);
echo $this->Form->hidden('x', ['type' => 'hidden', 'id' => 'CropX1']);
echo $this->Form->hidden('y', ['type' => 'hidden', 'id' => 'CropY1']);
echo $this->Form->hidden('width', ['type' => 'hidden', 'id' => 'CropWidth']);
echo $this->Form->hidden('height', ['type' => 'hidden', 'id' => 'CropHeight']);

$this->Form->unlockField('x');
$this->Form->unlockField('y');
$this->Form->unlockField('width');
$this->Form->unlockField('height');

echo $this->Form->button(__('Save'), ['type' => 'submit']);
echo ' ' . __('or') . ' <span class="link" id="CancelCropLink">' . __('Cancel') . '</span>';
echo $this->Form->end();
?>
</div>

<?php
echo $this->Html->script('jquery.imgareaselect-0.8.min');
echo $this->Html->script('jquery.imgnotes-0.2');

echo $this->Html->script('ui.core');
echo $this->Html->script('ui.autocomplete');
echo $this->Html->css('imgnotes');
echo $this->Html->css('ui.all');
?>
</div>
?>

<script type="text/javascript">
<?php
echo 'var notes = [';
Expand Down Expand Up @@ -176,6 +202,11 @@ if (!empty($attachment->description)) {
$('#NoteForm').hide();
});

$('#CancelCropLink').click(function() {
$('#AttachmentImage').imgAreaSelect({ hide: true });
$('#CropForm').hide();
});

$('#AddNoteLink').click(function() {
<?php
$large_sizes = $attachment->getImageSize('large');
Expand All @@ -197,6 +228,27 @@ if (!empty($attachment->description)) {
return false;
});

$('#CropLink').click(function() {
<?php
$large_sizes = $attachment->getImageSize('large');
// do a 10% frame from middle
$w = round($large_sizes['width'] * .3);
$x1 = round($large_sizes['width'] / 2 - $w / 2);
$x2 = $x1 + $w;
$h = round($large_sizes['height'] * .3);
$y1 = round($large_sizes['height'] / 2 - $h / 2);
$y2 = $y1 + $h;

printf('var frame = {onSelectChange: ShowCropFrame, handles: true, x1:%1$s, x2:%2$s, y1:%3$s, y2:%4$s, width:%5$s, height:%6$s};', $x1, $x2, $y1, $y2, $w, $h).PHP_EOL;
?>
ShowCropFrame('#AttachmentImage', frame);

$('#CropForm').show();
$('#AttachmentImage').imgAreaSelect(frame);

return false;
});

$('#AddAttachmentsLink').click(function(e) {
$('#AttachmentsLinkForm').css('display', 'inline');
$('#AddAttachmentsLink').hide();
Expand Down Expand Up @@ -243,7 +295,21 @@ if (!empty($attachment->description)) {
$('#ImgnoteY1').val(area.y1);
$('#ImgnoteHeight').val(area.height);
$('#ImgnoteWidth').val(area.width);
}

function ShowCropFrame(img, area) {
imgOffset = $(img).position();
form_left = parseInt(imgOffset.left) + parseInt(area.x1);
form_top = parseInt(imgOffset.top) + parseInt(area.y1) + parseInt(area.height)+5;

$('#CropForm').css({ left: form_left + 'px', top: form_top + 'px'});
$('#CropForm').show();

$('#CropForm').css("z-index", 10000);
$('#CropX1').val(area.x1);
$('#CropY1').val(area.y1);
$('#CropHeight').val(area.height);
$('#CropWidth').val(area.width);
}


Expand Down
34 changes: 16 additions & 18 deletions src/Template/Element/Sidebar/Attachments/view.ctp
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,23 @@ if ($this->currentUser->exists() && $this->currentUser->get('lvl') <= LVL_EDITOR
<h1><?= __('Operations') ?></h1>
<ul>
<li>
<?php
echo $this->Html->image('ico_avatar.gif', ['class' => 'icon']);
echo $this->Html->link(
__('Point a Person'),
[
'controller' => 'Attachments',
'action' => 'addNote',
$attachment->id
],
[
'id' => 'AddNoteLink'
]
);
?>
<?php
echo $this->Html->image('ico_avatar.gif', ['class' => 'icon']);
echo $this->Html->link(__('Point a Person'), ['action' => 'addNote', $attachment->id], [ 'id' => 'AddNoteLink']);
?>
</li>
<li>
<?php
echo $this->Html->image('ico_profile_edit.gif', ['class' => 'icon']);
echo $this->Famiree->link(__('[Edit] properties'), ['action' => 'edit', $attachment->id]);
?>
</li>
<li>
<?php
echo $this->Html->image('ico_crop.gif', ['class' => 'icon']);
echo $this->Famiree->link(__('[Crop] attachment'), ['action' => 'crop', $attachment->id], [ 'id' => 'CropLink']);
?>
</li>
<li><?php
echo $this->Html->image('ico_profile_edit.gif', ['class' => 'icon']);
echo $this->Famiree->link(__('[Edit] properties'), ['controller' => 'Attachments', 'action' => 'edit', $attachment->id]);
?></li>
</ul>
<div>&nbsp;</div>
<?php
Expand Down
25 changes: 17 additions & 8 deletions webroot/css/imgnotes.css
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
.note {
display: none;
background: url(spacer.gif);
border: 2px solid rgb(255, 255, 255);
overflow: hidden;
position: absolute;
background: url(spacer.gif);
border: 2px solid rgb(255, 255, 255);
overflow: hidden;
position: absolute;
z-index: 0;
cursor: text;
}
Expand All @@ -13,11 +13,11 @@
}

.notep {
display: none;
background: #eee;
display: none;
background: #eee;
font-family: Tahoma, helvetica, sans-serif;
font-size: 8pt;
margin-top: 0px;
font-size: 8pt;
margin-top: 0px;
padding: 2px;
position: absolute;
width: 175px;
Expand All @@ -37,3 +37,12 @@
#NoteForm textarea{
width: 100%;
}

#CropForm {
display: none;
position: absolute;
width: 150px;
padding: 10px;
background-color:#f8f8f8;
border: solid 4px #a0a0a0;
}
Binary file added webroot/img/ico_crop.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 0 additions & 2 deletions webroot/js/jquery.imgnotes-0.2.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@
$.extend(options, o);
}

console.log(options);

if(typeof options.notes != "undefined"){
notes = options.notes;
}
Expand Down

0 comments on commit 9df7be9

Please sign in to comment.