From 2ffe973275e16f587d5048382cbe977d79129e8a Mon Sep 17 00:00:00 2001 From: evazion Date: Tue, 30 Nov 2021 04:27:25 -0600 Subject: [PATCH] MediaFile: add support for creating .webp and .avif thumbnails. These other formats aren't actually generated during upload, but support for creating them is there. Also tune the parameters for generating JPEGs: * Use Q=85 instead of Q=90 because Q=85 enables 4:2:0 chroma subsampling, while Q=90 doesn't use subsampling. Subsampling reduces filesize by ~30% in most cases. It does reduce quality for certain images, particularly for images with lots of bright red, but in most cases the quality difference isn't noticeable. * Enable several MozJPEG-specific options, including trellis quantization and scan optimization. These reduce filesize without reducing quality, at the cost of slower encoding times. --- app/logical/media_file/image.rb | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/app/logical/media_file/image.rb b/app/logical/media_file/image.rb index 3535f43ab..9d1cc7c0f 100644 --- a/app/logical/media_file/image.rb +++ b/app/logical/media_file/image.rb @@ -3,9 +3,6 @@ # @see https://github.com/libvips/ruby-vips # @see https://libvips.github.io/libvips/API/current class MediaFile::Image < MediaFile - # http://jcupitt.github.io/libvips/API/current/VipsForeignSave.html#vips-jpegsave - JPEG_OPTIONS = { Q: 90, background: 255, strip: true, interlace: true, optimize_coding: true } - def dimensions image.size rescue Vips::Error @@ -66,8 +63,20 @@ class MediaFile::Image < MediaFile raise NotImplementedError end - output_file = Tempfile.new(["image-preview", ".jpg"]) - resized_image.jpegsave(output_file.path, **JPEG_OPTIONS) + output_file = Tempfile.new(["image-preview-#{md5}", ".#{format.to_s}"]) + case format.to_sym + when :jpeg + # https://www.libvips.org/API/current/VipsForeignSave.html#vips-jpegsave + resized_image.jpegsave(output_file.path, Q: 85, background: 255, strip: true, interlace: true, optimize_coding: true, optimize_scans: true, trellis_quant: true, overshoot_deringing: true, quant_table: 3) + when :webp + # https://www.libvips.org/API/current/VipsForeignSave.html#vips-webpsave + resized_image.webpsave(output_file.path, Q: 85, preset: :drawing, effort: 4, strip: true) + when :avif + # https://www.libvips.org/API/current/VipsForeignSave.html#vips-heifsave + resized_image.heifsave(output_file.path, Q: 40, compression: :av1, effort: 4, strip: true) + else + raise NotImplementedError + end MediaFile::Image.new(output_file) end