imgproxy 1.2.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +238 -113
- data/lib/imgproxy/builder.rb +47 -55
- data/lib/imgproxy/config.rb +96 -30
- data/lib/imgproxy/extensions/active_storage.rb +10 -0
- data/lib/imgproxy/extensions/shrine.rb +10 -0
- data/lib/imgproxy/options.rb +86 -120
- data/lib/imgproxy/options_aliases.rb +45 -0
- data/lib/imgproxy/options_casters/adjust.rb +22 -0
- data/lib/imgproxy/options_casters/array.rb +12 -0
- data/lib/imgproxy/options_casters/base64.rb +12 -0
- data/lib/imgproxy/options_casters/bool.rb +12 -0
- data/lib/imgproxy/options_casters/crop.rb +23 -0
- data/lib/imgproxy/options_casters/extend.rb +26 -0
- data/lib/imgproxy/options_casters/float.rb +16 -0
- data/lib/imgproxy/options_casters/gif_options.rb +21 -0
- data/lib/imgproxy/options_casters/gravity.rb +23 -0
- data/lib/imgproxy/options_casters/group.rb +21 -0
- data/lib/imgproxy/options_casters/integer.rb +10 -0
- data/lib/imgproxy/options_casters/jpeg_options.rb +26 -0
- data/lib/imgproxy/options_casters/png_options.rb +23 -0
- data/lib/imgproxy/options_casters/resize.rb +21 -0
- data/lib/imgproxy/options_casters/size.rb +24 -0
- data/lib/imgproxy/options_casters/string.rb +10 -0
- data/lib/imgproxy/options_casters/trim.rb +28 -0
- data/lib/imgproxy/options_casters/watermark.rb +30 -0
- data/lib/imgproxy/trim_array.rb +11 -0
- data/lib/imgproxy/url_adapters/active_storage.rb +35 -0
- data/lib/imgproxy/url_adapters/shrine.rb +16 -6
- data/lib/imgproxy/url_adapters.rb +0 -4
- data/lib/imgproxy/version.rb +1 -1
- data/lib/imgproxy.rb +72 -50
- metadata +69 -23
- data/lib/imgproxy/url_adapters/active_storage_gcs.rb +0 -31
- data/lib/imgproxy/url_adapters/active_storage_s3.rb +0 -23
- data/lib/imgproxy/url_adapters/shrine_s3.rb +0 -21
data/lib/imgproxy/config.rb
CHANGED
@@ -1,44 +1,110 @@
|
|
1
|
+
require "anyway_config"
|
2
|
+
|
1
3
|
require "imgproxy/url_adapters"
|
2
4
|
|
3
5
|
module Imgproxy
|
4
6
|
# Imgproxy config
|
7
|
+
#
|
8
|
+
# @!attribute endpoint
|
9
|
+
# imgproxy endpoint
|
10
|
+
# @return [String]
|
11
|
+
# @!attribute key
|
12
|
+
# imgproxy hex-encoded signature key
|
13
|
+
# @return [String]
|
14
|
+
# @!attribute salt
|
15
|
+
# imgproxy hex-encoded signature salt
|
16
|
+
# @return [String]
|
17
|
+
# @!attribute raw_key
|
18
|
+
# Decoded signature key
|
19
|
+
# @return [String]
|
20
|
+
# @!attribute raw_salt
|
21
|
+
# Decoded signature salt
|
22
|
+
# @return [String]
|
23
|
+
# @!attribute signature_size
|
24
|
+
# imgproxy signature size. Defaults to 32
|
25
|
+
# @return [String]
|
26
|
+
# @!attribute use_short_options
|
27
|
+
# Use short processing option names (+rs+ for +resize+, +g+ for +gravity+, etc).
|
28
|
+
# Defaults to true
|
29
|
+
# @return [String]
|
30
|
+
# @!attribute base64_encode_urls
|
31
|
+
# Base64 encode the URL. Defaults to false
|
32
|
+
# @return [String]
|
33
|
+
# @!attribute always_escape_plain_urls
|
34
|
+
# Always escape plain URLs. Defaults to false
|
35
|
+
# @return [String]
|
36
|
+
# @!attribute use_s3_urls
|
37
|
+
# Use short S3 urls (s3://...) when possible. Defaults to false
|
38
|
+
# @return [String]
|
39
|
+
# @!attribute use_gcs_urls
|
40
|
+
# Use short Google Cloud Storage urls (gs://...) when possible. Defaults to false
|
41
|
+
# @return [String]
|
42
|
+
# @!attribute gcs_bucket
|
43
|
+
# Google Cloud Storage bucket name
|
44
|
+
# @return [String]
|
45
|
+
# @!attribute shrine_host
|
46
|
+
# Shrine host
|
47
|
+
# @return [String]
|
48
|
+
#
|
5
49
|
# @see Imgproxy.configure
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
50
|
+
# @see https://github.com/palkan/anyway_config anyway_config
|
51
|
+
class Config < Anyway::Config
|
52
|
+
attr_config(
|
53
|
+
:endpoint,
|
54
|
+
:key,
|
55
|
+
:salt,
|
56
|
+
:raw_key,
|
57
|
+
:raw_salt,
|
58
|
+
signature_size: 32,
|
59
|
+
use_short_options: true,
|
60
|
+
base64_encode_urls: false,
|
61
|
+
always_escape_plain_urls: false,
|
62
|
+
use_s3_urls: false,
|
63
|
+
use_gcs_urls: false,
|
64
|
+
gcs_bucket: nil,
|
65
|
+
shrine_host: nil,
|
66
|
+
)
|
67
|
+
|
68
|
+
alias_method :set_key, :key=
|
69
|
+
alias_method :set_raw_key, :raw_key=
|
70
|
+
alias_method :set_salt, :salt=
|
71
|
+
alias_method :set_raw_salt, :raw_salt=
|
72
|
+
private :set_key, :set_raw_key, :set_salt, :set_raw_salt
|
73
|
+
|
74
|
+
def key=(value)
|
75
|
+
value = value&.to_s
|
76
|
+
super(value)
|
77
|
+
set_raw_key(value && [value].pack("H*"))
|
28
78
|
end
|
29
79
|
|
30
|
-
|
31
|
-
|
32
|
-
|
80
|
+
def raw_key=(value)
|
81
|
+
value = value&.to_s
|
82
|
+
super(value)
|
83
|
+
set_key(value&.unpack("H*")&.first)
|
84
|
+
end
|
85
|
+
|
86
|
+
def salt=(value)
|
87
|
+
value = value&.to_s
|
88
|
+
super(value)
|
89
|
+
set_raw_salt(value && [value].pack("H*"))
|
90
|
+
end
|
91
|
+
|
92
|
+
def raw_salt=(value)
|
93
|
+
value = value&.to_s
|
94
|
+
super(value)
|
95
|
+
set_salt(value&.unpack("H*")&.first)
|
96
|
+
end
|
97
|
+
|
98
|
+
# @deprecated Please use {#key} instead
|
33
99
|
def hex_key=(value)
|
34
|
-
|
100
|
+
warn "[DEPRECATION] #hex_key is deprecated. Please use #key instead."
|
101
|
+
self.key = value
|
35
102
|
end
|
36
103
|
|
37
|
-
#
|
38
|
-
#
|
39
|
-
# @param value [String] hex-encoded signature salt
|
104
|
+
# @deprecated Please use {#salt} instead
|
40
105
|
def hex_salt=(value)
|
41
|
-
|
106
|
+
warn "[DEPRECATION] #hex_salt is deprecated. Please use #salt instead."
|
107
|
+
self.salt = value
|
42
108
|
end
|
43
109
|
|
44
110
|
# URL adapters config. Allows to use this gem with ActiveStorage, Shrine, etc.
|
@@ -12,6 +12,16 @@ module Imgproxy
|
|
12
12
|
return options.url_for(self) if options.is_a?(Imgproxy::Builder)
|
13
13
|
Imgproxy.url_for(self, options)
|
14
14
|
end
|
15
|
+
|
16
|
+
# Returns imgproxy info URL for an attachment
|
17
|
+
#
|
18
|
+
# @return [String]
|
19
|
+
# @param options [Hash, Imgproxy::Builder]
|
20
|
+
# @see Imgproxy.info_url_for
|
21
|
+
def imgproxy_info_url(options = {})
|
22
|
+
return options.info_url_for(self) if options.is_a?(Imgproxy::Builder)
|
23
|
+
Imgproxy.info_url_for(self, options)
|
24
|
+
end
|
15
25
|
end
|
16
26
|
end
|
17
27
|
end
|
@@ -12,6 +12,16 @@ module Imgproxy
|
|
12
12
|
return options.url_for(self) if options.is_a?(Imgproxy::Builder)
|
13
13
|
Imgproxy.url_for(self, options)
|
14
14
|
end
|
15
|
+
|
16
|
+
# Returns imgproxy info URL for a Shrine::UploadedFile instance
|
17
|
+
#
|
18
|
+
# @return [String]
|
19
|
+
# @param options [Hash, Imgproxy::Builder]
|
20
|
+
# @see Imgproxy.info_url_for
|
21
|
+
def imgproxy_info_url(options = {})
|
22
|
+
return options.info_url_for(self) if options.is_a?(Imgproxy::Builder)
|
23
|
+
Imgproxy.info_url_for(self, options)
|
24
|
+
end
|
15
25
|
end
|
16
26
|
end
|
17
27
|
end
|
data/lib/imgproxy/options.rb
CHANGED
@@ -1,153 +1,119 @@
|
|
1
|
+
require "imgproxy/trim_array"
|
2
|
+
require "imgproxy/options_casters/string"
|
3
|
+
require "imgproxy/options_casters/integer"
|
4
|
+
require "imgproxy/options_casters/float"
|
5
|
+
require "imgproxy/options_casters/bool"
|
6
|
+
require "imgproxy/options_casters/array"
|
7
|
+
require "imgproxy/options_casters/base64"
|
8
|
+
require "imgproxy/options_casters/resize"
|
9
|
+
require "imgproxy/options_casters/size"
|
10
|
+
require "imgproxy/options_casters/extend"
|
11
|
+
require "imgproxy/options_casters/gravity"
|
12
|
+
require "imgproxy/options_casters/crop"
|
13
|
+
require "imgproxy/options_casters/trim"
|
14
|
+
require "imgproxy/options_casters/adjust"
|
15
|
+
require "imgproxy/options_casters/watermark"
|
16
|
+
require "imgproxy/options_casters/jpeg_options"
|
17
|
+
require "imgproxy/options_casters/png_options"
|
18
|
+
require "imgproxy/options_casters/gif_options"
|
19
|
+
|
1
20
|
module Imgproxy
|
2
21
|
# Formats and regroups processing options
|
3
22
|
class Options < Hash
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
23
|
+
using TrimArray
|
24
|
+
|
25
|
+
CASTERS = {
|
26
|
+
resize: Imgproxy::OptionsCasters::Resize,
|
27
|
+
size: Imgproxy::OptionsCasters::Size,
|
28
|
+
resizing_type: Imgproxy::OptionsCasters::String,
|
29
|
+
resizing_algorithm: Imgproxy::OptionsCasters::String,
|
30
|
+
width: Imgproxy::OptionsCasters::Integer,
|
31
|
+
height: Imgproxy::OptionsCasters::Integer,
|
32
|
+
dpr: Imgproxy::OptionsCasters::Float,
|
33
|
+
enlarge: Imgproxy::OptionsCasters::Bool,
|
34
|
+
extend: Imgproxy::OptionsCasters::Extend,
|
35
|
+
gravity: Imgproxy::OptionsCasters::Gravity,
|
36
|
+
crop: Imgproxy::OptionsCasters::Crop,
|
37
|
+
padding: Imgproxy::OptionsCasters::Array,
|
38
|
+
trim: Imgproxy::OptionsCasters::Trim,
|
39
|
+
rotate: Imgproxy::OptionsCasters::Integer,
|
40
|
+
quality: Imgproxy::OptionsCasters::Integer,
|
41
|
+
max_bytes: Imgproxy::OptionsCasters::Integer,
|
42
|
+
background: Imgproxy::OptionsCasters::Array,
|
43
|
+
background_alpha: Imgproxy::OptionsCasters::Float,
|
44
|
+
adjust: Imgproxy::OptionsCasters::Adjust,
|
45
|
+
brightness: Imgproxy::OptionsCasters::Integer,
|
46
|
+
contrast: Imgproxy::OptionsCasters::Float,
|
47
|
+
saturation: Imgproxy::OptionsCasters::Float,
|
48
|
+
blur: Imgproxy::OptionsCasters::Float,
|
49
|
+
sharpen: Imgproxy::OptionsCasters::Float,
|
50
|
+
pixelate: Imgproxy::OptionsCasters::Integer,
|
51
|
+
unsharpening: Imgproxy::OptionsCasters::String,
|
52
|
+
watermark: Imgproxy::OptionsCasters::Watermark,
|
53
|
+
watermark_url: Imgproxy::OptionsCasters::Base64,
|
54
|
+
style: Imgproxy::OptionsCasters::Base64,
|
55
|
+
jpeg_options: Imgproxy::OptionsCasters::JpegOptions,
|
56
|
+
png_options: Imgproxy::OptionsCasters::PngOptions,
|
57
|
+
gif_options: Imgproxy::OptionsCasters::GifOptions,
|
58
|
+
page: Imgproxy::OptionsCasters::Integer,
|
59
|
+
video_thumbnail_second: Imgproxy::OptionsCasters::Integer,
|
60
|
+
preset: Imgproxy::OptionsCasters::Array,
|
61
|
+
cachebuster: Imgproxy::OptionsCasters::String,
|
62
|
+
strip_metadata: Imgproxy::OptionsCasters::Bool,
|
63
|
+
strip_color_profile: Imgproxy::OptionsCasters::Bool,
|
64
|
+
auto_rotate: Imgproxy::OptionsCasters::Bool,
|
65
|
+
filename: Imgproxy::OptionsCasters::String,
|
66
|
+
format: Imgproxy::OptionsCasters::String,
|
67
|
+
return_attachment: Imgproxy::OptionsCasters::Bool,
|
68
|
+
expires: Imgproxy::OptionsCasters::Integer,
|
69
|
+
}.freeze
|
70
|
+
|
71
|
+
META = %i[size resize adjust].freeze
|
19
72
|
|
20
73
|
# @param options [Hash] raw processing options
|
21
74
|
def initialize(options)
|
22
|
-
|
23
|
-
|
24
|
-
typecast
|
25
|
-
|
26
|
-
group_options
|
27
|
-
|
28
|
-
encode_style
|
29
|
-
encode_watermark_url
|
30
|
-
|
31
|
-
replace(Hash[sort_by { |k, _| OPTS_PRIORITY.index(k) || 99 }])
|
75
|
+
super()
|
32
76
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
private
|
77
|
+
# Options order hack: initialize known and meta options with nil value to preserve order
|
78
|
+
CASTERS.each_key { |n| self[n] = nil if options.key?(n) || META.include?(n) }
|
37
79
|
|
38
|
-
|
39
|
-
|
40
|
-
self[
|
41
|
-
case key
|
42
|
-
when *STRING_OPTS then value.to_s
|
43
|
-
when *INT_OPTS then value.to_i
|
44
|
-
when *FLOAT_OPTS then value.to_f
|
45
|
-
when *BOOL_OPTS then bool(value)
|
46
|
-
when *ARRAY_OPTS then wrap_array(value)
|
47
|
-
end
|
80
|
+
options.each do |name, value|
|
81
|
+
caster = CASTERS[name]
|
82
|
+
self[name] = caster ? caster.cast(value) : unwrap_hash(value)
|
48
83
|
end
|
49
|
-
end
|
50
84
|
|
51
|
-
def bool(value)
|
52
|
-
value && value != 0 && value != "0" ? 1 : 0
|
53
|
-
end
|
54
|
-
|
55
|
-
def wrap_array(value)
|
56
|
-
value.is_a?(Array) ? value : [value]
|
57
|
-
end
|
58
|
-
|
59
|
-
def group_options
|
60
|
-
group_crop_opts
|
61
|
-
group_extend_opts
|
62
85
|
group_resizing_opts
|
63
|
-
group_gravity_opts
|
64
86
|
group_adjust_opts
|
65
|
-
group_watermark_opts
|
66
|
-
group_trim_opts
|
67
|
-
end
|
68
87
|
|
69
|
-
|
70
|
-
|
71
|
-
crop_height = delete(:crop_height)
|
72
|
-
crop_gravity = extract_and_trim_nils(:crop_gravity, :crop_gravity_x, :crop_gravity_y)
|
88
|
+
compact!
|
89
|
+
end
|
73
90
|
|
74
|
-
|
91
|
+
private
|
75
92
|
|
76
|
-
|
93
|
+
def unwrap_hash(raw)
|
94
|
+
return raw unless raw.is_a?(Hash)
|
77
95
|
|
78
|
-
|
96
|
+
raw.flat_map do |_key, val|
|
97
|
+
unwrap_hash(val)
|
98
|
+
end
|
79
99
|
end
|
80
100
|
|
81
101
|
def group_resizing_opts
|
82
|
-
return unless self[:width] && self[:height]
|
102
|
+
return unless self[:width] && self[:height] && !self[:size] && !self[:resize]
|
83
103
|
|
84
104
|
self[:size] = extract_and_trim_nils(:width, :height, :enlarge, :extend)
|
85
|
-
|
86
105
|
self[:resize] = [delete(:resizing_type), *delete(:size)] if self[:resizing_type]
|
87
106
|
end
|
88
107
|
|
89
|
-
def group_gravity_opts
|
90
|
-
gravity = extract_and_trim_nils(:gravity, :gravity_x, :gravity_y)
|
91
|
-
|
92
|
-
self[:gravity] = gravity unless gravity[0].nil?
|
93
|
-
end
|
94
|
-
|
95
|
-
def group_extend_opts
|
96
|
-
extend_opts =
|
97
|
-
extract_and_trim_nils(:extend, :extend_gravity, :extend_gravity_x, :extend_gravity_y)
|
98
|
-
|
99
|
-
return if extend_opts[0].nil?
|
100
|
-
return self[:extend] = 0 if extend_opts[0].zero?
|
101
|
-
|
102
|
-
self[:extend] = extend_opts
|
103
|
-
end
|
104
|
-
|
105
108
|
def group_adjust_opts
|
106
|
-
return
|
109
|
+
return if self[:adjust]
|
110
|
+
return unless values_at(:brightness, :contrast, :saturation).count { |o| o } > 1
|
107
111
|
|
108
112
|
self[:adjust] = extract_and_trim_nils(:brightness, :contrast, :saturation)
|
109
113
|
end
|
110
114
|
|
111
|
-
def group_watermark_opts
|
112
|
-
watermark = extract_and_trim_nils(
|
113
|
-
:watermark_opacity,
|
114
|
-
:watermark_position,
|
115
|
-
:watermark_x_offset,
|
116
|
-
:watermark_y_offset,
|
117
|
-
:watermark_scale,
|
118
|
-
)
|
119
|
-
|
120
|
-
self[:watermark] = watermark unless watermark[0].nil?
|
121
|
-
end
|
122
|
-
|
123
|
-
def group_trim_opts
|
124
|
-
trim = extract_and_trim_nils(
|
125
|
-
:trim_threshold,
|
126
|
-
:trim_color,
|
127
|
-
:trim_equal_hor,
|
128
|
-
:trim_equal_ver,
|
129
|
-
)
|
130
|
-
|
131
|
-
self[:trim] = trim unless trim[0].nil?
|
132
|
-
end
|
133
|
-
|
134
|
-
def encode_style
|
135
|
-
return if self[:style].nil?
|
136
|
-
self[:style] = Base64.urlsafe_encode64(self[:style]).tr("=", "")
|
137
|
-
end
|
138
|
-
|
139
|
-
def encode_watermark_url
|
140
|
-
return if self[:watermark_url].nil?
|
141
|
-
self[:watermark_url] = Base64.urlsafe_encode64(self[:watermark_url]).tr("=", "")
|
142
|
-
end
|
143
|
-
|
144
115
|
def extract_and_trim_nils(*keys)
|
145
|
-
|
146
|
-
end
|
147
|
-
|
148
|
-
def trim_nils(value)
|
149
|
-
value.delete_at(-1) while !value.empty? && value[-1].nil?
|
150
|
-
value
|
116
|
+
keys.map { |k| delete(k) }.trim!
|
151
117
|
end
|
152
118
|
end
|
153
119
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Imgproxy
|
2
|
+
OPTIONS_ALIASES = {
|
3
|
+
resize: :rs,
|
4
|
+
size: :s,
|
5
|
+
resizing_type: :rt,
|
6
|
+
resizing_algorithm: :ra,
|
7
|
+
width: :w,
|
8
|
+
height: :h,
|
9
|
+
enlarge: :el,
|
10
|
+
extend: :ex,
|
11
|
+
gravity: :g,
|
12
|
+
crop: :c,
|
13
|
+
padding: :pd,
|
14
|
+
trim: :t,
|
15
|
+
rotate: :rot,
|
16
|
+
quality: :q,
|
17
|
+
max_bytes: :mb,
|
18
|
+
background: :bg,
|
19
|
+
background_alpha: :bga,
|
20
|
+
adjust: :a,
|
21
|
+
brightness: :br,
|
22
|
+
contrast: :co,
|
23
|
+
saturation: :sa,
|
24
|
+
blur: :bl,
|
25
|
+
sharpen: :sh,
|
26
|
+
pixelate: :pix,
|
27
|
+
unsharpening: :ush,
|
28
|
+
watermark: :wm,
|
29
|
+
watermark_url: :wmu,
|
30
|
+
style: :st,
|
31
|
+
jpeg_options: :jpego,
|
32
|
+
png_options: :pngo,
|
33
|
+
gif_options: :gifo,
|
34
|
+
page: :pg,
|
35
|
+
video_thumbnail_second: :vts,
|
36
|
+
preset: :pr,
|
37
|
+
cachebuster: :cb,
|
38
|
+
strip_metadata: :sm,
|
39
|
+
strip_color_profile: :scp,
|
40
|
+
auto_rotate: :ar,
|
41
|
+
filename: :fn,
|
42
|
+
return_attachment: :att,
|
43
|
+
expires: :exp,
|
44
|
+
}.freeze
|
45
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require "imgproxy/options_casters/group"
|
2
|
+
require "imgproxy/options_casters/integer"
|
3
|
+
require "imgproxy/options_casters/float"
|
4
|
+
|
5
|
+
module Imgproxy
|
6
|
+
module OptionsCasters
|
7
|
+
# Casts gravity option
|
8
|
+
module Adjust
|
9
|
+
CASTER = Imgproxy::OptionsCasters::Group.new(
|
10
|
+
brightness: Imgproxy::OptionsCasters::Integer,
|
11
|
+
contrast: Imgproxy::OptionsCasters::Float,
|
12
|
+
saturation: Imgproxy::OptionsCasters::Float,
|
13
|
+
).freeze
|
14
|
+
|
15
|
+
def self.cast(raw)
|
16
|
+
return raw unless raw.is_a?(Hash)
|
17
|
+
|
18
|
+
CASTER.cast(raw)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require "imgproxy/trim_array"
|
2
|
+
require "imgproxy/options_casters/float"
|
3
|
+
require "imgproxy/options_casters/gravity"
|
4
|
+
|
5
|
+
module Imgproxy
|
6
|
+
module OptionsCasters
|
7
|
+
# Casts crop option
|
8
|
+
module Crop
|
9
|
+
using TrimArray
|
10
|
+
|
11
|
+
def self.cast(raw)
|
12
|
+
return raw unless raw.is_a?(Hash)
|
13
|
+
return unless raw[:width] || raw[:height]
|
14
|
+
|
15
|
+
[
|
16
|
+
Imgproxy::OptionsCasters::Float.cast(raw[:width]) || 0,
|
17
|
+
Imgproxy::OptionsCasters::Float.cast(raw[:height]) || 0,
|
18
|
+
Imgproxy::OptionsCasters::Gravity.cast(raw[:gravity]),
|
19
|
+
].trim!
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require "imgproxy/options_casters/group"
|
2
|
+
require "imgproxy/options_casters/bool"
|
3
|
+
require "imgproxy/options_casters/gravity"
|
4
|
+
|
5
|
+
module Imgproxy
|
6
|
+
module OptionsCasters
|
7
|
+
# Casts extend option
|
8
|
+
module Extend
|
9
|
+
CASTER = Imgproxy::OptionsCasters::Group.new(
|
10
|
+
extend: Imgproxy::OptionsCasters::Bool,
|
11
|
+
gravity: Imgproxy::OptionsCasters::Gravity,
|
12
|
+
).freeze
|
13
|
+
|
14
|
+
def self.cast(raw)
|
15
|
+
# Allow extend to be just a boolean
|
16
|
+
return Imgproxy::OptionsCasters::Bool.cast(raw) if [true, false].include?(raw)
|
17
|
+
|
18
|
+
return raw unless raw.is_a?(Hash)
|
19
|
+
return if raw[:extend].nil?
|
20
|
+
|
21
|
+
values = CASTER.cast(raw)
|
22
|
+
values[0].zero? ? 0 : values
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Imgproxy
|
2
|
+
module OptionsCasters
|
3
|
+
# Casts float option
|
4
|
+
module Float
|
5
|
+
ZERO_RE = /\.0+/.freeze
|
6
|
+
|
7
|
+
def self.cast(raw)
|
8
|
+
raw&.to_f&.then do |f|
|
9
|
+
# Convert integral value to Integer so to_s won't give us trailing zero
|
10
|
+
i = f.to_i
|
11
|
+
i == f ? i : f
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "imgproxy/options_casters/group"
|
2
|
+
require "imgproxy/options_casters/bool"
|
3
|
+
|
4
|
+
module Imgproxy
|
5
|
+
module OptionsCasters
|
6
|
+
# Casts gif_options option
|
7
|
+
module GifOptions
|
8
|
+
CASTER = Imgproxy::OptionsCasters::Group.new(
|
9
|
+
optimize_frames: Imgproxy::OptionsCasters::Bool,
|
10
|
+
optimize_transparency: Imgproxy::OptionsCasters::Bool,
|
11
|
+
).freeze
|
12
|
+
|
13
|
+
def self.cast(raw)
|
14
|
+
return raw unless raw.is_a?(Hash)
|
15
|
+
|
16
|
+
values = CASTER.cast(raw)
|
17
|
+
values.empty? ? nil : values
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require "imgproxy/options_casters/group"
|
2
|
+
require "imgproxy/options_casters/string"
|
3
|
+
require "imgproxy/options_casters/float"
|
4
|
+
|
5
|
+
module Imgproxy
|
6
|
+
module OptionsCasters
|
7
|
+
# Casts gravity option
|
8
|
+
module Gravity
|
9
|
+
CASTER = Imgproxy::OptionsCasters::Group.new(
|
10
|
+
type: Imgproxy::OptionsCasters::String,
|
11
|
+
x_offset: Imgproxy::OptionsCasters::Float,
|
12
|
+
y_offset: Imgproxy::OptionsCasters::Float,
|
13
|
+
).freeze
|
14
|
+
|
15
|
+
def self.cast(raw)
|
16
|
+
return raw unless raw.is_a?(Hash)
|
17
|
+
return unless raw[:type]
|
18
|
+
|
19
|
+
CASTER.cast(raw)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "imgproxy/trim_array"
|
2
|
+
|
3
|
+
module Imgproxy
|
4
|
+
module OptionsCasters
|
5
|
+
# Casts group of options and trim nils from the end
|
6
|
+
class Group
|
7
|
+
using TrimArray
|
8
|
+
|
9
|
+
def initialize(extractors)
|
10
|
+
@extractors = extractors
|
11
|
+
end
|
12
|
+
|
13
|
+
def cast(raw)
|
14
|
+
values = @extractors.map do |key, extractor|
|
15
|
+
extractor.cast(raw[key])
|
16
|
+
end
|
17
|
+
values.trim!
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|