134 lines
4 KiB
PHP
134 lines
4 KiB
PHP
<?php
|
|
namespace Szurubooru\Services;
|
|
use Szurubooru\Helpers\MimeHelper;
|
|
use Szurubooru\Helpers\ProgramExecutor;
|
|
use Szurubooru\Services\ImageManipulation\ImageManipulator;
|
|
|
|
class ImageConverter
|
|
{
|
|
const PROGRAM_NAME_DUMP_GNASH = 'dump-gnash';
|
|
const PROGRAM_NAME_SWFRENDER = 'swfrender';
|
|
const PROGRAM_NAME_FFMPEG = 'ffmpeg';
|
|
const PROGRAM_NAME_FFMPEGTHUMBNAILER = 'ffmpegthumbnailer';
|
|
|
|
private $imageManipulator;
|
|
|
|
public function __construct(ImageManipulator $imageManipulator)
|
|
{
|
|
$this->imageManipulator = $imageManipulator;
|
|
}
|
|
|
|
public function createImageFromBuffer($source)
|
|
{
|
|
$tmpSourcePath = tempnam(sys_get_temp_dir(), 'thumb') . '.dat';
|
|
$tmpTargetPath = tempnam(sys_get_temp_dir(), 'thumb') . '.png';
|
|
try
|
|
{
|
|
file_put_contents($tmpSourcePath, $source);
|
|
$this->convert($tmpSourcePath, $tmpTargetPath);
|
|
|
|
$tmpSource = file_get_contents($tmpTargetPath);
|
|
return $this->imageManipulator->loadFromBuffer($tmpSource);
|
|
}
|
|
finally
|
|
{
|
|
$this->deleteIfExists($tmpSourcePath);
|
|
$this->deleteIfExists($tmpTargetPath);
|
|
}
|
|
}
|
|
|
|
public function convert($sourcePath, $targetPath)
|
|
{
|
|
$mime = MimeHelper::getMimeTypeFromFile($sourcePath);
|
|
|
|
if (MimeHelper::isImage($mime))
|
|
copy($sourcePath, $targetPath);
|
|
|
|
elseif (MimeHelper::isFlash($mime))
|
|
$this->convertFromFlash($sourcePath, $targetPath);
|
|
|
|
elseif (MimeHelper::isVideo($mime))
|
|
$this->convertFromVideo($sourcePath, $targetPath);
|
|
|
|
else
|
|
throw new \Exception('Error while converting file to image - unrecognized MIME: ' . $mime);
|
|
}
|
|
|
|
private function convertFromFlash($sourcePath, $targetPath)
|
|
{
|
|
if (ProgramExecutor::isProgramAvailable(self::PROGRAM_NAME_DUMP_GNASH))
|
|
{
|
|
ProgramExecutor::run(
|
|
self::PROGRAM_NAME_DUMP_GNASH,
|
|
[
|
|
'--screenshot', 'last',
|
|
'--screenshot-file', $targetPath,
|
|
'-1',
|
|
'-r1',
|
|
'--max-advances', '15',
|
|
$sourcePath,
|
|
]);
|
|
}
|
|
|
|
if (!file_exists($targetPath) && ProgramExecutor::isProgramAvailable(self::PROGRAM_NAME_SWFRENDER))
|
|
{
|
|
ProgramExecutor::run(
|
|
self::PROGRAM_NAME_SWFRENDER,
|
|
[
|
|
'swfrender',
|
|
$sourcePath,
|
|
'-o',
|
|
$targetPath,
|
|
]);
|
|
}
|
|
|
|
if (!file_exists($targetPath) && ProgramExecutor::isProgramAvailable(self::PROGRAM_NAME_FFMPEG))
|
|
{
|
|
ProgramExecutor::run(
|
|
self::PROGRAM_NAME_FFMPEG,
|
|
[
|
|
'-i',
|
|
$sourcePath,
|
|
'-vframes', '1',
|
|
$targetPath,
|
|
]);
|
|
}
|
|
|
|
if (!file_exists($targetPath))
|
|
throw new \Exception('Error while converting Flash file to image');
|
|
}
|
|
|
|
private function convertFromVideo($sourcePath, $targetPath)
|
|
{
|
|
if (ProgramExecutor::isProgramAvailable(self::PROGRAM_NAME_FFMPEGTHUMBNAILER))
|
|
{
|
|
ProgramExecutor::run(
|
|
self::PROGRAM_NAME_FFMPEGTHUMBNAILER,
|
|
[
|
|
'-i' . $sourcePath,
|
|
'-o' . $targetPath,
|
|
'-s0',
|
|
'-t12%%'
|
|
]);
|
|
}
|
|
|
|
if (!file_exists($targetPath) && ProgramExecutor::isProgramAvailable(self::PROGRAM_NAME_FFMPEG))
|
|
{
|
|
ProgramExecutor::run(self::PROGRAM_NAME_FFMPEG,
|
|
[
|
|
'-i', $sourcePath,
|
|
'-vframes', '1',
|
|
$targetPath
|
|
]);
|
|
}
|
|
|
|
if (!file_exists($targetPath))
|
|
throw new \Exception('Error while converting video file to image');
|
|
}
|
|
|
|
private function deleteIfExists($path)
|
|
{
|
|
if (file_exists($path))
|
|
unlink($path);
|
|
}
|
|
}
|