media assets: add full variant for .avif and .webp files.
Add a JPEG conversion for .avif and .webp files. The `full` variant is the .avif or .webp file converted to JPEG format, with the same resolution as the original file (full resolution). Known bug: When converting an HDR .avif file to .jpeg, the resulting image is too bright compared to the original image as rendered by Firefox or Chrome.
This commit is contained in:
@@ -5,7 +5,7 @@ class MediaAsset < ApplicationRecord
|
||||
|
||||
FILE_TYPES = %w[jpg png gif webp avif mp4 webm swf zip]
|
||||
FILE_KEY_LENGTH = 9
|
||||
VARIANTS = %i[preview 180x180 360x360 720x720 sample original]
|
||||
VARIANTS = %i[preview 180x180 360x360 720x720 sample full original]
|
||||
MAX_FILE_SIZE = Danbooru.config.max_file_size.to_i
|
||||
MAX_VIDEO_DURATION = Danbooru.config.max_video_duration.to_i
|
||||
MAX_IMAGE_RESOLUTION = Danbooru.config.max_image_resolution
|
||||
@@ -95,7 +95,7 @@ class MediaAsset < ApplicationRecord
|
||||
media_file.preview(width, height, format: :webp, quality: 75)
|
||||
in :sample if media_asset.is_ugoira?
|
||||
media_file.convert
|
||||
in :sample if media_asset.is_static_image?
|
||||
in :sample | :full if media_asset.is_static_image?
|
||||
media_file.preview(width, height, format: :jpeg, quality: 85)
|
||||
in :original
|
||||
media_file
|
||||
@@ -124,13 +124,15 @@ class MediaAsset < ApplicationRecord
|
||||
# The file extension of this variant.
|
||||
def file_ext
|
||||
case type
|
||||
when :preview, :"180x180", :"360x360"
|
||||
in :preview | :"180x180" | :"360x360"
|
||||
"jpg"
|
||||
when :"720x720"
|
||||
in :"720x720"
|
||||
"webp"
|
||||
when :sample
|
||||
media_asset.is_ugoira? ? "webm" : "jpg"
|
||||
when :original
|
||||
in :sample if media_asset.is_animated?
|
||||
"webm"
|
||||
in :sample | :full if media_asset.is_static_image?
|
||||
"jpg"
|
||||
in :original
|
||||
media_asset.file_ext
|
||||
end
|
||||
end
|
||||
@@ -147,6 +149,8 @@ class MediaAsset < ApplicationRecord
|
||||
[720, 720]
|
||||
when :sample
|
||||
[850, nil]
|
||||
when :full
|
||||
[nil, nil]
|
||||
when :original
|
||||
[nil, nil]
|
||||
end
|
||||
@@ -359,14 +363,14 @@ class MediaAsset < ApplicationRecord
|
||||
end
|
||||
|
||||
def variant_types
|
||||
@variant_types ||=
|
||||
if is_flash?
|
||||
[:original]
|
||||
elsif (is_animated? && !is_ugoira?) || (is_static_image? && image_width <= LARGE_IMAGE_WIDTH)
|
||||
VARIANTS - [:sample]
|
||||
else
|
||||
VARIANTS
|
||||
end
|
||||
@variant_types ||= begin
|
||||
variants = []
|
||||
variants = %i[preview 180x180 360x360 720x720] unless is_flash?
|
||||
variants << :sample if is_ugoira? || (is_static_image? && image_width > LARGE_IMAGE_WIDTH)
|
||||
variants << :full if is_webp? || is_avif?
|
||||
variants << :original
|
||||
variants
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -379,6 +383,14 @@ class MediaAsset < ApplicationRecord
|
||||
is_image? && !is_animated?
|
||||
end
|
||||
|
||||
def is_webp?
|
||||
file_ext == "webp"
|
||||
end
|
||||
|
||||
def is_avif?
|
||||
file_ext == "avif"
|
||||
end
|
||||
|
||||
def is_video?
|
||||
file_ext.in?(%w[webm mp4])
|
||||
end
|
||||
|
||||
@@ -247,12 +247,9 @@ class UploadsControllerTest < ActionDispatch::IntegrationTest
|
||||
end
|
||||
end
|
||||
|
||||
# XXX fixme
|
||||
context "for a video longer than the video length limit" do
|
||||
should_eventually "work for an admin" do
|
||||
@source = "https://cdn.donmai.us/original/63/cb/63cb09f2526ef3ac14f11c011516ad9b.webm"
|
||||
post_auth uploads_path(format: :json), create(:admin_user), params: { upload: { source: @source }}
|
||||
perform_enqueued_jobs
|
||||
should "work for an admin" do
|
||||
create_upload!("https://cdn.donmai.us/original/63/cb/63cb09f2526ef3ac14f11c011516ad9b.webm", user: create(:admin_user))
|
||||
|
||||
assert_response 201
|
||||
assert_equal("completed", Upload.last.status)
|
||||
@@ -301,6 +298,32 @@ class UploadsControllerTest < ActionDispatch::IntegrationTest
|
||||
assert_equal(true, upload.media_assets.first.media_metadata.present?)
|
||||
end
|
||||
|
||||
context "uploading an AVIF file" do
|
||||
should "generate thumbnails" do
|
||||
upload = assert_successful_upload("test/files/avif/paris_icc_exif_xmp.avif", user: @user)
|
||||
media_asset = upload.media_assets.first
|
||||
|
||||
full_variant = media_asset.variant(:full).open_file
|
||||
assert_equal([403, 302], full_variant.dimensions)
|
||||
assert_equal(:jpg, full_variant.file_ext)
|
||||
|
||||
assert_nil(media_asset.variant(:sample))
|
||||
end
|
||||
end
|
||||
|
||||
context "uploading a WebP file" do
|
||||
should "generate thumbnails" do
|
||||
upload = assert_successful_upload("test/files/webp/fjord.webp", user: @user)
|
||||
media_asset = upload.media_assets.first
|
||||
|
||||
full_variant = media_asset.variant(:full).open_file
|
||||
assert_equal([550, 368], full_variant.dimensions)
|
||||
assert_equal(:jpg, full_variant.file_ext)
|
||||
|
||||
assert_equal(nil, media_asset.variant(:sample))
|
||||
end
|
||||
end
|
||||
|
||||
context "uploading a file from your computer" do
|
||||
should_upload_successfully("test/files/test.jpg")
|
||||
should_upload_successfully("test/files/test.png")
|
||||
@@ -319,6 +342,11 @@ class UploadsControllerTest < ActionDispatch::IntegrationTest
|
||||
|
||||
should_upload_successfully("test/files/webp/test.webp")
|
||||
should_upload_successfully("test/files/webp/fjord.webp")
|
||||
should_upload_successfully("test/files/webp/2_webp_a.webp")
|
||||
should_upload_successfully("test/files/webp/2_webp_ll.webp")
|
||||
should_upload_successfully("test/files/webp/Exif2.webp")
|
||||
should_upload_successfully("test/files/webp/lossless1.webp")
|
||||
should_upload_successfully("test/files/webp/lossy_alpha1.webp")
|
||||
end
|
||||
|
||||
context "uploading multiple files from your computer" do
|
||||
@@ -344,6 +372,7 @@ class UploadsControllerTest < ActionDispatch::IntegrationTest
|
||||
upload = assert_successful_upload("https://www.pixiv.net/en/artworks/45982180", user: @user)
|
||||
|
||||
assert_equal([60] * 70, upload.media_assets.first.metadata["Ugoira:FrameDelays"])
|
||||
assert_equal(:webm, upload.media_assets.first.variant(:sample).open_file.file_ext)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user