Add: Crop and resize images

This commit is contained in:
philipp lang 2020-10-25 20:53:10 +01:00
parent d1c7a25b29
commit b113aa47fe
8 changed files with 202 additions and 99 deletions

1
.gitignore vendored
View File

@ -4,3 +4,4 @@
/formwidgets/responsiveimage/assets/images/
/formwidgets/responsiveimage/assets/mix-manifest.json
/formwidgets/responsiveimage/assets/node_modules/
*.swp

85
classes/CompressJob.php Normal file
View File

@ -0,0 +1,85 @@
<?php
namespace Aweos\Resizer\Classes;
use Storage;
use Aweos\Resizer\Models\Setting;
use October\Rain\Database\Attach\Resizer;
class CompressJob {
public $path;
public $filename;
public $disk;
public $strategy;
public $sizes;
public $maxFilesize = 1920;
public function fire($job, $data) {
$this->path = $data['path'];
$this->filename = $data['filename'];
$this->disk = $data['disk'];
$this->strategy = $data['strategy'];
$this->crop = $data['crop'];
$this->sizes = Setting::get('srcx');
$this->crop();
$this->createVersions();
}
public function crop() {
if ($this->crop === null) {
return;
}
$fullPath = Storage::disk($this->disk)->path($this->path.'/'.$this->filename);
Storage::disk($this->disk)->makeDirectory($this->getStrategy()->croppedPath());
$r = Resizer::open($fullPath);
$r->crop(floor($this->crop['x']), floor($this->crop['y']), floor($this->crop['w']), floor($this->crop['h']));
$this->path = $this->getStrategy()->croppedPath($this->filename);
$this->filename = $this->getStrategy()->croppedFilename($this->filename, $this->crop);
$r->save(Storage::disk($this->disk)->path($this->path.'/'.$this->filename));
}
public function createVersions()
{
$fullPath = Storage::disk($this->disk)->path($this->path.'/'.$this->filename);
[ $width, $height ] = getimagesize($fullPath);
if ($width > $this->maxFilesize) {
$r = Resizer::open($fullPath);
$r->resize($this->maxFilesize, 0);
$r->save($fullPath);
}
[ $width, $height ] = getimagesize($fullPath);
Storage::disk($this->disk)->makeDirectory($this->getStrategy()->publicPath($this->filename));
foreach ($this->sizes as $w) {
$filename = $this->getStrategy()->smallFilename($this->filename, $w);
if ($width < $w) {
continue;
}
$destination = Storage::disk($this->disk)->path($this->getStrategy()->publicPath($this->filename).'/'.$this->getStrategy()->smallFilename($this->filename, $w));
$r = Resizer::open($fullPath);
$r->resize($w, 0);
$r->save($destination);
}
}
private function getStrategy() {
return app($this->strategy);
}
}

View File

@ -0,0 +1,31 @@
<?php
namespace Aweos\Resizer\Classes;
class FirstLetterStrategy {
public function sourcePath($fileName) {
return 'source';
}
public function sourceFileBasename($uploadedFile, $data) {
return str_slug($data['title']);
}
public function publicPath($filename) {
return strtolower($filename[0]);
}
public function smallFilename($filename, $width) {
return pathinfo($filename, PATHINFO_FILENAME).'-'.$width.'.'.pathinfo($filename, PATHINFO_EXTENSION);
}
public function croppedPath() {
return 'cropped';
}
public function croppedFilename($filename, $crop) {
return $filename;
}
}

62
classes/UploadStorage.php Normal file
View File

@ -0,0 +1,62 @@
<?php
namespace Aweos\Resizer\Classes;
use Queue;
use Storage;
class UploadStorage {
public $disk = 'uploads';
public $file;
public $data;
public $strategy = FirstLetterStrategy::class;
public function storeFileFromUpload($uploadedFile, $data) {
$this->file = $uploadedFile;
$this->data = $data;
$fileName = $this->getStrategy()->sourceFileBasename($this->file, $this->data);
$sourcePath = $this->getStrategy()->sourcePath($fileName);
$fileName = $this->transformFileName($sourcePath, $fileName).'.'.$this->file->getClientOriginalExtension();
$uploadedFile->storeAs($sourcePath, $fileName, $this->disk);
Queue::push(CompressJob::class, [
'path' => $sourcePath,
'filename' => $fileName,
'disk' => $this->disk,
'strategy' => $this->strategy,
'crop' => $this->data['crop']
]);
return $fileName;
}
private function storage() {
return Storage::disk($this->disk);
}
private function transformFileName($path, $basename) {
if (count(glob($this->storage()->path($path).'/'.$basename.'*')) == 0) {
return $basename;
}
$i = 1;
while(count(glob($this->storage()->path($path).'/'.$basename.'-'.$i.'*')) != 0) {
$i++;
}
return $basename.'-'.$i;
}
private function originalExtension() {
return $this->file->getClientOriginalExtension();
}
private function getStrategy() {
return app($this->strategy);
}
}

Binary file not shown.

View File

@ -14,6 +14,7 @@ use ValidationException;
use Exception;
use Aweos\Resizer\Traits\ResponsiveSaver;
use Aweos\Resizer\Traits\ResponsiveWidget;
use Aweos\Resizer\Classes\UploadStorage;
/**
* File upload field
@ -230,24 +231,7 @@ class Responsiveimage extends FormWidgetBase
*/
public function onRemoveAttachment()
{
$fileModel = $this->getRelationModel();
if (($fileId = post('file_id')) && ($file = $fileModel::find($fileId))) {
$this->getRelationObject()->remove($file, $this->sessionKey);
}
}
/**
* Sorts file attachments.
*/
public function onSortAttachments()
{
if ($sortData = post('sortOrder')) {
$ids = array_keys($sortData);
$orders = array_values($sortData);
$fileModel = $this->getRelationModel();
$fileModel->setSortableOrder($ids, $orders);
}
//
}
/**
@ -255,20 +239,7 @@ class Responsiveimage extends FormWidgetBase
*/
public function onLoadAttachmentConfig()
{
$fileModel = $this->getRelationModel();
if ($file = $this->getFileRecord()) {
$file = $this->decorateFileAttributes($file);
$this->vars['file'] = $file;
$this->vars['displayMode'] = $this->getDisplayMode();
$this->vars['cssDimensions'] = $this->getCssDimensions();
$this->vars['relationManageId'] = post('manage_id');
$this->vars['relationField'] = post('_relation_field');
return $this->makePartial('config_form');
}
throw new ApplicationException('Unable to find file, it may no longer exist');
//
}
/**
@ -318,70 +289,20 @@ class Responsiveimage extends FormWidgetBase
*/
public function onUpload()
{
try {
if (!Input::hasFile('file_data')) {
throw new ApplicationException('File missing from request');
}
$fileModel = $this->getRelationModel();
$data = json_decode(Input::get('extraData'), true);
$uploadedFile = Input::file('file_data');
$validationRules = ['max:'.$fileModel::getMaxFilesize()];
if ($fileTypes = $this->getAcceptedFileTypes()) {
$validationRules[] = 'extensions:'.$fileTypes;
}
if ($this->mimeTypes) {
$validationRules[] = 'mimes:'.$this->mimeTypes;
}
$validation = Validator::make(
['file_data' => $uploadedFile],
['file_data' => $validationRules]
);
if ($validation->fails()) {
throw new ValidationException($validation);
}
if (!$uploadedFile->isValid()) {
throw new ApplicationException('File is not valid');
}
$fileRelation = $this->getRelationObject();
app(UploadStorage::class)->storeFileFromUpload($uploadedFile, $data);
$file = $fileModel;
$file->data = $uploadedFile;
$file->is_public = $fileRelation->isPublic();
$file->save();
/**
* Attach directly to the parent model if it exists and attachOnUpload has been set to true
* else attach via deferred binding
*/
$parent = $fileRelation->getParent();
if ($this->attachOnUpload && $parent && $parent->exists) {
$fileRelation->add($file);
}
else {
$fileRelation->add($file, $this->sessionKey);
}
$file = $this->decorateFileAttributes($file);
$result = [
'id' => $file->id,
'thumb' => $file->thumbUrl,
'path' => $file->pathUrl
];
$response = Response::make($result, 200);
}
catch (Exception $ex) {
$response = Response::make($ex->getMessage(), 400);
}
return $response;
return Response::make('', 200);
}
/**

View File

@ -9,7 +9,7 @@
<span class="upload-button-icon oc-icon-upload"></span>
</a>
<vue-dropzone @vdropzone-thumbnail="onAdd" v-if="loaded" ref="dropzone" :id="id" :options="dropzoneOptions"></vue-dropzone>
<vue-dropzone @vdropzone-sending="onSend" @vdropzone-thumbnail="onAdd" v-if="loaded" ref="dropzone" :id="id" :options="dropzoneOptions"></vue-dropzone>
<div class="preview-container" ref="previewsContainer"></div>
@ -77,6 +77,7 @@ export default {
data: function() {
return {
extraData: {},
addVisible: true,
content: {
sections: [],
@ -110,7 +111,7 @@ export default {
dropzoneOptions() {
return {
paramName: 'file_data',
autoQueue: false,
autoProcessQueue: false,
url: window.location,
clickable: this.$refs.addQueueTrigger,
previewsContainer: this.$refs.previewsContainer,
@ -147,14 +148,16 @@ export default {
this.addVisible = false;
this.showPopup(file).then((ret) => {
console.log(ret);
this.extraData[file.name] = ret;
this.$refs.dropzone.processQueue();
console.log('AAA');
}).catch((err) => {
this.$refs.dropzone.removeFile(file);
this.addVisible = true;
});
},
upload() {
onSend(file, xhr, formData) {
formData.append('extraData', JSON.stringify(this.extraData[file.name]));
}
},
mounted() {