From 9cb70fa63248e82d7d134d6541a8f682d7d0b114 Mon Sep 17 00:00:00 2001 From: evazion Date: Sun, 5 Dec 2021 08:23:49 -0600 Subject: [PATCH] posts: add 720x720 thumbnail size. This is used to provide higher resolution thumbnails for high pixel density displays, such as phones or laptops. If your screen has a 2x pixel density ratio, then 360x360 thumbnails will be rendered at 720x720 resolution. We use WebP here because it's about 15% smaller than the equivalent JPEG, and because if a device has a high enough pixel density to use this, then it probably supports WebP. 720x720 thumbnails average about 36kb in size, compared to 20.35kb for 360x360 thumbnails and 7.55kb for 180x180 thumbnails. --- app/components/post_preview_component.rb | 12 ------------ .../post_preview_component.html.erb | 13 ++++++++++++- app/logical/media_file/image.rb | 12 ++++++++---- app/models/media_asset.rb | 16 ++++++++++++---- 4 files changed, 32 insertions(+), 21 deletions(-) diff --git a/app/components/post_preview_component.rb b/app/components/post_preview_component.rb index b3a24bcf7..8414f8c61 100644 --- a/app/components/post_preview_component.rb +++ b/app/components/post_preview_component.rb @@ -65,18 +65,6 @@ class PostPreviewComponent < ApplicationComponent end end - def preview_srcset - if size == "180" - "#{media_asset.variant("180x180").file_url} 1x, #{media_asset.variant("360x360").file_url} 2x" - else - nil - end - end - - def preview_url - variant.file_url - end - def tooltip "#{post.tag_string} rating:#{post.rating} score:#{post.score}" end diff --git a/app/components/post_preview_component/post_preview_component.html.erb b/app/components/post_preview_component/post_preview_component.html.erb index 88fbcc40e..a0ea881b2 100644 --- a/app/components/post_preview_component/post_preview_component.html.erb +++ b/app/components/post_preview_component/post_preview_component.html.erb @@ -13,7 +13,18 @@ <% end %> - <%= tag.img srcset: preview_srcset, src: preview_url, width: variant.width, height: variant.height, class: "post-preview-image", title: tooltip, alt: "post ##{post.id}", crossorigin: "anonymous" -%> + + <% case size %> + <% when "150" %> + <%# no-op %> + <% when "180" %> + <%= tag.source type: "image/jpeg", srcset: "#{media_asset.variant("180x180").file_url} 1x, #{media_asset.variant("360x360").file_url} 2x" %> + <% else # 225 to 360 %> + <%= tag.source type: "image/webp", srcset: "#{media_asset.variant("360x360").file_url} 1x, #{media_asset.variant("720x720").file_url} 2x" %> + <% end %> + + <%= tag.img src: variant.file_url, width: variant.width, height: variant.height, class: "post-preview-image", title: tooltip, alt: "post ##{post.id}", crossorigin: "anonymous" -%> + <% end -%> <% if pool -%>

diff --git a/app/logical/media_file/image.rb b/app/logical/media_file/image.rb index 33cdc9e3b..d8667c67f 100644 --- a/app/logical/media_file/image.rb +++ b/app/logical/media_file/image.rb @@ -44,7 +44,7 @@ class MediaFile::Image < MediaFile image.interpretation end - def resize(max_width, max_height, format: :jpeg, **options) + def resize(max_width, max_height, format: :jpeg, quality: 85, **options) # @see https://www.libvips.org/API/current/Using-vipsthumbnail.md.html # @see https://www.libvips.org/API/current/libvips-resample.html#vips-thumbnail if colorspace == :srgb @@ -63,17 +63,21 @@ class MediaFile::Image < MediaFile raise NotImplementedError end + if resized_image.has_alpha? + resized_image = resized_image.flatten(background: 255) + end + 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) + resized_image.jpegsave(output_file.path, Q: quality, 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) + resized_image.webpsave(output_file.path, Q: quality, preset: :drawing, smart_subsample: false, 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) + resized_image.heifsave(output_file.path, Q: quality, compression: :av1, effort: 4, strip: true) else raise NotImplementedError end diff --git a/app/models/media_asset.rb b/app/models/media_asset.rb index afcdbcf26..6656d314f 100644 --- a/app/models/media_asset.rb +++ b/app/models/media_asset.rb @@ -1,7 +1,7 @@ class MediaAsset < ApplicationRecord class Error < StandardError; end - VARIANTS = %i[preview crop 180x180 360x360 sample original] + VARIANTS = %i[preview crop 180x180 360x360 720x720 sample original] has_one :media_metadata, dependent: :destroy has_one :pixiv_ugoira_frame_data, class_name: "PixivUgoiraFrameData", foreign_key: :md5, primary_key: :md5 @@ -59,13 +59,15 @@ class MediaAsset < ApplicationRecord def convert_file(media_file) case variant in :preview, :"180x180", :"360x360" - media_file.preview(width, height) + media_file.preview(width, height, format: :jpeg, quality: 85) + in :"720x720" + media_file.preview(width, height, format: :webp, quality: 75) in :crop media_file.crop(width, height) in :sample if media_asset.is_ugoira? media_file.convert in :sample if media_asset.is_static_image? - media_file.preview(width, height) + media_file.preview(width, height, format: :jpeg, quality: 85) in :original media_file end @@ -76,7 +78,7 @@ class MediaAsset < ApplicationRecord end def file_path(slug = "") - if variant.in?(%i[preview crop 180x180 360x360]) && media_asset.is_flash? + if variant.in?(%i[preview crop 180x180 360x360 720x720]) && media_asset.is_flash? "/images/download-preview.png" else slug = "__#{slug}__" if slug.present? @@ -100,6 +102,8 @@ class MediaAsset < ApplicationRecord case variant when :preview, :crop, :"180x180", :"360x360" "jpg" + when :"720x720" + "webp" when :sample media_asset.is_ugoira? ? "webm" : "jpg" when :original @@ -117,6 +121,8 @@ class MediaAsset < ApplicationRecord [180, 180] when :"360x360" [360, 360] + when :"720x720" + [720, 720] when :sample [850, nil] when :original @@ -151,6 +157,8 @@ class MediaAsset < ApplicationRecord true when :"360x360" true + when :"720x720" + true when :sample media_asset.is_ugoira? || (media_asset.is_static_image? && media_asset.image_width > Danbooru.config.large_image_width) when :original