imgproxy 2.1.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +8 -0
  3. data/CHANGELOG.md +74 -0
  4. data/README.md +176 -135
  5. data/UPGRADE.md +136 -0
  6. data/docs/info_options.md +223 -0
  7. data/docs/processing_options.md +724 -0
  8. data/docs/yard/fix_pictures.rb +25 -0
  9. data/docs/yard/github_alerts.rb +16 -0
  10. data/docs/yard/relative_markdown_links.rb +31 -0
  11. data/lib/imgproxy/config.rb +96 -41
  12. data/lib/imgproxy/extensions/active_storage.rb +6 -4
  13. data/lib/imgproxy/extensions/shrine.rb +6 -4
  14. data/lib/imgproxy/option_aliases/info.rb +33 -0
  15. data/lib/imgproxy/option_aliases/processing.rb +74 -0
  16. data/lib/imgproxy/options_builders/base.rb +54 -0
  17. data/lib/imgproxy/options_builders/info.rb +52 -0
  18. data/lib/imgproxy/options_builders/processing.rb +150 -0
  19. data/lib/imgproxy/options_casters/adjust.rb +3 -1
  20. data/lib/imgproxy/options_casters/alpha.rb +27 -0
  21. data/lib/imgproxy/options_casters/array.rb +3 -1
  22. data/lib/imgproxy/options_casters/autoquality.rb +28 -0
  23. data/lib/imgproxy/options_casters/average.rb +27 -0
  24. data/lib/imgproxy/options_casters/background.rb +27 -0
  25. data/lib/imgproxy/options_casters/base64.rb +2 -0
  26. data/lib/imgproxy/options_casters/blur_detections.rb +28 -0
  27. data/lib/imgproxy/options_casters/blurhash.rb +21 -0
  28. data/lib/imgproxy/options_casters/bool.rb +3 -1
  29. data/lib/imgproxy/options_casters/crop.rb +3 -1
  30. data/lib/imgproxy/options_casters/dominant_colors.rb +27 -0
  31. data/lib/imgproxy/options_casters/draw_detections.rb +28 -0
  32. data/lib/imgproxy/options_casters/extend.rb +3 -1
  33. data/lib/imgproxy/options_casters/filename.rb +31 -0
  34. data/lib/imgproxy/options_casters/float.rb +3 -1
  35. data/lib/imgproxy/options_casters/format_quality.rb +19 -0
  36. data/lib/imgproxy/options_casters/gradient.rb +31 -0
  37. data/lib/imgproxy/options_casters/gravity.rb +20 -6
  38. data/lib/imgproxy/options_casters/group.rb +2 -0
  39. data/lib/imgproxy/options_casters/hashsum.rb +24 -0
  40. data/lib/imgproxy/options_casters/integer.rb +2 -0
  41. data/lib/imgproxy/options_casters/jpeg_options.rb +3 -1
  42. data/lib/imgproxy/options_casters/padding.rb +41 -0
  43. data/lib/imgproxy/options_casters/png_options.rb +3 -1
  44. data/lib/imgproxy/options_casters/resize.rb +3 -1
  45. data/lib/imgproxy/options_casters/size.rb +3 -1
  46. data/lib/imgproxy/options_casters/string.rb +2 -0
  47. data/lib/imgproxy/options_casters/trim.rb +3 -1
  48. data/lib/imgproxy/options_casters/unsharp_masking.rb +25 -0
  49. data/lib/imgproxy/options_casters/video_thumbnail_tile.rb +34 -0
  50. data/lib/imgproxy/options_casters/watermark.rb +5 -4
  51. data/lib/imgproxy/options_casters/watermark_size.rb +21 -0
  52. data/lib/imgproxy/options_casters/{gif_options.rb → webp_options.rb} +6 -5
  53. data/lib/imgproxy/options_casters/zoom.rb +27 -0
  54. data/lib/imgproxy/service_config.rb +111 -0
  55. data/lib/imgproxy/trim_array.rb +2 -0
  56. data/lib/imgproxy/url_adapters/active_storage.rb +2 -0
  57. data/lib/imgproxy/url_adapters/shrine.rb +8 -2
  58. data/lib/imgproxy/url_adapters.rb +3 -0
  59. data/lib/imgproxy/url_builders/base.rb +184 -0
  60. data/lib/imgproxy/url_builders/info.rb +44 -0
  61. data/lib/imgproxy/url_builders/processing.rb +59 -0
  62. data/lib/imgproxy/version.rb +3 -1
  63. data/lib/imgproxy.rb +19 -57
  64. data/logo/logo-dark.svg +22 -0
  65. data/logo/logo-light.svg +31 -0
  66. metadata +70 -32
  67. data/lib/imgproxy/builder.rb +0 -140
  68. data/lib/imgproxy/options.rb +0 -119
  69. data/lib/imgproxy/options_aliases.rb +0 -45
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "imgproxy/options_casters/integer"
4
+ require "imgproxy/options_casters/bool"
5
+ require "imgproxy/options_casters/extend"
6
+
7
+ module Imgproxy
8
+ module OptionsCasters
9
+ # Casts `watermark_size` processing option
10
+ module WatermarkSize
11
+ def self.cast(raw)
12
+ return raw unless raw.is_a?(Hash)
13
+
14
+ [
15
+ Imgproxy::OptionsCasters::Integer.cast(raw[:width]) || 0,
16
+ Imgproxy::OptionsCasters::Integer.cast(raw[:height]) || 0,
17
+ ]
18
+ end
19
+ end
20
+ end
21
+ end
@@ -1,13 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "imgproxy/options_casters/group"
2
- require "imgproxy/options_casters/bool"
4
+ require "imgproxy/options_casters/string"
3
5
 
4
6
  module Imgproxy
5
7
  module OptionsCasters
6
- # Casts gif_options option
7
- module GifOptions
8
+ # Casts `webp_options` processing option
9
+ module WebpOptions
8
10
  CASTER = Imgproxy::OptionsCasters::Group.new(
9
- optimize_frames: Imgproxy::OptionsCasters::Bool,
10
- optimize_transparency: Imgproxy::OptionsCasters::Bool,
11
+ compression: Imgproxy::OptionsCasters::String,
11
12
  ).freeze
12
13
 
13
14
  def self.cast(raw)
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "imgproxy/trim_array"
4
+ require "imgproxy/options_casters/float"
5
+
6
+ module Imgproxy
7
+ module OptionsCasters
8
+ # Casts `zoom` info option
9
+ module Zoom
10
+ using TrimArray
11
+
12
+ def self.cast(raw)
13
+ # Allow zoom to be just a float
14
+ return Imgproxy::OptionsCasters::Float.cast(raw) if raw.is_a?(Numeric)
15
+
16
+ return raw unless raw.is_a?(Hash)
17
+
18
+ return Imgproxy::OptionsCasters::Float.cast(raw[:zoom_x_y]) if raw.key?(:zoom_x_y)
19
+
20
+ [
21
+ Imgproxy::OptionsCasters::Float.cast(raw[:zoom_x]) || 1,
22
+ Imgproxy::OptionsCasters::Float.cast(raw[:zoom_y]) || 1,
23
+ ].trim!
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,111 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "anyway_config"
4
+
5
+ module Imgproxy
6
+ # Imgproxy custom config for services
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 source_url_encryption_key
27
+ # imgproxy hex-encoded source URL encryption key
28
+ # @return [String]
29
+ # @!attribute raw_source_url_encryption_key
30
+ # Decoded source URL encryption key
31
+ # @return [String]
32
+ # @!attribute always_encrypt_source_urls
33
+ # Always encrypt source URLs. Defaults to false
34
+ # @return [String]
35
+ #
36
+ # @see Imgproxy::Config
37
+ class ServiceConfig < Anyway::Config
38
+ # Inherit global config values
39
+ config_name :imgproxy
40
+
41
+ attr_config(
42
+ :endpoint,
43
+ :key,
44
+ :salt,
45
+ :raw_key,
46
+ :raw_salt,
47
+ :source_url_encryption_key,
48
+ :raw_source_url_encryption_key,
49
+ signature_size: 32,
50
+ always_encrypt_source_urls: false,
51
+ )
52
+
53
+ coerce_types(
54
+ endpoint: :string,
55
+ key: :string,
56
+ salt: :string,
57
+ raw_key: :string,
58
+ raw_salt: :string,
59
+ signature_size: :integer,
60
+ source_url_encryption_key: :string,
61
+ raw_source_url_encryption_key: :string,
62
+ always_encrypt_source_urls: :boolean,
63
+ )
64
+
65
+ alias_method :set_key, :key=
66
+ alias_method :set_raw_key, :raw_key=
67
+ alias_method :set_salt, :salt=
68
+ alias_method :set_raw_salt, :raw_salt=
69
+ alias_method :set_source_url_encryption_key, :source_url_encryption_key=
70
+ alias_method :set_raw_source_url_encryption_key, :raw_source_url_encryption_key=
71
+
72
+ private :set_key, :set_raw_key, :set_salt, :set_raw_salt,
73
+ :set_source_url_encryption_key, :set_raw_source_url_encryption_key
74
+
75
+ def key=(value)
76
+ value = value&.to_s
77
+ super(value)
78
+ set_raw_key(value && [value].pack("H*"))
79
+ end
80
+
81
+ def raw_key=(value)
82
+ value = value&.to_s
83
+ super(value)
84
+ set_key(value&.unpack!("H*"))
85
+ end
86
+
87
+ def salt=(value)
88
+ value = value&.to_s
89
+ super(value)
90
+ set_raw_salt(value && [value].pack("H*"))
91
+ end
92
+
93
+ def raw_salt=(value)
94
+ value = value&.to_s
95
+ super(value)
96
+ set_salt(value&.unpack1("H*"))
97
+ end
98
+
99
+ def source_url_encryption_key=(value)
100
+ value = value&.to_s
101
+ super(value)
102
+ set_raw_source_url_encryption_key(value && [value].pack("H*"))
103
+ end
104
+
105
+ def raw_source_url_encryption_key=(value)
106
+ value = value&.to_s
107
+ super(value)
108
+ set_source_url_encryption_key(value&.unpack1("H*"))
109
+ end
110
+ end
111
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Imgproxy
2
4
  # `Array.trim!` refinement
3
5
  module TrimArray
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Imgproxy
2
4
  class UrlAdapters
3
5
  # Adapter for ActiveStorage
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Imgproxy
2
4
  class UrlAdapters
3
5
  # Adapter for Shrine
@@ -16,7 +18,7 @@ module Imgproxy
16
18
  return s3_url(image) if use_s3_url(image)
17
19
 
18
20
  opts = {}
19
- opts[:host] = Imgproxy.config.shrine_host if Imgproxy.config.shrine_host
21
+ opts[:host] = config.shrine_host if config.shrine_host
20
22
  image.url(**opts)
21
23
  end
22
24
 
@@ -28,9 +30,13 @@ module Imgproxy
28
30
  end
29
31
 
30
32
  def use_s3_url(image)
31
- Imgproxy.config.use_s3_urls &&
33
+ config.use_s3_urls &&
32
34
  image.storage.is_a?(::Shrine::Storage::S3)
33
35
  end
36
+
37
+ def config
38
+ Imgproxy.config
39
+ end
34
40
  end
35
41
  end
36
42
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "imgproxy/url_adapters/active_storage"
2
4
  require "imgproxy/url_adapters/shrine"
3
5
 
@@ -11,6 +13,7 @@ module Imgproxy
11
13
  # Imgproxy.url_for(user.avatar)
12
14
  class UrlAdapters
13
15
  class NotFound < StandardError; end
16
+
14
17
  class NotConfigured < StandardError; end
15
18
 
16
19
  # @return [Array] Currently added adapters
@@ -0,0 +1,184 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "openssl"
4
+ require "base64"
5
+ require "erb"
6
+
7
+ require "imgproxy/options_builders/base"
8
+
9
+ module Imgproxy
10
+ module UrlBuilders
11
+ class UnknownServiceError < StandardError; end
12
+
13
+ class InvalidEncryptionKeyError < StandardError; end
14
+
15
+ # Builds imgproxy URL
16
+ #
17
+ # builder = Imgproxy::UrlBuilders::Base.new(
18
+ # width: 500,
19
+ # height: 400,
20
+ # resizing_type: :fill,
21
+ # sharpen: 0.5
22
+ # )
23
+ #
24
+ # builder.url_for("http://images.example.com/images/image1.jpg")
25
+ # builder.url_for("http://images.example.com/images/image2.jpg")
26
+ class Base
27
+ OPTIONS_BUILDER = OptionsBuilders::Base
28
+ OPTION_ALIASES = {}.freeze
29
+
30
+ # @param [Hash] options imgproxy URL options
31
+ # @see Imgproxy.url_for
32
+ # @see Imgproxy.info_url_for
33
+ def initialize(options = {})
34
+ options = options.dup
35
+
36
+ extract_builder_options(options)
37
+
38
+ @options = self.class::OPTIONS_BUILDER.new(options)
39
+ end
40
+
41
+ # Genrates imgproxy URL
42
+ #
43
+ # @return [String] imgproxy URL
44
+ # @param [String,URI, Object] _image Source image URL or object applicable for
45
+ # the configured URL adapters
46
+ # @see Imgproxy.url_for
47
+ # @see Imgproxy.info_url_for
48
+ def url_for(_image)
49
+ raise NotImplementedError
50
+ end
51
+
52
+ private
53
+
54
+ attr_reader :service
55
+
56
+ NEED_ESCAPE_RE = /[@?% ]|[^\p{Ascii}]/.freeze
57
+ AES_SIZES = {32 => 256, 24 => 196, 16 => 128}.freeze
58
+
59
+ def extract_builder_options(options)
60
+ @service = options.delete(:service)&.to_sym || :default
61
+
62
+ @use_short_options =
63
+ not_nil_or(options.delete(:use_short_options), config.use_short_options)
64
+ @base64_encode_url =
65
+ not_nil_or(options.delete(:base64_encode_url), config.base64_encode_urls)
66
+ @escape_plain_url =
67
+ not_nil_or(options.delete(:escape_plain_url), config.always_escape_plain_urls)
68
+ @encrypt_source_url =
69
+ not_nil_or(options.delete(:encrypt_source_url), service_config.always_encrypt_source_urls)
70
+ @source_url_encryption_iv = options.delete(:source_url_encryption_iv)
71
+ end
72
+
73
+ def option_strings
74
+ @option_strings ||= @options.map do |key, value|
75
+ [option_alias(key), value].join(":")
76
+ end
77
+ end
78
+
79
+ def sourcce_url(image, ext: nil)
80
+ url = config.url_adapters.url_of(image)
81
+
82
+ return encrypted_sourcce_url_for(url, ext: ext) if @encrypt_source_url
83
+ return base64_sourcce_url_for(url, ext: ext) if @base64_encode_url
84
+ plain_url_for(url, ext: ext)
85
+ end
86
+
87
+ def plain_url_for(url, ext: nil)
88
+ escaped_url = need_escape_url?(url) ? ERB::Util.url_encode(url) : url
89
+
90
+ ext ? "plain/#{escaped_url}@#{ext}" : "plain/#{escaped_url}"
91
+ end
92
+
93
+ def base64_sourcce_url_for(url, ext: nil)
94
+ encoded_url = Base64.urlsafe_encode64(url).tr("=", "").scan(/.{1,16}/).join("/")
95
+
96
+ ext ? "#{encoded_url}.#{ext}" : encoded_url
97
+ end
98
+
99
+ def encrypted_sourcce_url_for(url, ext: nil)
100
+ cipher = build_cipher
101
+
102
+ iv = @source_url_encryption_iv || cipher.random_iv
103
+ cipher.iv = iv
104
+
105
+ "enc/#{base64_sourcce_url_for(iv + cipher.update(url) + cipher.final, ext: ext)}"
106
+ end
107
+
108
+ def need_escape_url?(url)
109
+ @escape_plain_url || url.match?(NEED_ESCAPE_RE)
110
+ end
111
+
112
+ def build_cipher
113
+ key = encryption_key.to_s
114
+
115
+ aes_size = AES_SIZES.fetch(key.length) do
116
+ raise Imgproxy::UrlBuilders::InvalidEncryptionKeyError,
117
+ "Encryption key should be 16/24/32 bytes long, now - #{key.length}"
118
+ end
119
+
120
+ OpenSSL::Cipher::AES.new(aes_size, :CBC).tap do |cipher|
121
+ cipher.encrypt
122
+ cipher.key = key
123
+ end
124
+ end
125
+
126
+ def option_alias(name)
127
+ return name unless @use_short_options
128
+
129
+ self.class::OPTION_ALIASES.fetch(name, name)
130
+ end
131
+
132
+ def sign_path(path)
133
+ return "unsafe" unless ready_to_sign?
134
+
135
+ digest = OpenSSL::HMAC.digest(
136
+ OpenSSL::Digest.new("sha256"),
137
+ signature_key,
138
+ "#{signature_salt}/#{path}",
139
+ )[0, signature_size]
140
+
141
+ Base64.urlsafe_encode64(digest).tr("=", "")
142
+ end
143
+
144
+ def ready_to_sign?
145
+ !(signature_key.nil? || signature_salt.nil? ||
146
+ signature_key.empty? || signature_salt.empty?)
147
+ end
148
+
149
+ def signature_key
150
+ service_config.raw_key
151
+ end
152
+
153
+ def signature_salt
154
+ service_config.raw_salt
155
+ end
156
+
157
+ def signature_size
158
+ service_config.signature_size
159
+ end
160
+
161
+ def encryption_key
162
+ service_config.raw_source_url_encryption_key
163
+ end
164
+
165
+ def not_nil_or(value, fallback)
166
+ value.nil? ? fallback : value
167
+ end
168
+
169
+ def endpoint
170
+ service_config.endpoint
171
+ end
172
+
173
+ def service_config
174
+ @service_config ||= config.services[service].tap do |c|
175
+ raise Imgproxy::UrlBuilders::UnknownServiceError, service unless c
176
+ end
177
+ end
178
+
179
+ def config
180
+ Imgproxy.config
181
+ end
182
+ end
183
+ end
184
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "imgproxy/option_aliases/info"
4
+ require "imgproxy/options_builders/info"
5
+ require "imgproxy/url_builders/base"
6
+
7
+ module Imgproxy
8
+ module UrlBuilders
9
+ # Builds imgproxy info URL
10
+ #
11
+ # builder = Imgproxy::UrlBuilders::Info.new(
12
+ # width: 500,
13
+ # height: 400,
14
+ # resizing_type: :fill,
15
+ # sharpen: 0.5
16
+ # )
17
+ #
18
+ # builder.url_for("http://images.example.com/images/image1.jpg")
19
+ # builder.url_for("http://images.example.com/images/image2.jpg")
20
+ class Info < Base
21
+ OPTIONS_BUILDER = OptionsBuilders::Info
22
+ OPTION_ALIASES = Imgproxy::OptionAliases::INFO
23
+
24
+ # @param [Hash] options Info options
25
+ # @see Imgproxy.info_url_for
26
+ def initialize(options = {})
27
+ super
28
+ end
29
+
30
+ # Genrates imgproxy info URL
31
+ #
32
+ # @return [String] imgproxy info URL
33
+ # @param [String,URI, Object] image Source image URL or object applicable for
34
+ # the configured URL adapters
35
+ # @see Imgproxy.info_url_for
36
+ def url_for(image)
37
+ path = [*option_strings, sourcce_url(image)].join("/")
38
+ signature = sign_path(path)
39
+
40
+ File.join(endpoint.to_s, "info", signature, path)
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "imgproxy/option_aliases/processing"
4
+ require "imgproxy/options_builders/processing"
5
+ require "imgproxy/url_builders/base"
6
+
7
+ module Imgproxy
8
+ module UrlBuilders
9
+ # Builds imgproxy URL
10
+ #
11
+ # builder = Imgproxy::UrlBuilders::Processing.new(
12
+ # width: 500,
13
+ # height: 400,
14
+ # resizing_type: :fill,
15
+ # sharpen: 0.5
16
+ # )
17
+ #
18
+ # builder.url_for("http://images.example.com/images/image1.jpg")
19
+ # builder.url_for("http://images.example.com/images/image2.jpg")
20
+ class Processing < Base
21
+ OPTIONS_BUILDER = OptionsBuilders::Processing
22
+ OPTION_ALIASES = Imgproxy::OptionAliases::PROCESSING
23
+
24
+ # @param [Hash] options Processing options
25
+ # @see Imgproxy.url_for
26
+ def initialize(options = {})
27
+ super(options)
28
+
29
+ @format = @options.delete(:format)
30
+ end
31
+
32
+ # Genrates imgproxy URL
33
+ #
34
+ # @return [String] imgproxy URL
35
+ # @param [String,URI, Object] image Source image URL or object applicable for
36
+ # the configured URL adapters
37
+ # @see Imgproxy.url_for
38
+ def url_for(image)
39
+ path = [*option_strings, sourcce_url(image, ext: @format)].join("/")
40
+ signature = sign_path(path)
41
+
42
+ File.join(endpoint.to_s, signature, path)
43
+ end
44
+
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)
54
+
55
+ # File.join(endpoint.to_s, "info", signature, path)
56
+ # end
57
+ end
58
+ end
59
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Imgproxy
2
- VERSION = "2.1.0".freeze
4
+ VERSION = "3.0.0"
3
5
  end
data/lib/imgproxy.rb CHANGED
@@ -1,6 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "imgproxy/version"
2
4
  require "imgproxy/config"
3
- require "imgproxy/builder"
5
+ require "imgproxy/url_builders/processing"
6
+ require "imgproxy/url_builders/info"
4
7
 
5
8
  require "imgproxy/extensions/active_storage"
6
9
  require "imgproxy/extensions/shrine"
@@ -58,71 +61,30 @@ module Imgproxy
58
61
  # @return [String] imgproxy URL
59
62
  # @param [String,URI, Object] image Source image URL or object applicable for
60
63
  # the configured URL adapters
61
- # @param [Hash] options Processing options
62
- # @option options [Hash|Array|String] :resize
63
- # @option options [Hash|Array|String] :size
64
- # @option options [String] :resizing_type
65
- # @option options [String] :resizing_algorithm supported only by imgproxy pro
66
- # @option options [Integer] :width
67
- # @option options [Integer] :height
68
- # @option options [Float] :dpr
69
- # @option options [Boolean] :enlarge
70
- # @option options [Hash|Array|Boolean|String] :extend
71
- # @option options [Hash|Array|String] :gravity
72
- # @option options [Hash|Array|String] :crop
73
- # @option options [Array] :padding
74
- # @option options [Hash|Array|String] :trim
75
- # @option options [Integer] :rotate
76
- # @option options [Integer] :quality
77
- # @option options [Integer] :max_bytes
78
- # @option options [Array|String] :background
79
- # @option options [Float] :background_alpha supported only by imgproxy pro
80
- # @option options [Hash|Array|String] :adjust
81
- # @option options [Integer] :brightness supported only by imgproxy pro
82
- # @option options [Float] :contrast supported only by imgproxy pro
83
- # @option options [Float] :saturation supported only by imgproxy pro
84
- # @option options [Float] :blur
85
- # @option options [Float] :sharpen
86
- # @option options [Integer] :pixelate supported only by imgproxy pro
87
- # @option options [String] :unsharpening supported only by imgproxy pro
88
- # @option options [Hash|Array|Float|String] :watermark
89
- # @option options [String] :watermark_url supported only by imgproxy pro
90
- # @option options [String] :style supported only by imgproxy pro
91
- # @option options [Hash|Array|String] :jpeg_options supported only by imgproxy pro
92
- # @option options [Hash|Array|String] :png_options supported only by imgproxy pro
93
- # @option options [Hash|Array|String] :gif_options supported only by imgproxy pro
94
- # @option options [Integer] :page supported only by imgproxy pro
95
- # @option options [Integer] :video_thumbnail_second supported only by imgproxy pro
96
- # @option options [Array] :preset
97
- # @option options [String] :cachebuster
98
- # @option options [Boolean] :strip_metadata
99
- # @option options [Boolean] :strip_color_profile
100
- # @option options [Boolean] :auto_rotate
101
- # @option options [String] :filename
102
- # @option options [String] :format
103
- # @option options [Boolean] :return_attachment
104
- # @option options [Integer] :expires
105
- # @option options [Boolean] :use_short_options
106
- # @option options [Boolean] :base64_encode_urls
107
- # @option options [Boolean] :escape_plain_url
108
- # @see https://docs.imgproxy.net/#/generating_the_url_advanced?id=processing-options
109
- # Available imgproxy URL processing options and their arguments
64
+ # @param [Hash] options Processing options.
65
+ # See: {file:docs/processing_options.md Supported processing options}
110
66
  def url_for(image, options = {})
111
- Imgproxy::Builder.new(options).url_for(image)
67
+ Imgproxy::UrlBuilders::Processing.new(options).url_for(image)
112
68
  end
113
69
 
114
- # Genrates imgproxy info URL. Supported only by imgproxy pro
70
+ # Genrates imgproxy info URL. Supported only by imgproxy Pro
115
71
  #
116
- # Imgproxy.info_url_for("http://images.example.com/images/image.jpg")
72
+ # Imgproxy.info_url_for(
73
+ # "http://images.example.com/images/image.jpg",
74
+ # alpha: {
75
+ # alpha: true,
76
+ # check_transparency: true
77
+ # },
78
+ # palette: 128,
79
+ # )
117
80
  #
118
81
  # @return [String] imgproxy info URL
119
82
  # @param [String,URI, Object] image Source image URL or object applicable for
120
83
  # the configured URL adapters
121
- # @param [Hash] options Processing options
122
- # @option options [Boolean] :base64_encode_urls
123
- # @option options [Boolean] :escape_plain_url
84
+ # @param [Hash] options Info options.
85
+ # See: {file:docs/info_options.md Supported info options}
124
86
  def info_url_for(image, options = {})
125
- Imgproxy::Builder.new(options).info_url_for(image)
87
+ Imgproxy::UrlBuilders::Info.new(options).url_for(image)
126
88
  end
127
89
 
128
90
  # Extends +ActiveStorage::Blob+ with {Imgproxy::Extensions::ActiveStorage.imgproxy_url} method
@@ -0,0 +1,22 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="266" height="100" fill="none">
2
+ <g clip-path="url(#a)">
3
+ <path fill="#fff" d="M94.056 42.55v2.915h5.803v11.648h-5.803v2.915h14.733v-2.915h-5.69V42.549h-9.043Zm4.916-4.367c0 1.423.83 2.423 2.451 2.423 1.619 0 2.45-1 2.45-2.423 0-1.422-.831-2.422-2.45-2.422-1.62 0-2.451 1-2.451 2.422Zm14.479 4.366v17.465h3.239V48.746c0-2.507.859-3.633 2.775-3.633 1.915 0 2.774 1.14 2.774 3.633v11.268h3.24V48.746c0-2.535.859-3.633 2.775-3.633 1.915 0 2.774 1.112 2.774 3.633v11.268h3.24V47.845c0-3.465-2.099-5.76-5.24-5.76-1.648 0-3.155.732-4.014 1.915h-.591c-.86-1.225-2.155-1.916-3.747-1.916-1.648 0-2.887.578-3.563 1.634h-.409V42.55h-3.253Zm42.704 16.902V42.549h-3.24v1.578h-.887c-.831-1.226-2.676-2.043-4.662-2.043-4.662 0-7.774 3.437-7.774 8.62 0 5.099 3.126 8.507 7.774 8.507 1.916 0 3.775-.76 4.662-1.915h.887v1.859c0 2.676-1.887 4.253-5.07 4.253-2.535 0-4.422-1.042-5.07-2.788h-3.183c.183 3.436 3.478 5.704 8.253 5.704 5.155-.014 8.31-2.746 8.31-6.873Zm-13.324-8.747c0-3.465 1.944-5.591 5.127-5.591s5.127 2.126 5.127 5.591c0 3.465-1.944 5.592-5.127 5.592s-5.127-2.127-5.127-5.592Zm28.648-8.62c-2.127 0-4.071.874-4.887 2.212h-.888v-1.747h-3.239v23.296h3.239v-7.577h.888c.816 1.338 2.774 2.21 4.887 2.21 4.775 0 7.958-3.675 7.958-9.196s-3.183-9.197-7.958-9.197Zm-5.887 9.212c0-3.817 2-6.17 5.309-6.17 3.296 0 5.31 2.353 5.31 6.17 0 3.817-2 6.169-5.31 6.169-3.309 0-5.309-2.366-5.309-6.17Zm18.845-8.747v2.916h4.14v11.648h-4.14v2.915h13.746v-2.915h-6.366v-6.409c0-3.704 1.155-5.591 3.422-5.591 1.831 0 2.775 1.07 2.775 3.14v2.057h3.352v-2.521c0-3.55-1.915-5.705-5.07-5.705-1.676 0-3.071.634-3.831 1.803h-.888V42.55h-7.14Zm30.042 17.944c5.211 0 8.69-3.676 8.69-9.197 0-5.521-3.479-9.197-8.69-9.197-5.211 0-8.69 3.676-8.69 9.197 0 5.52 3.465 9.197 8.69 9.197Zm-5.451-9.197c0-3.817 2.071-6.17 5.451-6.17 3.394 0 5.451 2.353 5.451 6.17 0 3.817-2.057 6.169-5.451 6.169-3.394 0-5.451-2.366-5.451-6.17ZM227 60.028h3.718l4.127-6.056.324-.845h.296l.324.845 4.07 6.056h3.944l-5.747-8.591 6.099-8.888h-3.62l-4.62 6.705-.323.845h-.296l-.324-.845-4.423-6.705h-3.887l6.042 9.17-5.704 8.31Zm20.69-17.479 6.338 16.014h2.648l-1.056 2.972c-.535 1.31-1.057 1.86-2.028 1.86-1.057 0-1.62-.55-2.184-1.86h-2.943c.239 3.056 2.155 4.775 5.31 4.775 2.126 0 3.859-1.395 4.718-3.789l7.127-19.972h-3.296l-4.62 13.099h-1.267l-5.155-13.099h-3.592Z"/>
4
+ <mask id="b" width="94" height="79" x="0" y="22" maskUnits="userSpaceOnUse" style="mask-type:luminance">
5
+ <path fill="#fff" d="M.394 22.535h92.817v78.169H.394V22.535Z"/>
6
+ </mask>
7
+ <g mask="url(#b)">
8
+ <path fill="url(#c)" d="M78.493 32.732V22.535H68.31v2.831H44.535v-2.83H34.352v2.83H10.577v-2.83H.394v10.196h2.831v12.465H.395v10.197h2.83V67.86H.395v10.197h10.182v-2.845h23.775v2.831h10.183v-2.83H68.31v2.83h10.183V67.845h-2.831V55.38h2.83V45.183h-2.83V32.718h2.83v.014Zm-41.873-7.93h5.662v5.663H36.62v-5.662ZM2.662 30.466v-5.662h5.662v5.662H2.662Zm0 22.662v-5.662h5.662v5.662H2.662Zm5.662 22.648H2.662v-5.662h5.662v5.662Zm33.958 0H36.62v-5.662h5.662v5.662Zm26.028-5.099H44.535v-2.83H34.352v2.83H10.577v-2.83h-2.83V55.38h2.83V45.183h-2.83V32.718h2.83v-2.83h23.775v2.83h10.183v-2.83H68.31v2.83h2.83v12.465h-2.83V55.38h2.83v12.465h-2.83v2.831Zm7.93-.563v5.662h-5.663v-5.662h5.662Zm0-22.648v5.662h-5.663v-5.662h5.662Zm-5.663-17v-5.662h5.662v5.662h-5.662Z"/>
9
+ <path fill="#1960C4" d="M22.55 45.192v.864h.592a1.98 1.98 0 0 1 .8-.848 2.36 2.36 0 0 1 1.2-.304c.778 0 1.37.293 1.776.88.405.587.608 1.445.608 2.576v1.552h-2.544V48.68c0-.459-.086-.8-.256-1.024-.17-.235-.432-.352-.784-.352-.438 0-.763.197-.976.592-.203.395-.304.997-.304 1.808v3.072h2.8V55h-6.88v-2.224h1.664v-5.36h-1.872v-2.224h4.176ZM35.545 55v-9.808h2.496V55h-2.496Zm-3.44-4.192c0 .715.144 1.253.432 1.616.288.363.715.544 1.28.544.576 0 1.008-.181 1.296-.544.288-.363.432-.901.432-1.616h.368v3.312h-.96a2.293 2.293 0 0 1-.896.88c-.384.203-.827.304-1.328.304-.65 0-1.21-.155-1.68-.464-.459-.31-.816-.752-1.072-1.328-.245-.587-.368-1.28-.368-2.08v-6.24h2.496v5.616Zm14.019 4.448c-.49 0-.933-.107-1.328-.32a2.085 2.085 0 0 1-.88-.864h-.592V55h-2.496V41.432h2.496v4.672h.592c.192-.352.485-.635.88-.848.395-.213.837-.32 1.328-.32.79 0 1.477.213 2.064.64.597.416 1.056 1.013 1.376 1.792.32.768.48 1.68.48 2.736 0 1.045-.16 1.957-.48 2.736-.32.768-.779 1.365-1.376 1.792-.587.416-1.275.624-2.064.624Zm-2.944-5.168c0 .928.192 1.653.576 2.176.395.512.944.768 1.648.768s1.248-.256 1.632-.768c.395-.523.592-1.248.592-2.176 0-.928-.197-1.648-.592-2.16-.384-.512-.928-.768-1.632-.768-.704 0-1.253.261-1.648.784-.384.512-.576 1.227-.576 2.144Zm10.835-4.896 2.256 7.072h1.376L57.12 54.2h-2.704l-2.96-9.008h2.56Zm4.144 10.864c-.245.8-.624 1.408-1.136 1.824-.501.416-1.125.624-1.872.624-.928 0-1.659-.256-2.192-.768-.523-.512-.832-1.259-.928-2.24h2.192c.117.32.245.544.384.672a.715.715 0 0 0 .528.208.623.623 0 0 0 .496-.224c.139-.139.261-.373.368-.704l2.848-10.256h2.368L58.16 56.056Z"/>
10
+ <path fill="#fff" fill-rule="evenodd" d="M81.437 91.746h10.957L73.606 72.945l7.83 18.802Zm-7.831-18.802v26.62l7.817-7.832" clip-rule="evenodd"/>
11
+ </g>
12
+ </g>
13
+ <defs>
14
+ <linearGradient id="c" x1="39.445" x2="39.445" y1="78.046" y2="22.535" gradientUnits="userSpaceOnUse">
15
+ <stop stop-color="#1D40B2"/>
16
+ <stop offset="1" stop-color="#1680D6"/>
17
+ </linearGradient>
18
+ <clipPath id="a">
19
+ <path fill="#fff" d="M0 0h266v100H0z"/>
20
+ </clipPath>
21
+ </defs>
22
+ </svg>