split out image cropping to width x height, add StorageManager::Match
This commit is contained in:
@@ -17,11 +17,11 @@ module DanbooruImageResizer
|
||||
end
|
||||
end
|
||||
|
||||
def self.crop(file, length, quality = 90)
|
||||
def self.crop(file, width, height, quality = 90)
|
||||
if Vips.at_least_libvips?(8, 5)
|
||||
crop_ruby(file, length, quality)
|
||||
crop_ruby(file, width, height, quality)
|
||||
else
|
||||
crop_shell(file, length, quality)
|
||||
crop_shell(file, width, height, quality)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -35,9 +35,9 @@ module DanbooruImageResizer
|
||||
output_file
|
||||
end
|
||||
|
||||
def self.crop_ruby(file, length, resize_quality)
|
||||
def self.crop_ruby(file, width, height, resize_quality)
|
||||
output_file = Tempfile.new
|
||||
resized_image = Vips::Image.thumbnail(file.path, length, height: length, **CROP_OPTIONS)
|
||||
resized_image = Vips::Image.thumbnail(file.path, width, height: height, **CROP_OPTIONS)
|
||||
resized_image.jpegsave(output_file.path, Q: resize_quality, **JPEG_OPTIONS)
|
||||
|
||||
output_file
|
||||
@@ -65,7 +65,7 @@ module DanbooruImageResizer
|
||||
output_file
|
||||
end
|
||||
|
||||
def self.crop_shell(file, length, quality)
|
||||
def self.crop_shell(file, width, height, quality)
|
||||
output_file = Tempfile.new(["crop", ".jpg"])
|
||||
|
||||
# --size=WxH will upscale if the image is smaller than the target size.
|
||||
@@ -76,7 +76,7 @@ module DanbooruImageResizer
|
||||
file.path,
|
||||
"--eprofile=#{SRGB_PROFILE}",
|
||||
"--smartcrop=attention",
|
||||
"--size=#{length}",
|
||||
"--size=#{width}x#{height}",
|
||||
"--format=#{output_file.path}[Q=#{quality},background=255,strip,interlace,optimize_coding]"
|
||||
]
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ class PixivUgoiraConverter
|
||||
zipfile = Zip::File.new(ugoira_file.path)
|
||||
zipfile.entries.first.extract(file.path) { true } # 'true' means overwrite the existing tempfile.
|
||||
|
||||
DanbooruImageResizer.crop(file, Danbooru.config.small_image_width, 85)
|
||||
DanbooruImageResizer.crop(file, Danbooru.config.small_image_width, Danbooru.config.small_image_width, 85)
|
||||
ensure
|
||||
file.close!
|
||||
end
|
||||
|
||||
113
app/logical/storage_manager/match.rb
Normal file
113
app/logical/storage_manager/match.rb
Normal file
@@ -0,0 +1,113 @@
|
||||
=begin
|
||||
|
||||
Generalizes the hybrid storage manager to be more declarative in
|
||||
syntax. Matches are executed in order of appearance so the first
|
||||
matching manager is returned. You should always add at least one
|
||||
manager with no constraints as a default case.
|
||||
|
||||
This does not derive from StorageManager so only `open_file`,
|
||||
`delete_file`, `store_file`, `file_url`, and `file_path` are
|
||||
implemented.
|
||||
|
||||
### Example
|
||||
|
||||
StorageManager::Match.new do |matcher|
|
||||
matcher.add_manager(type: :crop) do
|
||||
StorageManager::SFTP.new("raikou3.donmai.us", base_url: "https://raikou3.donmai.us", hierarchical: true, base_dir: "/var/www/raikou3")
|
||||
end
|
||||
|
||||
matcher.add_manager(id: 1..850_000) do
|
||||
StorageManager::SFTP.new("raikou1.donmai.us", base_url: "https://raikou1.donmai.us", hierarchical: true, base_dir: "/var/www/raikou1")
|
||||
end
|
||||
|
||||
matcher.add_manager(id: 850_001..2_000_000) do
|
||||
StorageManager::SFTP.new("raikou2.donmai.us", base_url: "https://raikou2.donmai.us", hierarchical: true, base_dir: "/var/www/raikou2")
|
||||
end
|
||||
|
||||
matcher.add_manager(id: 1..3_000_000, type: [:large, :original]) do
|
||||
StorageManager::SFTP.new(*Danbooru.config.all_server_hosts, base_url: "https://hijiribe.donmai.us/data")
|
||||
end
|
||||
|
||||
matcher.add_manager({}) do
|
||||
StorageManager::SFTP.new(*Danbooru.config.all_server_hosts, base_url: "#{CurrentUser.root_url}/data")
|
||||
end
|
||||
end
|
||||
|
||||
=end
|
||||
|
||||
class StorageManager::Match
|
||||
def initialize
|
||||
@managers = []
|
||||
|
||||
yield self if block_given?
|
||||
end
|
||||
|
||||
def add_manager(constraints)
|
||||
manager = yield
|
||||
@managers << [constraints, manager]
|
||||
end
|
||||
|
||||
def find(params)
|
||||
@managers.each do |constraints, manager|
|
||||
match = true
|
||||
|
||||
if params[:id] && constraints[:id] && !constraints[:id].include?(params[:id].to_i)
|
||||
match = false
|
||||
end
|
||||
|
||||
if constraints[:id] && !params[:id]
|
||||
match = false
|
||||
end
|
||||
|
||||
if params[:type] && constraints[:type]
|
||||
if constraints[:type].respond_to?(:include?)
|
||||
if !constraints[:type].include?(params[:type])
|
||||
match = false
|
||||
end
|
||||
elsif constraints[:type] != params[:type]
|
||||
match = false
|
||||
end
|
||||
end
|
||||
|
||||
if constraints[:type] && !params[:type]
|
||||
match = false
|
||||
end
|
||||
|
||||
if match
|
||||
yield manager if block_given?
|
||||
return manager unless block_given?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def store_file(io, post, type)
|
||||
find(id: post.id, type: type) do |manager|
|
||||
manager.store_file(io, post, type)
|
||||
end
|
||||
end
|
||||
|
||||
def delete_file(post_id, md5, file_ext, type)
|
||||
find(id: post_id, type: type) do |manager|
|
||||
manager.delete_file(post_id, md5, file_ext, type)
|
||||
end
|
||||
end
|
||||
|
||||
def open_file(post, type)
|
||||
find(id: post.id, type: type) do |manager|
|
||||
manager.open_file(post, type)
|
||||
end
|
||||
end
|
||||
|
||||
def file_url(post, type, **options)
|
||||
find(id: post.id, type: type) do |manager|
|
||||
manager.file_url(post, type, **options)
|
||||
end
|
||||
end
|
||||
|
||||
def file_path(post, type, **options)
|
||||
find(id: post.id, type: type) do |manager|
|
||||
manager.file_path(post, type, **options)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -140,7 +140,7 @@ class UploadService
|
||||
|
||||
elsif upload.is_image?
|
||||
preview_file = DanbooruImageResizer.resize(file, Danbooru.config.small_image_width, Danbooru.config.small_image_width, 85)
|
||||
crop_file = DanbooruImageResizer.crop(file, Danbooru.config.small_image_width, 85)
|
||||
crop_file = DanbooruImageResizer.crop(file, Danbooru.config.small_image_width, Danbooru.config.small_image_width, 85)
|
||||
if upload.image_width > Danbooru.config.large_image_width
|
||||
sample_file = DanbooruImageResizer.resize(file, Danbooru.config.large_image_width, upload.image_height, 90)
|
||||
end
|
||||
@@ -152,7 +152,7 @@ class UploadService
|
||||
def self.generate_video_crop_for(video, width)
|
||||
vp = Tempfile.new(["video-preview", ".jpg"], binmode: true)
|
||||
video.screenshot(vp.path, {:seek_time => 0, :resolution => "#{video.width}x#{video.height}"})
|
||||
crop = DanbooruImageResizer.crop(vp, width, 85)
|
||||
crop = DanbooruImageResizer.crop(vp, width, width, 85)
|
||||
vp.close
|
||||
return crop
|
||||
end
|
||||
|
||||
@@ -7,6 +7,42 @@ class StorageManagerTest < ActiveSupport::TestCase
|
||||
CurrentUser.ip_addr = "127.0.0.1"
|
||||
end
|
||||
|
||||
context "StorageManager::Match" do
|
||||
setup do
|
||||
@storage_manager = StorageManager::Match.new do |matcher|
|
||||
matcher.add_manager(type: :crop) do
|
||||
"crop"
|
||||
end
|
||||
|
||||
matcher.add_manager(type: [:large, :original]) do
|
||||
"large or original"
|
||||
end
|
||||
|
||||
matcher.add_manager(id: 1..100) do
|
||||
"first"
|
||||
end
|
||||
|
||||
matcher.add_manager(id: 101..200, type: :preview) do
|
||||
"preview"
|
||||
end
|
||||
|
||||
matcher.add_manager({}) do
|
||||
"default"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
should "find the different matches" do
|
||||
assert_equal("large or original", @storage_manager.find(type: :original))
|
||||
assert_equal("crop", @storage_manager.find(type: :crop))
|
||||
assert_equal("large or original", @storage_manager.find(type: :large))
|
||||
assert_equal("preview", @storage_manager.find(type: :preview, id: 150))
|
||||
assert_equal("default", @storage_manager.find(type: :preview, id: 1000))
|
||||
assert_equal("crop", @storage_manager.find(type: :crop, id: 1_000))
|
||||
assert_equal("large or original", @storage_manager.find(type: :large, id: 1_000))
|
||||
end
|
||||
end
|
||||
|
||||
context "StorageManager::Local" do
|
||||
setup do
|
||||
@storage_manager = StorageManager::Local.new(base_dir: BASE_DIR, base_url: "/data")
|
||||
|
||||
Reference in New Issue
Block a user