remove_bg 1.4.1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +298 -57
- data/.depfu.yml +21 -0
- data/.editorconfig +19 -0
- data/.gitignore +8 -8
- data/.grenrc.json +20 -0
- data/.rspec +5 -0
- data/.rubocop.yml +43 -0
- data/Appraisals +49 -10
- data/CHANGELOG.md +12 -0
- data/Gemfile +2 -5
- data/Gemfile.lock +132 -62
- data/LICENSE.md +25 -0
- data/README.md +93 -38
- data/Rakefile +4 -0
- data/SECURITY.md +36 -0
- data/gemfiles/faraday_2_0.gemfile +7 -0
- data/gemfiles/faraday_2_1.gemfile +7 -0
- data/gemfiles/faraday_2_2.gemfile +7 -0
- data/gemfiles/faraday_2_3.gemfile +7 -0
- data/gemfiles/faraday_2_4.gemfile +7 -0
- data/gemfiles/faraday_2_5.gemfile +7 -0
- data/gemfiles/faraday_2_6.gemfile +7 -0
- data/gemfiles/faraday_2_7.gemfile +7 -0
- data/gemfiles/faraday_2_8.gemfile +7 -0
- data/gemfiles/faraday_2_9.gemfile +7 -0
- data/gemfiles/faraday_2_x.gemfile +7 -0
- data/lib/remove_bg/account_info.rb +7 -1
- data/lib/remove_bg/api.rb +2 -0
- data/lib/remove_bg/api_client.rb +31 -12
- data/lib/remove_bg/base_request_options.rb +2 -0
- data/lib/remove_bg/composite_result.rb +29 -10
- data/lib/remove_bg/configuration.rb +16 -3
- data/lib/remove_bg/error.rb +12 -2
- data/lib/remove_bg/http_connection.rb +9 -4
- data/lib/remove_bg/image_composer.rb +28 -9
- data/lib/remove_bg/rate_limit_info.rb +9 -6
- data/lib/remove_bg/request_options.rb +32 -0
- data/lib/remove_bg/result.rb +29 -4
- data/lib/remove_bg/result_metadata.rb +2 -0
- data/lib/remove_bg/upload.rb +7 -5
- data/lib/remove_bg/url_validator.rb +4 -4
- data/lib/remove_bg/version.rb +3 -1
- data/lib/remove_bg.rb +19 -0
- data/remove_bg.gemspec +43 -16
- data/resources/removebgByCanva.svg +47 -0
- data/sonar-project.properties +22 -0
- data/tasks/version.rake +34 -0
- metadata +243 -63
- data/.env.test +0 -2
- data/LICENSE +0 -21
- data/gemfiles/faraday_0_15.gemfile +0 -11
- data/gemfiles/faraday_0_16.gemfile +0 -11
- data/gemfiles/faraday_0_17.gemfile +0 -11
- data/gemfiles/faraday_1_x.gemfile +0 -11
data/lib/remove_bg/api_client.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "json"
|
2
4
|
require "tempfile"
|
3
5
|
|
@@ -16,21 +18,40 @@ module RemoveBg
|
|
16
18
|
class ApiClient
|
17
19
|
include RemoveBg::Api
|
18
20
|
|
21
|
+
# @param connection [Faraday::Connection]
|
22
|
+
#
|
19
23
|
def initialize(connection: RemoveBg::HttpConnection.build)
|
20
24
|
@connection = connection
|
21
25
|
end
|
22
26
|
|
27
|
+
# Removes the background from an image on the local file system
|
28
|
+
# @param image_path [String]
|
29
|
+
# @param options [RemoveBg::RequestOptions]
|
30
|
+
# @return [RemoveBg::Result|RemoveBg::CompositeResult]
|
31
|
+
# @raise [RemoveBg::Error]
|
32
|
+
#
|
23
33
|
def remove_from_file(image_path, options)
|
24
34
|
data = options.data.merge(image_file: Upload.for_file(image_path))
|
25
35
|
request_remove_bg(data, options.api_key)
|
26
36
|
end
|
27
37
|
|
38
|
+
# Removes the background from the image at the URL specified
|
39
|
+
# @param image_url [String]
|
40
|
+
# @param options [RemoveBg::RequestOptions]
|
41
|
+
# @return [RemoveBg::Result|RemoveBg::CompositeResult]
|
42
|
+
# @raise [RemoveBg::Error]
|
43
|
+
#
|
28
44
|
def remove_from_url(image_url, options)
|
29
45
|
RemoveBg::UrlValidator.validate(image_url)
|
30
|
-
data = options.data.merge(image_url:
|
46
|
+
data = options.data.merge(image_url:)
|
31
47
|
request_remove_bg(data, options.api_key)
|
32
48
|
end
|
33
49
|
|
50
|
+
# Fetches account information
|
51
|
+
# @param options [RemoveBg::BaseRequestOptions]
|
52
|
+
# @return [RemoveBg::AccountInfo]
|
53
|
+
# @raise [RemoveBg::Error]
|
54
|
+
#
|
34
55
|
def account_info(options)
|
35
56
|
request_account_info(options.api_key)
|
36
57
|
end
|
@@ -51,26 +72,24 @@ module RemoveBg
|
|
51
72
|
# Faraday v0.16 & v1.0+ support streaming, v0.17 did not (rollback release)
|
52
73
|
if req.options.respond_to?(:on_data)
|
53
74
|
streaming = true
|
54
|
-
req.options.on_data =
|
75
|
+
req.options.on_data = proc do |chunk, _|
|
55
76
|
download.write(chunk)
|
56
77
|
end
|
57
78
|
end
|
58
79
|
end
|
59
80
|
|
60
|
-
# Faraday v0.
|
61
|
-
|
62
|
-
download.write(response.body)
|
63
|
-
end
|
81
|
+
# Faraday v0.17
|
82
|
+
download.write(response.body) unless streaming
|
64
83
|
|
65
84
|
download.rewind
|
66
85
|
|
67
86
|
if response.status == 200
|
68
|
-
parse_image_result(headers: response.headers, download:
|
87
|
+
parse_image_result(headers: response.headers, download:)
|
69
88
|
else
|
70
89
|
response_body = download.read
|
71
90
|
download.close
|
72
91
|
download.unlink
|
73
|
-
handle_http_error(response
|
92
|
+
handle_http_error(response:, body: response_body)
|
74
93
|
end
|
75
94
|
end
|
76
95
|
|
@@ -82,7 +101,7 @@ module RemoveBg
|
|
82
101
|
if response.status == 200
|
83
102
|
parse_account_result(response)
|
84
103
|
else
|
85
|
-
handle_http_error(response
|
104
|
+
handle_http_error(response:, body: response.body)
|
86
105
|
end
|
87
106
|
end
|
88
107
|
|
@@ -104,7 +123,7 @@ module RemoveBg
|
|
104
123
|
|
105
124
|
def parse_image_result(headers:, download:)
|
106
125
|
result_for_content_type(headers["Content-Type"]).new(
|
107
|
-
download
|
126
|
+
download:,
|
108
127
|
metadata: ResultMetadata.new(headers),
|
109
128
|
rate_limit: RateLimitInfo.new(headers)
|
110
129
|
)
|
@@ -120,8 +139,8 @@ module RemoveBg
|
|
120
139
|
|
121
140
|
def parse_account_result(response)
|
122
141
|
attributes = JSON.parse(response.body, symbolize_names: true)
|
123
|
-
|
124
|
-
|
142
|
+
.fetch(:data)
|
143
|
+
.fetch(:attributes)
|
125
144
|
|
126
145
|
RemoveBg::AccountInfo.new(attributes)
|
127
146
|
end
|
@@ -1,15 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative "result"
|
2
4
|
|
3
5
|
module RemoveBg
|
6
|
+
# Handles image composition for larger images (over 10MP) where transparency is
|
7
|
+
# required.
|
8
|
+
# @see RemoveBg::Result
|
9
|
+
#
|
4
10
|
class CompositeResult < Result
|
11
|
+
# Saves the ZIP archive containing the alpha.png and color.jpg files
|
12
|
+
# (useful if you want to handle composition yourself)
|
13
|
+
# @param file_path [string]
|
14
|
+
# @param overwrite [boolean] Overwrite any existing file at the specified path
|
15
|
+
# @return [nil]
|
16
|
+
#
|
5
17
|
def save_zip(file_path, overwrite: false)
|
6
|
-
if File.exist?(file_path) && !overwrite
|
7
|
-
|
8
|
-
|
18
|
+
raise FileOverwriteError.new(file_path) if File.exist?(file_path) && !overwrite
|
19
|
+
|
20
|
+
warn("DEPRECATION WARNING: overwrite: true is deprecated and will be removed from remove_bg 2.0 (use save_zip! instead)") if overwrite
|
9
21
|
|
10
22
|
FileUtils.cp(download, file_path)
|
11
23
|
end
|
12
24
|
|
25
|
+
# Saves the ZIP archive containing the alpha.png and color.jpg files, overwriting any exisiting files
|
26
|
+
# (useful if you want to handle composition yourself)
|
27
|
+
# @param file_path [string]
|
28
|
+
# @return [nil]
|
29
|
+
#
|
30
|
+
def save_zip!(file_path)
|
31
|
+
FileUtils.cp(download, file_path)
|
32
|
+
end
|
33
|
+
|
13
34
|
private
|
14
35
|
|
15
36
|
def image_file
|
@@ -17,10 +38,8 @@ module RemoveBg
|
|
17
38
|
end
|
18
39
|
|
19
40
|
def composite_file
|
20
|
-
@composite_file ||=
|
21
|
-
|
22
|
-
.tap { |file| compose_to_file(file) }
|
23
|
-
end
|
41
|
+
@composite_file ||= binary_tempfile(["composed", ".png"])
|
42
|
+
.tap { |file| compose_to_file(file) }
|
24
43
|
end
|
25
44
|
|
26
45
|
def color_file
|
@@ -35,8 +54,8 @@ module RemoveBg
|
|
35
54
|
extract_parts
|
36
55
|
|
37
56
|
ImageComposer.new.compose(
|
38
|
-
color_file
|
39
|
-
alpha_file
|
57
|
+
color_file:,
|
58
|
+
alpha_file:,
|
40
59
|
destination_path: destination.path
|
41
60
|
)
|
42
61
|
end
|
@@ -49,7 +68,7 @@ module RemoveBg
|
|
49
68
|
end
|
50
69
|
|
51
70
|
def binary_tempfile(basename)
|
52
|
-
Tempfile.new(basename).tap
|
71
|
+
Tempfile.new(basename).tap(&:binmode)
|
53
72
|
end
|
54
73
|
end
|
55
74
|
end
|
@@ -1,13 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "image_composer"
|
4
|
+
|
1
5
|
module RemoveBg
|
2
6
|
class Configuration
|
3
|
-
attr_accessor :api_key, :image_processor
|
7
|
+
attr_accessor :api_key, :image_processor, :auto_upgrade_png_to_zip
|
4
8
|
|
5
9
|
def self.configuration
|
6
|
-
@configuration ||= Configuration.new
|
10
|
+
@configuration ||= Configuration.new.tap do |config|
|
11
|
+
config.image_processor = ImageComposer.detect_image_processor
|
12
|
+
|
13
|
+
# Upgrade to ZIP where possible to save bandwith
|
14
|
+
config.auto_upgrade_png_to_zip = true
|
15
|
+
end
|
7
16
|
end
|
8
17
|
|
9
18
|
def self.reset
|
10
|
-
@configuration =
|
19
|
+
@configuration = nil
|
20
|
+
end
|
21
|
+
|
22
|
+
def can_process_images?
|
23
|
+
!image_processor.nil?
|
11
24
|
end
|
12
25
|
end
|
13
26
|
end
|
data/lib/remove_bg/error.rb
CHANGED
@@ -1,8 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RemoveBg
|
2
4
|
class Error < StandardError; end
|
3
5
|
|
4
6
|
class HttpError < Error
|
5
|
-
|
7
|
+
# @return [Faraday::Response]
|
8
|
+
attr_reader :http_response
|
9
|
+
|
10
|
+
# @return [String]
|
11
|
+
attr_reader :http_response_body
|
6
12
|
|
7
13
|
def initialize(message, http_response, http_response_body)
|
8
14
|
@http_response = http_response
|
@@ -11,9 +17,13 @@ module RemoveBg
|
|
11
17
|
end
|
12
18
|
end
|
13
19
|
|
20
|
+
# Raised for all HTTP 4XX errors
|
14
21
|
class ClientHttpError < HttpError; end
|
22
|
+
|
23
|
+
# Raised for all HTTP 5XX errors
|
15
24
|
class ServerHttpError < HttpError; end
|
16
25
|
|
26
|
+
# Raised for HTTP 429 status code
|
17
27
|
class RateLimitError < ClientHttpError
|
18
28
|
attr_reader :rate_limit
|
19
29
|
|
@@ -40,7 +50,7 @@ module RemoveBg
|
|
40
50
|
|
41
51
|
class FileOverwriteError < FileError
|
42
52
|
def initialize(file_path)
|
43
|
-
super("The file already exists: '#{file_path}' (
|
53
|
+
super("The file already exists: '#{file_path}' (use #save! or #save_zip! to overwrite existing files)", file_path)
|
44
54
|
end
|
45
55
|
end
|
46
56
|
|
@@ -1,21 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "faraday"
|
4
|
+
require "faraday/retry"
|
5
|
+
|
2
6
|
require_relative "api"
|
3
7
|
require_relative "version"
|
4
8
|
|
5
9
|
module RemoveBg
|
6
10
|
class HttpConnection
|
7
|
-
USER_AGENT = "remove-bg-ruby-#{RemoveBg::VERSION}"
|
8
|
-
HTTP_BASE_TIMEOUT =
|
11
|
+
USER_AGENT = "remove-bg-ruby-#{RemoveBg::VERSION}".freeze
|
12
|
+
HTTP_BASE_TIMEOUT = 20
|
9
13
|
HTTP_WRITE_TIMEOUT = 120
|
10
14
|
|
15
|
+
# @return [Faraday::Connection]
|
16
|
+
#
|
11
17
|
def self.build(api_url = RemoveBg::Api::URL)
|
12
18
|
retry_options = {
|
13
19
|
max: 2,
|
14
20
|
interval: 0.2,
|
15
21
|
backoff_factor: 2,
|
16
22
|
methods: [:post],
|
17
|
-
exceptions: Faraday::
|
18
|
-
[Faraday::ConnectionFailed]
|
23
|
+
exceptions: Faraday::Retry::Middleware::DEFAULT_EXCEPTIONS + [Faraday::ConnectionFailed],
|
19
24
|
}
|
20
25
|
|
21
26
|
request_options = Faraday::RequestOptions.new.tap do |req_options|
|
@@ -1,18 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative "error"
|
2
4
|
|
3
5
|
module RemoveBg
|
6
|
+
# Combines alpha.png and color.jpg files to produce a full-sized transparent PNG.
|
7
|
+
# An image processing library (ImageMagick, GraphicsMagick, or libvips) must
|
8
|
+
# be available on the system.
|
9
|
+
# @see RemoveBg::CompositeResult
|
10
|
+
#
|
4
11
|
class ImageComposer
|
12
|
+
DEFAULT_BINARY_DETECTOR = lambda do |binary_name|
|
13
|
+
system("which", binary_name, out: File::NULL)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.detect_image_processor(detector: DEFAULT_BINARY_DETECTOR)
|
17
|
+
if detector.call("magick") || detector.call("convert") || detector.call("gm")
|
18
|
+
:minimagick
|
19
|
+
elsif detector.call("vips")
|
20
|
+
:vips
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
5
24
|
def compose(color_file:, alpha_file:, destination_path:)
|
6
25
|
image = case configured_image_processor
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
26
|
+
when :vips
|
27
|
+
vips_compose(color_file:, alpha_file:)
|
28
|
+
when :minimagick
|
29
|
+
minimagick_compose(color_file:, alpha_file:)
|
30
|
+
when nil
|
31
|
+
raise RemoveBg::Error, "Please configure an image processor to use image composition"
|
32
|
+
else
|
33
|
+
raise RemoveBg::Error, "Unsupported image processor: #{configured_image_processor.inspect}"
|
34
|
+
end
|
16
35
|
|
17
36
|
image.call(destination: destination_path)
|
18
37
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "time"
|
2
4
|
|
3
5
|
module RemoveBg
|
@@ -15,16 +17,17 @@ module RemoveBg
|
|
15
17
|
|
16
18
|
def reset_at
|
17
19
|
return if reset_timestamp.nil?
|
20
|
+
|
18
21
|
Time.at(reset_timestamp).utc
|
19
22
|
end
|
20
23
|
|
21
24
|
def to_s
|
22
|
-
"<RateLimit"\
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
"<RateLimit " \
|
26
|
+
"reset_at='#{reset_at.iso8601}' " \
|
27
|
+
"retry_after_seconds=#{retry_after_seconds} " \
|
28
|
+
"total=#{total} " \
|
29
|
+
"remaining=#{remaining}" \
|
30
|
+
">"
|
28
31
|
end
|
29
32
|
|
30
33
|
private
|
@@ -1,6 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative "base_request_options"
|
2
4
|
|
3
5
|
module RemoveBg
|
6
|
+
# Options for image processing requests. Arbitary options are passed directly to the API.
|
7
|
+
#
|
4
8
|
class RequestOptions < BaseRequestOptions
|
5
9
|
SIZE_REGULAR = "regular"
|
6
10
|
SIZE_MEDIUM = "medium"
|
@@ -15,10 +19,38 @@ module RemoveBg
|
|
15
19
|
CHANNELS_RGBA = "rgba"
|
16
20
|
CHANNELS_ALPHA = "alpha"
|
17
21
|
|
22
|
+
FORMAT_PNG = "png"
|
23
|
+
FORMAT_ZIP = "zip"
|
24
|
+
FORMAT_JPG = "jpg"
|
25
|
+
|
18
26
|
def initialize(raw_options = {})
|
19
27
|
options = raw_options.dup
|
20
28
|
options[:size] ||= SIZE_AUTO
|
29
|
+
|
30
|
+
options[:format] = optimize_format(options[:format]) if options.key?(:format)
|
31
|
+
|
21
32
|
super(options)
|
22
33
|
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
# Save bandwidth where possible
|
38
|
+
def optimize_format(requested_format)
|
39
|
+
requested_png = requested_format.to_s.casecmp?(FORMAT_PNG)
|
40
|
+
|
41
|
+
if requested_png && optimization_enabled? && can_process_images?
|
42
|
+
FORMAT_ZIP
|
43
|
+
else
|
44
|
+
requested_format
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def can_process_images?
|
49
|
+
RemoveBg::Configuration.configuration.can_process_images?
|
50
|
+
end
|
51
|
+
|
52
|
+
def optimization_enabled?
|
53
|
+
RemoveBg::Configuration.configuration.auto_upgrade_png_to_zip
|
54
|
+
end
|
23
55
|
end
|
24
56
|
end
|
data/lib/remove_bg/result.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "fileutils"
|
2
4
|
require "forwardable"
|
3
5
|
require "zip"
|
@@ -5,10 +7,17 @@ require_relative "error"
|
|
5
7
|
require_relative "image_composer"
|
6
8
|
|
7
9
|
module RemoveBg
|
10
|
+
# Provides convenience methods to save the processed image, read the image data,
|
11
|
+
# and access metadata such as the image height/width and credits charged.
|
12
|
+
#
|
8
13
|
class Result
|
9
14
|
extend ::Forwardable
|
10
15
|
|
11
|
-
|
16
|
+
# @return [RemoveBg::ResultMetadata]
|
17
|
+
attr_reader :metadata
|
18
|
+
|
19
|
+
# @return [RemoveBg::RateLimitInfo]
|
20
|
+
attr_reader :rate_limit
|
12
21
|
|
13
22
|
def_delegators :metadata, :type, :width, :height, :credits_charged
|
14
23
|
|
@@ -18,14 +27,30 @@ module RemoveBg
|
|
18
27
|
@rate_limit = rate_limit
|
19
28
|
end
|
20
29
|
|
30
|
+
# Saves the processed image to the path specified
|
31
|
+
# @param file_path [string]
|
32
|
+
# @param overwrite [boolean] Overwrite any existing file at the specified path
|
33
|
+
# @return [nil]
|
34
|
+
#
|
21
35
|
def save(file_path, overwrite: false)
|
22
|
-
if File.exist?(file_path) && !overwrite
|
23
|
-
|
24
|
-
|
36
|
+
raise FileOverwriteError.new(file_path) if File.exist?(file_path) && !overwrite
|
37
|
+
|
38
|
+
warn("DEPRECATION WARNING: overwrite: true is deprecated and will be removed from remove_bg 2.0 (use save! instead)") if overwrite
|
39
|
+
|
40
|
+
FileUtils.cp(image_file, file_path)
|
41
|
+
end
|
25
42
|
|
43
|
+
# Saves the processed image to the path specified, overwriting any existing file at the specified path
|
44
|
+
# @param file_path [string]
|
45
|
+
# @return [nil]
|
46
|
+
#
|
47
|
+
def save!(file_path)
|
26
48
|
FileUtils.cp(image_file, file_path)
|
27
49
|
end
|
28
50
|
|
51
|
+
# Returns the binary data of the processed image
|
52
|
+
# @return [String]
|
53
|
+
#
|
29
54
|
def data
|
30
55
|
image_file.rewind
|
31
56
|
image_file.read
|
data/lib/remove_bg/upload.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "faraday"
|
4
|
+
require "faraday/multipart"
|
2
5
|
require_relative "error"
|
3
6
|
|
4
7
|
module RemoveBg
|
5
8
|
class Upload
|
6
9
|
def self.for_file(file_path)
|
7
|
-
|
8
|
-
raise RemoveBg::FileMissingError.new(file_path)
|
9
|
-
end
|
10
|
+
raise RemoveBg::FileMissingError.new(file_path) unless File.exist?(file_path)
|
10
11
|
|
11
12
|
content_type = determine_content_type(file_path)
|
12
13
|
FARADAY_FILE.new(file_path, content_type)
|
@@ -23,8 +24,9 @@ module RemoveBg
|
|
23
24
|
|
24
25
|
private_class_method :determine_content_type
|
25
26
|
|
26
|
-
|
27
|
-
FARADAY_FILE =
|
27
|
+
FARADAY_FILE = File
|
28
|
+
FARADAY_FILE = Faraday::Multipart::FilePart if defined?(Faraday::Multipart::FilePart)
|
29
|
+
|
28
30
|
private_constant :FARADAY_FILE
|
29
31
|
end
|
30
32
|
end
|
@@ -1,16 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "uri"
|
2
4
|
require_relative "error"
|
3
5
|
|
4
6
|
module RemoveBg
|
5
7
|
class UrlValidator
|
6
|
-
PERMITTED_SCHEMES = [
|
8
|
+
PERMITTED_SCHEMES = %w[http https].freeze
|
7
9
|
|
8
10
|
def self.validate(url)
|
9
11
|
parsed = URI.parse(url)
|
10
12
|
|
11
|
-
unless parsed.absolute? && PERMITTED_SCHEMES.include?(parsed.scheme)
|
12
|
-
raise RemoveBg::InvalidUrlError.new(url)
|
13
|
-
end
|
13
|
+
raise RemoveBg::InvalidUrlError.new(url) unless parsed.absolute? && PERMITTED_SCHEMES.include?(parsed.scheme)
|
14
14
|
rescue URI::InvalidURIError
|
15
15
|
raise RemoveBg::InvalidUrlError.new(url)
|
16
16
|
end
|
data/lib/remove_bg/version.rb
CHANGED
data/lib/remove_bg.rb
CHANGED
@@ -1,24 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "remove_bg/version"
|
2
4
|
require "remove_bg/api_client"
|
3
5
|
require "remove_bg/configuration"
|
4
6
|
require "remove_bg/request_options"
|
5
7
|
|
6
8
|
module RemoveBg
|
9
|
+
# Removes the background from an image on the local file system
|
10
|
+
# @param image_path [String] Path to the input image
|
11
|
+
# @param options [Hash<Symbol, Object>] Image processing options (see API docs)
|
12
|
+
# @return [RemoveBg::Result|RemoveBg::CompositeResult] a processed image result
|
13
|
+
#
|
7
14
|
def self.from_file(image_path, raw_options = {})
|
8
15
|
options = RemoveBg::RequestOptions.new(raw_options)
|
9
16
|
ApiClient.new.remove_from_file(image_path, options)
|
10
17
|
end
|
11
18
|
|
19
|
+
# Removes the background from the image at the URL specified
|
20
|
+
# @param image_url [String] Absolute URL of the input image
|
21
|
+
# @param options [Hash<Symbol, Object>] Image processing options (see API docs)
|
22
|
+
# @return [RemoveBg::Result|RemoveBg::CompositeResult] A processed image result
|
23
|
+
#
|
12
24
|
def self.from_url(image_url, raw_options = {})
|
13
25
|
options = RemoveBg::RequestOptions.new(raw_options)
|
14
26
|
ApiClient.new.remove_from_url(image_url, options)
|
15
27
|
end
|
16
28
|
|
29
|
+
# Fetches account information for the globally configured API key, or a
|
30
|
+
# specific API key if provided
|
31
|
+
# @param options [Hash<Symbol, Object>]
|
32
|
+
# @return [RemoveBg::AccountInfo]
|
33
|
+
#
|
17
34
|
def self.account_info(raw_options = {})
|
18
35
|
options = RemoveBg::BaseRequestOptions.new(raw_options)
|
19
36
|
ApiClient.new.account_info(options)
|
20
37
|
end
|
21
38
|
|
39
|
+
# Yields the global Remove.bg configuration
|
40
|
+
# @yield [RemoveBg::Configuration]
|
22
41
|
def self.configure
|
23
42
|
yield RemoveBg::Configuration.configuration
|
24
43
|
end
|
data/remove_bg.gemspec
CHANGED
@@ -1,39 +1,66 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path("lib", __dir__)
|
2
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
5
|
require "remove_bg/version"
|
4
6
|
|
5
7
|
Gem::Specification.new do |spec|
|
6
8
|
spec.name = "remove_bg"
|
7
9
|
spec.version = RemoveBg::VERSION
|
8
|
-
spec.authors = ["
|
9
|
-
spec.email = ["
|
10
|
+
spec.authors = ["Canva Austria GmbH"]
|
11
|
+
spec.email = ["ops@kaleido.ai"]
|
12
|
+
|
13
|
+
spec.platform = Gem::Platform::RUBY
|
10
14
|
|
11
15
|
spec.summary = "Remove image background - 100% automatically"
|
16
|
+
spec.description = "Use remove.bg with our official Ruby library to quickly, easily and 100% automatically remove the background from images."
|
12
17
|
spec.homepage = "https://www.remove.bg/"
|
13
18
|
spec.license = "MIT"
|
14
|
-
spec.metadata
|
15
|
-
|
19
|
+
spec.metadata = {
|
20
|
+
"bug_tracker_uri" => "https://github.com/remove-bg/ruby/issues",
|
21
|
+
"source_code_uri" => "https://github.com/remove-bg/ruby",
|
22
|
+
"changelog_uri" => "https://github.com/remove-bg/ruby/blob/main/CHANGELOG.md",
|
23
|
+
"allowed_push_host" => "https://rubygems.org",
|
24
|
+
"rubygems_mfa_required" => "true",
|
25
|
+
}
|
26
|
+
|
27
|
+
# Require at least Ruby 3.1
|
28
|
+
spec.required_ruby_version = ">= 3.1"
|
16
29
|
|
17
30
|
# Specify which files should be added to the gem when it is released.
|
18
31
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
19
|
-
spec.files = Dir.chdir(File.expand_path(
|
32
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
20
33
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|examples)/}) }
|
21
34
|
end
|
22
35
|
spec.bindir = "exe"
|
23
36
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
24
37
|
spec.require_paths = ["lib"]
|
25
38
|
|
26
|
-
spec.add_dependency "faraday", ">=
|
27
|
-
spec.add_dependency "
|
39
|
+
spec.add_dependency "faraday", ">= 2", "<= 3"
|
40
|
+
spec.add_dependency "faraday-multipart", "~> 1.0"
|
41
|
+
spec.add_dependency "faraday-retry", "~> 2.2"
|
42
|
+
|
43
|
+
spec.add_dependency "image_processing", "~> 1.12"
|
28
44
|
spec.add_dependency "rubyzip", ">= 2.0", "< 3"
|
29
45
|
|
46
|
+
spec.add_development_dependency "appraisal", "~> 2.5"
|
47
|
+
|
30
48
|
spec.add_development_dependency "bundler", "~> 2.0"
|
31
|
-
spec.add_development_dependency "
|
32
|
-
spec.add_development_dependency "
|
33
|
-
spec.add_development_dependency "
|
34
|
-
spec.add_development_dependency "rspec_junit_formatter"
|
35
|
-
spec.add_development_dependency "rspec-
|
36
|
-
spec.add_development_dependency "rspec", "~> 3
|
37
|
-
spec.add_development_dependency "
|
38
|
-
spec.add_development_dependency "
|
49
|
+
spec.add_development_dependency "pry", "~> 0.14"
|
50
|
+
spec.add_development_dependency "rake", "~> 13.2"
|
51
|
+
spec.add_development_dependency "rspec", "~> 3.13"
|
52
|
+
spec.add_development_dependency "rspec_junit_formatter", "~> 0.6"
|
53
|
+
spec.add_development_dependency "rspec-sonarqube-formatter", "~> 1.5"
|
54
|
+
spec.add_development_dependency "rspec-with_params", "~> 0.3"
|
55
|
+
spec.add_development_dependency "rubocop", "~> 1.64"
|
56
|
+
spec.add_development_dependency "rubocop-performance", "~> 1.21"
|
57
|
+
spec.add_development_dependency "rubocop-rake", "~> 0.6"
|
58
|
+
spec.add_development_dependency "rubocop-rspec", "~> 3.0"
|
59
|
+
spec.add_development_dependency "simplecov", "~> 0.22"
|
60
|
+
spec.add_development_dependency "simplecov-cobertura", "~> 2.1"
|
61
|
+
spec.add_development_dependency "simplecov_json_formatter", "~> 0.1"
|
62
|
+
spec.add_development_dependency "vcr", "~> 6.2"
|
63
|
+
spec.add_development_dependency "vcr_better_binary", "~> 0.2"
|
64
|
+
spec.add_development_dependency "webmock", "~> 3.23"
|
65
|
+
spec.add_development_dependency "yard", "~> 0.9"
|
39
66
|
end
|