diff --git a/core/imageboard/misc.php b/core/imageboard/misc.php
index 88b36d7a..7d588955 100644
--- a/core/imageboard/misc.php
+++ b/core/imageboard/misc.php
@@ -73,6 +73,12 @@ function get_thumbnail_size(int $orig_width, int $orig_height, bool $use_dpi_sca
{
global $config;
+ $fit = $config->get_string(ImageConfig::THUMB_FIT);
+
+ if (in_array($fit, [Media::RESIZE_TYPE_FILL, Media::RESIZE_TYPE_STRETCH, Media::RESIZE_TYPE_FIT_BLUR])) {
+ return [$config->get_int(ImageConfig::THUMB_WIDTH), $config->get_int(ImageConfig::THUMB_HEIGHT)];
+ }
+
if ($orig_width === 0) {
$orig_width = 192;
}
@@ -132,18 +138,32 @@ function get_thumbnail_max_size_scaled(): array
function create_image_thumb(string $hash, string $type, string $engine = null)
{
+ global $config;
+
$inname = warehouse_path(Image::IMAGE_DIR, $hash);
$outname = warehouse_path(Image::THUMBNAIL_DIR, $hash);
$tsize = get_thumbnail_max_size_scaled();
- create_scaled_image($inname, $outname, $tsize, $type, $engine);
+ create_scaled_image(
+ $inname,
+ $outname,
+ $tsize,
+ $type,
+ $engine,
+ $config->get_string(ImageConfig::THUMB_FIT)
+ );
}
-function create_scaled_image(string $inname, string $outname, array $tsize, string $type, ?string $engine)
+
+
+function create_scaled_image(string $inname, string $outname, array $tsize, string $type, ?string $engine = null, ?string $resize_type = null)
{
global $config;
if (empty($engine)) {
$engine = $config->get_string(ImageConfig::THUMB_ENGINE);
}
+ if (empty($resize_type)) {
+ $resize_type = $config->get_string(ImageConfig::THUMB_FIT);
+ }
$output_format = $config->get_string(ImageConfig::THUMB_TYPE);
if ($output_format==EXTENSION_WEBP) {
@@ -157,10 +177,10 @@ function create_scaled_image(string $inname, string $outname, array $tsize, stri
$outname,
$tsize[0],
$tsize[1],
- false,
+ $resize_type,
$output_format,
$config->get_int(ImageConfig::THUMB_QUALITY),
true,
- $config->get_bool('thumb_upscale', false)
+ true
));
}
diff --git a/ext/image/config.php b/ext/image/config.php
index b54452fe..2b078113 100644
--- a/ext/image/config.php
+++ b/ext/image/config.php
@@ -8,6 +8,7 @@ abstract class ImageConfig
const THUMB_SCALING = 'thumb_scaling';
const THUMB_QUALITY = 'thumb_quality';
const THUMB_TYPE = 'thumb_type';
+ const THUMB_FIT = 'thumb_fit';
const SHOW_META = 'image_show_meta';
const ILINK = 'image_ilink';
diff --git a/ext/image/main.php b/ext/image/main.php
index 2d873ec2..bba0e551 100644
--- a/ext/image/main.php
+++ b/ext/image/main.php
@@ -33,6 +33,7 @@ class ImageIO extends Extension
$config->set_default_int(ImageConfig::THUMB_SCALING, 100);
$config->set_default_int(ImageConfig::THUMB_QUALITY, 75);
$config->set_default_string(ImageConfig::THUMB_TYPE, EXTENSION_JPG);
+ $config->set_default_string(ImageConfig::THUMB_FIT, Media::RESIZE_TYPE_FIT);
if (function_exists(self::EXIF_READ_FUNCTION)) {
$config->set_default_bool(ImageConfig::SHOW_META, false);
@@ -215,35 +216,41 @@ class ImageIO extends Extension
public function onSetupBuilding(SetupBuildingEvent $event)
{
+ global $config;
+
$sb = new SetupBlock("Image Options");
+ $sb->start_table();
$sb->position = 30;
// advanced only
//$sb->add_text_option(ImageConfig::ILINK, "Image link: ");
//$sb->add_text_option(ImageConfig::TLINK, "
Thumbnail link: ");
- $sb->add_text_option(ImageConfig::TIP, "Image tooltip: ");
- $sb->add_choice_option(ImageConfig::UPLOAD_COLLISION_HANDLER, self::COLLISION_OPTIONS, "
Upload collision handler: ");
+ $sb->add_text_option(ImageConfig::TIP, "Image tooltip", true);
+ $sb->add_choice_option(ImageConfig::UPLOAD_COLLISION_HANDLER, self::COLLISION_OPTIONS, "Upload collision handler", true);
if (function_exists(self::EXIF_READ_FUNCTION)) {
- $sb->add_bool_option(ImageConfig::SHOW_META, "
Show metadata: ");
+ $sb->add_bool_option(ImageConfig::SHOW_META, "Show metadata", true);
}
-
+ $sb->end_table();
$event->panel->add_block($sb);
$sb = new SetupBlock("Thumbnailing");
- $sb->add_choice_option(ImageConfig::THUMB_ENGINE, self::THUMBNAIL_ENGINES, "Engine: ");
- $sb->add_label("
");
- $sb->add_choice_option(ImageConfig::THUMB_TYPE, self::THUMBNAIL_TYPES, "Filetype: ");
+ $sb->start_table();
+ $sb->add_choice_option(ImageConfig::THUMB_ENGINE, self::THUMBNAIL_ENGINES, "Engine", true);
+ $sb->add_choice_option(ImageConfig::THUMB_TYPE, self::THUMBNAIL_TYPES, "Filetype", true);
- $sb->add_label("
Size ");
- $sb->add_int_option(ImageConfig::THUMB_WIDTH);
- $sb->add_label(" x ");
- $sb->add_int_option(ImageConfig::THUMB_HEIGHT);
- $sb->add_label(" px at ");
- $sb->add_int_option(ImageConfig::THUMB_QUALITY);
- $sb->add_label(" % quality ");
+ $sb->add_int_option(ImageConfig::THUMB_WIDTH, "Max Width", true);
+ $sb->add_int_option(ImageConfig::THUMB_HEIGHT, "Max Height", true);
- $sb->add_label("
High-DPI scaling ");
- $sb->add_int_option(ImageConfig::THUMB_SCALING);
- $sb->add_label("%");
+ $options = [];
+ foreach (MediaEngine::RESIZE_TYPE_SUPPORT[$config->get_string(ImageConfig::THUMB_ENGINE)] as $type) {
+ $options[$type] = $type;
+ }
+
+ $sb->add_choice_option(ImageConfig::THUMB_FIT, $options, "Fit", true);
+
+ $sb->add_int_option(ImageConfig::THUMB_QUALITY, "Quality", true);
+ $sb->add_int_option(ImageConfig::THUMB_SCALING, "High-DPI Scale %", true);
+
+ $sb->end_table();
$event->panel->add_block($sb);
}
diff --git a/ext/media/events.php b/ext/media/events.php
index b8cd984a..ffa69a49 100644
--- a/ext/media/events.php
+++ b/ext/media/events.php
@@ -11,8 +11,8 @@ class MediaResizeEvent extends Event
public $target_height;
public $target_quality;
public $minimize;
- public $ignore_aspect_ratio;
public $allow_upscale;
+ public $resize_type;
public function __construct(
String $engine,
@@ -21,7 +21,7 @@ class MediaResizeEvent extends Event
string $output_path,
int $target_width,
int $target_height,
- bool $ignore_aspect_ratio = false,
+ string $resize_type = Media::RESIZE_TYPE_FIT,
string $target_format = null,
int $target_quality = 80,
bool $minimize = false,
@@ -38,8 +38,8 @@ class MediaResizeEvent extends Event
$this->target_format = $target_format;
$this->target_quality = $target_quality;
$this->minimize = $minimize;
- $this->ignore_aspect_ratio = $ignore_aspect_ratio;
$this->allow_upscale = $allow_upscale;
+ $this->resize_type = $resize_type;
}
}
diff --git a/ext/media/main.php b/ext/media/main.php
index 814af2da..50d548ad 100644
--- a/ext/media/main.php
+++ b/ext/media/main.php
@@ -48,6 +48,10 @@ class Media extends Extension
EXTENSION_JPEG => EXTENSION_JPG,
];
+ const RESIZE_TYPE_FIT = "Fit";
+ const RESIZE_TYPE_FIT_BLUR = "Fit Blur";
+ const RESIZE_TYPE_FILL = "Fill";
+ const RESIZE_TYPE_STRETCH = "Stretch";
//RIFF####WEBPVP8?..............ANIM
private const WEBP_ANIMATION_HEADER =
@@ -206,6 +210,10 @@ class Media extends Extension
*/
public function onMediaResize(MediaResizeEvent $event)
{
+ if (!in_array($event->resize_type, MediaEngine::RESIZE_TYPE_SUPPORT[MediaEngine::IMAGICK])) {
+ throw new MediaException("Resize type $event->resize_type not supported by selected media engine $event->engine");
+ }
+
switch ($event->engine) {
case MediaEngine::GD:
$info = getimagesize($event->input_path);
@@ -220,7 +228,7 @@ class Media extends Extension
$event->target_height,
$event->output_path,
$event->target_format,
- $event->ignore_aspect_ratio,
+ $event->resize_type,
$event->target_quality,
$event->allow_upscale
);
@@ -236,7 +244,7 @@ class Media extends Extension
$event->target_height,
$event->output_path,
$event->target_format,
- $event->ignore_aspect_ratio,
+ $event->resize_type,
$event->target_quality,
$event->minimize,
$event->allow_upscale
@@ -356,6 +364,7 @@ class Media extends Extension
}
$inname = warehouse_path(Image::IMAGE_DIR, $hash);
+ $tmpname = tempnam("/tmp", "shimmie_ffmpeg_thumb");
$outname = warehouse_path(Image::THUMBNAIL_DIR, $hash);
$orig_size = self::video_size($inname);
@@ -376,12 +385,11 @@ class Media extends Extension
$args = [
escapeshellarg($ffmpeg),
"-y", "-i", escapeshellarg($inname),
- "-vf", "thumbnail,scale={$scaled_size[0]}:{$scaled_size[1]}",
+ "-vf", "thumbnail",
"-f", "image2",
"-vframes", "1",
- "-c:v", $codec,
- "-q:v", $quality,
- escapeshellarg($outname),
+ "-c:v", "png",
+ escapeshellarg($tmpname),
];
$cmd = escapeshellcmd(implode(" ", $args));
@@ -390,6 +398,10 @@ class Media extends Extension
if ((int)$ret == (int)0) {
log_debug('media', "Generating thumbnail with command `$cmd`, returns $ret");
+
+ create_scaled_image($tmpname, $outname, $scaled_size, "png");
+
+
return true;
} else {
log_error('media', "Generating thumbnail with command `$cmd`, returns $ret");
@@ -569,7 +581,7 @@ class Media extends Extension
int $new_height,
string $output_filename,
string $output_type = null,
- bool $ignore_aspect_ratio = false,
+ string $resize_type = self::RESIZE_TYPE_FIT,
int $output_quality = 80,
bool $minimize = false,
bool $allow_upscale = true
@@ -598,16 +610,41 @@ class Media extends Extension
$input_type = $input_type . ":";
}
-
- $resize_args = "";
+ $resize_suffix = "";
if (!$allow_upscale) {
- $resize_args .= "\>";
+ $resize_suffix .= "\>";
}
- if ($ignore_aspect_ratio) {
- $resize_args .= "\!";
+ if ($resize_type==Media::RESIZE_TYPE_STRETCH) {
+ $resize_suffix .= "\!";
}
$args = "";
+ $resize_arg = "-resize";
+ if ($minimize) {
+ $args .= "-strip ";
+ $resize_arg = "-thumbnail";
+ }
+
+ $file_arg = "${input_type}\"${input_path}[0]\"";
+
+ switch ($resize_type) {
+ case Media::RESIZE_TYPE_FIT:
+ case Media::RESIZE_TYPE_STRETCH:
+ $args .= "${resize_arg} ${new_width}x${new_height}${resize_suffix} ${file_arg}";
+ break;
+ case Media::RESIZE_TYPE_FILL:
+ $args .= "${resize_arg} ${new_width}x${new_height}\^ -gravity center -extent ${new_width}x${new_height} ${file_arg}";
+ break;
+ case Media::RESIZE_TYPE_FIT_BLUR:
+ $blur_size = max(ceil(max($new_width, $new_height) / 25), 5);
+ $args .= "${file_arg} ".
+ "\( -clone 0 -resize ${new_width}x${new_height}\^ -gravity center -fill black -colorize 50% -extent ${new_width}x${new_height} -blur 0x${blur_size} \) ".
+ "\( -clone 0 -resize ${new_width}x${new_height} \) ".
+ "-delete 0 -gravity center -compose over -composite";
+ break;
+ }
+
+
switch ($output_type) {
case Media::WEBP_LOSSLESS:
$args .= '-define webp:lossless=true';
@@ -617,17 +654,14 @@ class Media extends Extension
break;
}
- if ($minimize) {
- $args .= " -strip -thumbnail";
- } else {
- $args .= " -resize";
- }
+
+ $args .= " -quality ${output_quality} -background ${bg}";
$output_ext = self::determine_ext($output_type);
- $format = '"%s" %s %ux%u%s -quality %u -background %s %s"%s[0]" %s:"%s" 2>&1';
- $cmd = sprintf($format, $convert, $args, $new_width, $new_height, $resize_args, $output_quality, $bg, $input_type, $input_path, $output_ext, $output_filename);
+ $format = '"%s" %s %s:"%s" 2>&1';
+ $cmd = sprintf($format, $convert, $args, $output_ext, $output_filename);
$cmd = str_replace("\"convert\"", "convert", $cmd); // quotes are only needed if the path to convert contains a space; some other times, quotes break things, see github bug #27
exec($cmd, $output, $ret);
if ($ret != 0) {
@@ -657,7 +691,7 @@ class Media extends Extension
int $new_height,
string $output_filename,
string $output_type = null,
- bool $ignore_aspect_ratio = false,
+ string $resize_type = self::RESIZE_TYPE_FIT,
int $output_quality = 80,
bool $allow_upscale = true
) {
@@ -693,7 +727,7 @@ class Media extends Extension
throw new InsufficientMemoryException("The image is too large to resize given the memory limits. ($memory_use > $memory_limit)");
}
- if (!$ignore_aspect_ratio) {
+ if ($resize_type==Media::RESIZE_TYPE_FIT) {
list($new_width, $new_height) = get_scaled_by_aspect_ratio($width, $height, $new_width, $new_height);
}
if (!$allow_upscale &&
diff --git a/ext/media/media_engine.php b/ext/media/media_engine.php
index 43dc74f4..3a43b14d 100644
--- a/ext/media/media_engine.php
+++ b/ext/media/media_engine.php
@@ -74,4 +74,19 @@ abstract class MediaEngine
EXTENSION_PNG,
],
];
+ public const RESIZE_TYPE_SUPPORT = [
+ MediaEngine::GD => [
+ Media::RESIZE_TYPE_FIT,
+ Media::RESIZE_TYPE_STRETCH
+ ],
+ MediaEngine::IMAGICK => [
+ Media::RESIZE_TYPE_FIT,
+ Media::RESIZE_TYPE_FIT_BLUR,
+ Media::RESIZE_TYPE_FILL,
+ Media::RESIZE_TYPE_STRETCH,
+ ],
+ MediaEngine::FFMPEG => [
+ Media::RESIZE_TYPE_FIT
+ ]
+ ];
}
diff --git a/ext/transcode/main.php b/ext/transcode/main.php
index 27c1eb8c..42f7b8c3 100644
--- a/ext/transcode/main.php
+++ b/ext/transcode/main.php
@@ -88,7 +88,7 @@ class TranscodeImage extends Extension
$sb->add_choice_option(TranscodeConfig::UPLOAD_PREFIX.$format, $outputs, "$display", true);
}
}
- $sb->add_int_option(TranscodeConfig::QUALITY, "Lossy format quality: ");
+ $sb->add_int_option(TranscodeConfig::QUALITY, "Lossy Format Quality", true);
$sb->end_table();
$event->panel->add_block($sb);
}