imgproxy 1.2.0 → 2.0.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 +235 -112
- data/lib/imgproxy.rb +70 -50
- 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 +83 -121
- data/lib/imgproxy/options_aliases.rb +43 -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.rb +0 -4
- data/lib/imgproxy/url_adapters/active_storage.rb +25 -0
- data/lib/imgproxy/url_adapters/shrine.rb +15 -5
- data/lib/imgproxy/version.rb +1 -1
- metadata +54 -9
- 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/builder.rb
CHANGED
@@ -3,6 +3,7 @@ require "base64"
|
|
3
3
|
require "erb"
|
4
4
|
|
5
5
|
require "imgproxy/options"
|
6
|
+
require "imgproxy/options_aliases"
|
6
7
|
|
7
8
|
module Imgproxy
|
8
9
|
# Builds imgproxy URL
|
@@ -17,19 +18,15 @@ module Imgproxy
|
|
17
18
|
# builder.url_for("http://images.example.com/images/image1.jpg")
|
18
19
|
# builder.url_for("http://images.example.com/images/image2.jpg")
|
19
20
|
class Builder
|
20
|
-
OMITTED_OPTIONS = %i[format].freeze
|
21
21
|
# @param [Hash] options Processing options
|
22
22
|
# @see Imgproxy.url_for
|
23
23
|
def initialize(options = {})
|
24
24
|
options = options.dup
|
25
25
|
|
26
|
-
|
27
|
-
@use_short_options = options.delete(:use_short_options)
|
28
|
-
|
29
|
-
@use_short_options = config.use_short_options if @use_short_options.nil?
|
30
|
-
@base64_encode_url = config.base64_encode_urls if @base64_encode_url.nil?
|
26
|
+
extract_builder_options(options)
|
31
27
|
|
32
28
|
@options = Imgproxy::Options.new(options)
|
29
|
+
@format = @options.delete(:format)
|
33
30
|
end
|
34
31
|
|
35
32
|
# Genrates imgproxy URL
|
@@ -39,77 +36,68 @@ module Imgproxy
|
|
39
36
|
# the configured URL adapters
|
40
37
|
# @see Imgproxy.url_for
|
41
38
|
def url_for(image)
|
42
|
-
path = [*processing_options, url(image)].join("/")
|
39
|
+
path = [*processing_options, url(image, ext: @format)].join("/")
|
43
40
|
signature = sign_path(path)
|
44
41
|
|
45
42
|
File.join(Imgproxy.config.endpoint.to_s, signature, path)
|
46
43
|
end
|
47
44
|
|
48
|
-
|
45
|
+
# Genrates imgproxy info URL
|
46
|
+
#
|
47
|
+
# @return [String] imgproxy info URL
|
48
|
+
# @param [String,URI, Object] image Source image URL or object applicable for
|
49
|
+
# the configured URL adapters
|
50
|
+
# @see Imgproxy.info_url_for
|
51
|
+
def info_url_for(image)
|
52
|
+
path = url(image)
|
53
|
+
signature = sign_path(path)
|
49
54
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
width: :w,
|
55
|
-
height: :h,
|
56
|
-
enlarge: :en,
|
57
|
-
extend: :ex,
|
58
|
-
gravity: :g,
|
59
|
-
crop: :c,
|
60
|
-
padding: :pd,
|
61
|
-
trim: :t,
|
62
|
-
quality: :q,
|
63
|
-
max_bytes: :mb,
|
64
|
-
background: :bg,
|
65
|
-
adjust: :a,
|
66
|
-
brightness: :br,
|
67
|
-
contrast: :co,
|
68
|
-
saturation: :sa,
|
69
|
-
blur: :bl,
|
70
|
-
sharpen: :sh,
|
71
|
-
pixelate: :pix,
|
72
|
-
watermark: :wm,
|
73
|
-
watermark_url: :wmu,
|
74
|
-
preset: :pr,
|
75
|
-
cachebuster: :cb,
|
76
|
-
}.freeze
|
55
|
+
File.join(Imgproxy.config.endpoint.to_s, "info", signature, path)
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
77
59
|
|
78
60
|
NEED_ESCAPE_RE = /[@?% ]|[^\p{Ascii}]/.freeze
|
79
61
|
|
62
|
+
def extract_builder_options(options)
|
63
|
+
@use_short_options = not_nil_or(options.delete(:use_short_options), config.use_short_options)
|
64
|
+
@base64_encode_url = not_nil_or(options.delete(:base64_encode_url), config.base64_encode_urls)
|
65
|
+
@escape_plain_url =
|
66
|
+
not_nil_or(options.delete(:escape_plain_url), config.always_escape_plain_urls)
|
67
|
+
end
|
68
|
+
|
80
69
|
def processing_options
|
81
|
-
@processing_options ||=
|
82
|
-
|
83
|
-
|
84
|
-
end
|
70
|
+
@processing_options ||= @options.map do |key, value|
|
71
|
+
[option_alias(key), value].join(":")
|
72
|
+
end
|
85
73
|
end
|
86
74
|
|
87
|
-
def
|
88
|
-
|
75
|
+
def url(image, ext: nil)
|
76
|
+
url = config.url_adapters.url_of(image)
|
89
77
|
|
90
|
-
@
|
78
|
+
@base64_encode_url ? base64_url_for(url, ext: ext) : plain_url_for(url, ext: ext)
|
91
79
|
end
|
92
80
|
|
93
|
-
def
|
94
|
-
|
81
|
+
def plain_url_for(url, ext: nil)
|
82
|
+
escaped_url = need_escape_url?(url) ? ERB::Util.url_encode(url) : url
|
95
83
|
|
96
|
-
|
84
|
+
ext ? "plain/#{escaped_url}@#{ext}" : "plain/#{escaped_url}"
|
97
85
|
end
|
98
86
|
|
99
|
-
def
|
100
|
-
|
87
|
+
def base64_url_for(url, ext: nil)
|
88
|
+
encoded_url = Base64.urlsafe_encode64(url).tr("=", "").scan(/.{1,16}/).join("/")
|
101
89
|
|
102
|
-
|
90
|
+
ext ? "#{encoded_url}.#{ext}" : encoded_url
|
103
91
|
end
|
104
92
|
|
105
|
-
def
|
106
|
-
|
93
|
+
def need_escape_url?(url)
|
94
|
+
@escape_plain_url || url.match?(NEED_ESCAPE_RE)
|
107
95
|
end
|
108
96
|
|
109
|
-
def
|
110
|
-
|
97
|
+
def option_alias(name)
|
98
|
+
return name unless @use_short_options
|
111
99
|
|
112
|
-
|
100
|
+
Imgproxy::OPTIONS_ALIASES.fetch(name, name)
|
113
101
|
end
|
114
102
|
|
115
103
|
def sign_path(path)
|
@@ -130,11 +118,11 @@ module Imgproxy
|
|
130
118
|
end
|
131
119
|
|
132
120
|
def signature_key
|
133
|
-
config.
|
121
|
+
config.raw_key
|
134
122
|
end
|
135
123
|
|
136
124
|
def signature_salt
|
137
|
-
config.
|
125
|
+
config.raw_salt
|
138
126
|
end
|
139
127
|
|
140
128
|
def signature_size
|
@@ -144,5 +132,9 @@ module Imgproxy
|
|
144
132
|
def config
|
145
133
|
Imgproxy.config
|
146
134
|
end
|
135
|
+
|
136
|
+
def not_nil_or(value, fallback)
|
137
|
+
value.nil? ? fallback : value
|
138
|
+
end
|
147
139
|
end
|
148
140
|
end
|
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,115 @@
|
|
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
|
+
}.freeze
|
68
|
+
|
69
|
+
META = %i[size resize adjust].freeze
|
19
70
|
|
20
71
|
# @param options [Hash] raw processing options
|
21
72
|
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 }])
|
32
|
-
|
33
|
-
freeze
|
34
|
-
end
|
35
|
-
|
36
|
-
private
|
73
|
+
# Options order hack: initialize known and meta options with nil value to preserve order
|
74
|
+
CASTERS.each_key { |n| self[n] = nil if options.key?(n) || META.include?(n) }
|
37
75
|
|
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
|
76
|
+
options.each do |name, value|
|
77
|
+
caster = CASTERS[name]
|
78
|
+
self[name] = caster ? caster.cast(value) : unwrap_hash(value)
|
48
79
|
end
|
49
|
-
end
|
50
|
-
|
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
80
|
|
59
|
-
def group_options
|
60
|
-
group_crop_opts
|
61
|
-
group_extend_opts
|
62
81
|
group_resizing_opts
|
63
|
-
group_gravity_opts
|
64
82
|
group_adjust_opts
|
65
|
-
group_watermark_opts
|
66
|
-
group_trim_opts
|
67
|
-
end
|
68
83
|
|
69
|
-
|
70
|
-
|
71
|
-
crop_height = delete(:crop_height)
|
72
|
-
crop_gravity = extract_and_trim_nils(:crop_gravity, :crop_gravity_x, :crop_gravity_y)
|
84
|
+
compact!
|
85
|
+
end
|
73
86
|
|
74
|
-
|
87
|
+
private
|
75
88
|
|
76
|
-
|
89
|
+
def unwrap_hash(raw)
|
90
|
+
return raw unless raw.is_a?(Hash)
|
77
91
|
|
78
|
-
|
92
|
+
raw.flat_map do |_key, val|
|
93
|
+
unwrap_hash(val)
|
94
|
+
end
|
79
95
|
end
|
80
96
|
|
81
97
|
def group_resizing_opts
|
82
|
-
return unless self[:width] && self[:height]
|
98
|
+
return unless self[:width] && self[:height] && !self[:size] && !self[:resize]
|
83
99
|
|
84
100
|
self[:size] = extract_and_trim_nils(:width, :height, :enlarge, :extend)
|
85
|
-
|
86
101
|
self[:resize] = [delete(:resizing_type), *delete(:size)] if self[:resizing_type]
|
87
102
|
end
|
88
103
|
|
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
104
|
def group_adjust_opts
|
106
|
-
return
|
105
|
+
return if self[:adjust]
|
106
|
+
return unless values_at(:brightness, :contrast, :saturation).count { |o| o } > 1
|
107
107
|
|
108
108
|
self[:adjust] = extract_and_trim_nils(:brightness, :contrast, :saturation)
|
109
109
|
end
|
110
110
|
|
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
111
|
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
|
112
|
+
keys.map { |k| delete(k) }.trim!
|
151
113
|
end
|
152
114
|
end
|
153
115
|
end
|