This repository has been archived on 2025-02-26. You can view files and clone it, but cannot push or open issues or pull requests.
szurubooru/src/Services/ImageConverter.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);
}
}