Thumbnails are now being generated as part of the photo analysis routine
This commit is contained in:
parent
d559d09d55
commit
c2a65accdf
@ -16,6 +16,8 @@ interface IAlbumSource
|
|||||||
*/
|
*/
|
||||||
function getPathToPhoto(Album $album, Photo $photo);
|
function getPathToPhoto(Album $album, Photo $photo);
|
||||||
|
|
||||||
|
function saveThumbnail(Album $album, Photo $photo, $thumbnailImageResource, $thumbnailInfo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves an uploaded file to the container and returns the filename.
|
* Saves an uploaded file to the container and returns the filename.
|
||||||
* @param Album $album The album containing the photo
|
* @param Album $album The album containing the photo
|
||||||
|
@ -21,6 +21,10 @@ class LocalFilesystemSource implements IAlbumSource
|
|||||||
return sprintf('%s/%s', $this->getPathToAlbum($album), $photo->file_name);
|
return sprintf('%s/%s', $this->getPathToAlbum($album), $photo->file_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function saveThumbnail(Album $album, Photo $photo, $thumbnailImageResource, $thumbnailInfo)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public function saveUploadedPhoto(Album $album, File $uploadedFile)
|
public function saveUploadedPhoto(Album $album, File $uploadedFile)
|
||||||
{
|
{
|
||||||
$tempFilename = sprintf('%s/photo_%s', $this->getPathToAlbum($album), MiscHelper::randomString(20));
|
$tempFilename = sprintf('%s/photo_%s', $this->getPathToAlbum($album), MiscHelper::randomString(20));
|
||||||
|
@ -4,6 +4,8 @@ namespace App\Console\Commands;
|
|||||||
|
|
||||||
use App\Album;
|
use App\Album;
|
||||||
use App\AlbumSources\IAlbumSource;
|
use App\AlbumSources\IAlbumSource;
|
||||||
|
use App\Helpers\ImageHelper;
|
||||||
|
use App\Helpers\ThemeHelper;
|
||||||
use App\Photo;
|
use App\Photo;
|
||||||
use App\Upload;
|
use App\Upload;
|
||||||
use App\UploadPhoto;
|
use App\UploadPhoto;
|
||||||
@ -14,6 +16,16 @@ class ProcessUploadCommand extends Command
|
|||||||
{
|
{
|
||||||
const METADATA_VERSION = 1;
|
const METADATA_VERSION = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ImageHelper
|
||||||
|
*/
|
||||||
|
private $imageHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ThemeHelper
|
||||||
|
*/
|
||||||
|
private $themeHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name and signature of the console command.
|
* The name and signature of the console command.
|
||||||
*
|
*
|
||||||
@ -33,9 +45,12 @@ class ProcessUploadCommand extends Command
|
|||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct(ImageHelper $imageHelper, ThemeHelper $themeHelper)
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->imageHelper = $imageHelper;
|
||||||
|
$this->themeHelper = $themeHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -49,7 +64,7 @@ class ProcessUploadCommand extends Command
|
|||||||
['is_completed', false],
|
['is_completed', false],
|
||||||
['is_processing', false]
|
['is_processing', false]
|
||||||
])
|
])
|
||||||
->orderBy('created_at', 'desc')
|
->orderBy('created_at')
|
||||||
->get();
|
->get();
|
||||||
|
|
||||||
foreach ($uploadsToProcess as $upload)
|
foreach ($uploadsToProcess as $upload)
|
||||||
@ -72,7 +87,6 @@ class ProcessUploadCommand extends Command
|
|||||||
{
|
{
|
||||||
/** @var Photo $photo */
|
/** @var Photo $photo */
|
||||||
$photo = $uploadPhoto->photo;
|
$photo = $uploadPhoto->photo;
|
||||||
$this->output->writeln(sprintf('Analysing photo #%d: %s', $photo->id, $photo->name));
|
|
||||||
|
|
||||||
/** @var Album $album */
|
/** @var Album $album */
|
||||||
$album = $photo->album;
|
$album = $photo->album;
|
||||||
@ -80,8 +94,21 @@ class ProcessUploadCommand extends Command
|
|||||||
|
|
||||||
$photoFile = $albumSource->getPathToPhoto($album, $photo);
|
$photoFile = $albumSource->getPathToPhoto($album, $photo);
|
||||||
|
|
||||||
|
// Read and analyse Exif data
|
||||||
|
$this->output->writeln(sprintf('Analysing photo #%d: %s', $photo->id, $photo->name));
|
||||||
|
|
||||||
|
// Open the photo
|
||||||
|
$imageInfo = null;
|
||||||
|
$originalPhotoResource = $this->imageHelper->openImage($photoFile, $imageInfo);
|
||||||
|
$photo->width = $imageInfo[0];
|
||||||
|
$photo->height = $imageInfo[1];
|
||||||
|
$photo->mime_type = $imageInfo['mime'];
|
||||||
|
|
||||||
|
// Read the Exif data
|
||||||
$exifData = @exif_read_data($photoFile);
|
$exifData = @exif_read_data($photoFile);
|
||||||
dump($exifData);
|
|
||||||
|
// For debugging:
|
||||||
|
//dump($exifData);
|
||||||
|
|
||||||
$photo->metadata_version = ProcessUploadCommand::METADATA_VERSION;
|
$photo->metadata_version = ProcessUploadCommand::METADATA_VERSION;
|
||||||
$photo->taken_at = $this->metadataDateTime($exifData);
|
$photo->taken_at = $this->metadataDateTime($exifData);
|
||||||
@ -89,6 +116,23 @@ class ProcessUploadCommand extends Command
|
|||||||
$photo->camera_model = $this->metadataCameraModel($exifData);
|
$photo->camera_model = $this->metadataCameraModel($exifData);
|
||||||
$photo->camera_software = $this->metadataCameraSoftware($exifData);
|
$photo->camera_software = $this->metadataCameraSoftware($exifData);
|
||||||
$photo->save();
|
$photo->save();
|
||||||
|
|
||||||
|
// Generate thumbnails
|
||||||
|
$this->output->writeln('Generating thumbnails');
|
||||||
|
$themeInfo = $this->themeHelper->info();
|
||||||
|
$thumbnailsRequired = $themeInfo['thumbnails'];
|
||||||
|
|
||||||
|
foreach ($thumbnailsRequired as $thumbnail)
|
||||||
|
{
|
||||||
|
$this->imageHelper->generateThumbnail(
|
||||||
|
$originalPhotoResource,
|
||||||
|
$photo,
|
||||||
|
$albumSource,
|
||||||
|
$thumbnail
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->output->writeln(sprintf('Thumbnail \'%s\' (%dx%d) created', $thumbnail['name'], $thumbnail['width'], $thumbnail['height']));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function metadataCameraMake(array $exifData)
|
private function metadataCameraMake(array $exifData)
|
||||||
|
79
app/Helpers/ImageHelper.php
Normal file
79
app/Helpers/ImageHelper.php
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Helpers;
|
||||||
|
|
||||||
|
use App\AlbumSources\IAlbumSource;
|
||||||
|
use App\Photo;
|
||||||
|
|
||||||
|
class ImageHelper
|
||||||
|
{
|
||||||
|
public function generateThumbnail(
|
||||||
|
$gdImageResource,
|
||||||
|
Photo $photo,
|
||||||
|
IAlbumSource $storage,
|
||||||
|
$thumbnailInfo
|
||||||
|
)
|
||||||
|
{
|
||||||
|
$thumbnailWidth = intval($thumbnailInfo['width']);
|
||||||
|
$thumbnailHeight = intval($thumbnailInfo['height']);
|
||||||
|
$thumbnailImageResource = imagecreatetruecolor($thumbnailWidth, $thumbnailHeight);
|
||||||
|
|
||||||
|
imagecopyresized(
|
||||||
|
$thumbnailImageResource,
|
||||||
|
$gdImageResource,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
$thumbnailWidth,
|
||||||
|
$thumbnailHeight,
|
||||||
|
$photo->width,
|
||||||
|
$photo->height
|
||||||
|
);
|
||||||
|
$tempName = tempnam('/tmp', 'blue_twilight_thumbnail_');
|
||||||
|
rename($tempName, $tempName . '.jpg');
|
||||||
|
|
||||||
|
// TODO make thumbnail quality configurable
|
||||||
|
imagejpeg($thumbnailImageResource, $tempName . '.jpg', 90);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function openImage($imagePath, &$imageInfo)
|
||||||
|
{
|
||||||
|
$imageInfo = getimagesize($imagePath);
|
||||||
|
|
||||||
|
$im = false;
|
||||||
|
$type = $imageInfo[2];
|
||||||
|
$allowedTypes = [
|
||||||
|
IMG_GIF,
|
||||||
|
IMG_PNG,
|
||||||
|
IMG_JPEG,
|
||||||
|
IMG_WBMP
|
||||||
|
];
|
||||||
|
|
||||||
|
if (!in_array($type, $allowedTypes))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($type)
|
||||||
|
{
|
||||||
|
case IMG_GIF:
|
||||||
|
$im = imagecreatefromgif($imagePath);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IMG_JPEG:
|
||||||
|
$im = imagecreatefromjpeg($imagePath);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IMG_PNG:
|
||||||
|
$im = imagecreatefrompng($imagePath);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IMG_WBMP:
|
||||||
|
$im = imagecreatefromwbmp($imagePath);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $im;
|
||||||
|
}
|
||||||
|
}
|
@ -25,7 +25,9 @@ class Photo extends Model
|
|||||||
'taken_at',
|
'taken_at',
|
||||||
'camera_make',
|
'camera_make',
|
||||||
'camera_model',
|
'camera_model',
|
||||||
'camera_software'
|
'camera_software',
|
||||||
|
'width',
|
||||||
|
'height'
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
namespace App\Providers;
|
namespace App\Providers;
|
||||||
|
|
||||||
use App\Facade\Theme;
|
use App\Facade\Theme;
|
||||||
|
use App\Helpers\ImageHelper;
|
||||||
use App\Helpers\ThemeHelper;
|
use App\Helpers\ThemeHelper;
|
||||||
use Illuminate\Database\QueryException;
|
use Illuminate\Database\QueryException;
|
||||||
use Illuminate\Support\Facades\View;
|
use Illuminate\Support\Facades\View;
|
||||||
@ -17,6 +18,10 @@ class AppServiceProvider extends ServiceProvider
|
|||||||
*/
|
*/
|
||||||
public function boot()
|
public function boot()
|
||||||
{
|
{
|
||||||
|
$this->app->singleton('image', function($app)
|
||||||
|
{
|
||||||
|
return new ImageHelper();
|
||||||
|
});
|
||||||
$this->app->singleton('theme', function($app)
|
$this->app->singleton('theme', function($app)
|
||||||
{
|
{
|
||||||
return new ThemeHelper();
|
return new ThemeHelper();
|
||||||
|
@ -19,6 +19,8 @@ class AddPhotoMetadataColumns extends Migration
|
|||||||
$table->string('camera_make')->nullable();
|
$table->string('camera_make')->nullable();
|
||||||
$table->string('camera_model')->nullable();
|
$table->string('camera_model')->nullable();
|
||||||
$table->string('camera_software')->nullable();
|
$table->string('camera_software')->nullable();
|
||||||
|
$table->integer('width')->nullable();
|
||||||
|
$table->integer('height')->nullable();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,6 +37,8 @@ class AddPhotoMetadataColumns extends Migration
|
|||||||
$table->dropColumn('camera_make');
|
$table->dropColumn('camera_make');
|
||||||
$table->dropColumn('camera_model');
|
$table->dropColumn('camera_model');
|
||||||
$table->dropColumn('camera_software');
|
$table->dropColumn('camera_software');
|
||||||
|
$table->dropColumn('width');
|
||||||
|
$table->dropColumn('height');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,5 +3,17 @@
|
|||||||
"version": "1.0",
|
"version": "1.0",
|
||||||
"author": "Andy Heathershaw",
|
"author": "Andy Heathershaw",
|
||||||
"author_email": "andy@andys.eu",
|
"author_email": "andy@andys.eu",
|
||||||
"navbar_class": "navbar-inverse navbar-static-top"
|
"navbar_class": "navbar-inverse navbar-static-top",
|
||||||
|
"thumbnails": [
|
||||||
|
{
|
||||||
|
"name": "fullsize",
|
||||||
|
"height": 600,
|
||||||
|
"width": 800
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "preview",
|
||||||
|
"height": 300,
|
||||||
|
"width": 400
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user