Add: Crop and resize images
This commit is contained in:
parent
d1c7a25b29
commit
b113aa47fe
|
@ -4,3 +4,4 @@
|
||||||
/formwidgets/responsiveimage/assets/images/
|
/formwidgets/responsiveimage/assets/images/
|
||||||
/formwidgets/responsiveimage/assets/mix-manifest.json
|
/formwidgets/responsiveimage/assets/mix-manifest.json
|
||||||
/formwidgets/responsiveimage/assets/node_modules/
|
/formwidgets/responsiveimage/assets/node_modules/
|
||||||
|
*.swp
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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.
|
@ -14,6 +14,7 @@ use ValidationException;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Aweos\Resizer\Traits\ResponsiveSaver;
|
use Aweos\Resizer\Traits\ResponsiveSaver;
|
||||||
use Aweos\Resizer\Traits\ResponsiveWidget;
|
use Aweos\Resizer\Traits\ResponsiveWidget;
|
||||||
|
use Aweos\Resizer\Classes\UploadStorage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* File upload field
|
* File upload field
|
||||||
|
@ -230,24 +231,7 @@ class Responsiveimage extends FormWidgetBase
|
||||||
*/
|
*/
|
||||||
public function onRemoveAttachment()
|
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()
|
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()
|
public function onUpload()
|
||||||
{
|
{
|
||||||
try {
|
|
||||||
if (!Input::hasFile('file_data')) {
|
if (!Input::hasFile('file_data')) {
|
||||||
throw new ApplicationException('File missing from request');
|
throw new ApplicationException('File missing from request');
|
||||||
}
|
}
|
||||||
|
|
||||||
$fileModel = $this->getRelationModel();
|
$data = json_decode(Input::get('extraData'), true);
|
||||||
$uploadedFile = Input::file('file_data');
|
$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()) {
|
if (!$uploadedFile->isValid()) {
|
||||||
throw new ApplicationException('File is not valid');
|
throw new ApplicationException('File is not valid');
|
||||||
}
|
}
|
||||||
|
|
||||||
$fileRelation = $this->getRelationObject();
|
app(UploadStorage::class)->storeFileFromUpload($uploadedFile, $data);
|
||||||
|
|
||||||
$file = $fileModel;
|
return Response::make('', 200);
|
||||||
$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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
<span class="upload-button-icon oc-icon-upload"></span>
|
<span class="upload-button-icon oc-icon-upload"></span>
|
||||||
</a>
|
</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>
|
<div class="preview-container" ref="previewsContainer"></div>
|
||||||
|
|
||||||
|
@ -77,6 +77,7 @@ export default {
|
||||||
|
|
||||||
data: function() {
|
data: function() {
|
||||||
return {
|
return {
|
||||||
|
extraData: {},
|
||||||
addVisible: true,
|
addVisible: true,
|
||||||
content: {
|
content: {
|
||||||
sections: [],
|
sections: [],
|
||||||
|
@ -110,7 +111,7 @@ export default {
|
||||||
dropzoneOptions() {
|
dropzoneOptions() {
|
||||||
return {
|
return {
|
||||||
paramName: 'file_data',
|
paramName: 'file_data',
|
||||||
autoQueue: false,
|
autoProcessQueue: false,
|
||||||
url: window.location,
|
url: window.location,
|
||||||
clickable: this.$refs.addQueueTrigger,
|
clickable: this.$refs.addQueueTrigger,
|
||||||
previewsContainer: this.$refs.previewsContainer,
|
previewsContainer: this.$refs.previewsContainer,
|
||||||
|
@ -147,14 +148,16 @@ export default {
|
||||||
this.addVisible = false;
|
this.addVisible = false;
|
||||||
|
|
||||||
this.showPopup(file).then((ret) => {
|
this.showPopup(file).then((ret) => {
|
||||||
console.log(ret);
|
this.extraData[file.name] = ret;
|
||||||
|
this.$refs.dropzone.processQueue();
|
||||||
|
console.log('AAA');
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
this.$refs.dropzone.removeFile(file);
|
this.$refs.dropzone.removeFile(file);
|
||||||
this.addVisible = true;
|
this.addVisible = true;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
upload() {
|
onSend(file, xhr, formData) {
|
||||||
|
formData.append('extraData', JSON.stringify(this.extraData[file.name]));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|
Binary file not shown.
Loading…
Reference in New Issue