active_analysis 0.1.2 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2264c818bb6bbdf31ecde9797cbeb77edf1f42b52d3b7f3f0178fbf47fec2ef8
4
- data.tar.gz: 8cf368194ab3226945d275fea222685b346c6c6821dddde0ad9ddcdea40ca445
3
+ metadata.gz: d9bd54c9d6b6579f5419244bdce0170c10889efc633d363b2a9be8129335b0bf
4
+ data.tar.gz: bea8aa7a1e0f5c8d716c6d9eb2c3d253f5a1be3cb461484c16b5e281f47cd6bd
5
5
  SHA512:
6
- metadata.gz: e9381a23b549ef234a7d4e13aa04460b99d6365b1f82f6cd3359d8d4b31e72d7be3664ee64536ff73429353c83122f5a0f113b64ebd104c530f1721cb1ed363e
7
- data.tar.gz: c9f3f4ce840c7b1cfae253459f09af28163672fff60c1d0643f45f256d3b08d4689752de359d47923e883c1e43abb9a6e33a91c8089ea27a26b7e95a72dc5710
6
+ metadata.gz: 402b15df181ac8bc2f583e70d9f856d7b7a9271493883a5ee9b7998aa890cb15c771f68e5be12028b4bfca29bf2514886fd09d841106cba88bed50975067dedb
7
+ data.tar.gz: f35aa5ac09d2f3294512541733f38d5fa649c82994c685d26d92f9dd94f6f6e15a83fda66affae7553b7028fb1878542586242d524124f8afa6a8d226052e52a
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  ## [Unreleased]
2
2
 
3
- ## [0.1.0] - 2021-05-01
3
+ ## [0.3] - 2021-06-17
4
+
5
+ - Added addons feature
6
+
7
+ ## [0.2] - 2021-06-01
8
+
9
+ - Added `opaque` metadata value to images
10
+
11
+ ## [0.1.3] - 2021-05-01
4
12
 
5
13
  - Initial release
data/README.md CHANGED
@@ -18,11 +18,62 @@ And then execute:
18
18
 
19
19
  ## Usage
20
20
 
21
- Active Analyzers will automatically add all its analyzers to Active Storage's analyzers array. Don't worry, if you added any custom analyzers they will be there. You can check the comments in the source code of each analyzer to see what information they extract from files:
22
- - Audio: [source](https://github.com/FestaLab/active_analysis/blob/main/lib/active_analysis/analyzer/audio_analyzer.rb)
23
- - Image: [source](https://github.com/FestaLab/active_analysis/blob/main/lib/active_analysis/analyzer/image_analyzer.rb)
24
- - PDF: [source](https://github.com/FestaLab/active_analysis/blob/main/lib/active_analysis/analyzer/pdf_analyzer.rb)
25
- - Video: [source](https://github.com/FestaLab/active_analysis/blob/main/lib/active_analysis/analyzer/video_analyzer.rb)
21
+ Active Analysis automatically replaces all of Rails default analyzers with its own. It will not remove other custom analyzers if you have them. You can also configure which analyzers will be inserted.
22
+
23
+ ```ruby
24
+ Rails.application.configure do |config|
25
+ config.active_analysis.image_library = :vips # Defaults to the same as active storage
26
+ config.active_analysis.image_analyzer = true # Defaults to true
27
+ config.active_analysis.audio_analyzer = true # Defaults to true
28
+ config.active_analysis.pdf_analyzer = false # Defaults to true
29
+ config.active_analysis.video_analyzer = false # Defaults to true
30
+ end
31
+ ```
32
+
33
+ #### Image
34
+ A modification of the original image analyzer and a new analyzer. Requires the [ImageMagick](http://www.imagemagick.org) system library or the [libvips](https://github.com/libvips/libvips) system library.
35
+
36
+ - Width (pixels)
37
+ - Height (pixels)
38
+ - Opaque (true if file is opaque, false if not)
39
+
40
+ An image will be considered opaque if it does not have an alpha channel, or if none of its pixels have an alpha value below the minimum (as defined by the library).
41
+
42
+ #### PDF
43
+ A new analyzer. Requires the [poppler](https://poppler.freedesktop.org/) system library.
44
+
45
+ - Width (pixels)
46
+ - Height (pixels)
47
+ - Pages
48
+
49
+ #### Audio
50
+ A new analyzer. Requires the [FFmpeg](https://www.ffmpeg.org) system library.
51
+
52
+ - Duration (seconds)
53
+ - Bit Rate (bits/second)
54
+
55
+ #### Video
56
+ A modification of the original video analyzer. Requires the [FFmpeg](https://www.ffmpeg.org) system library
57
+
58
+ - Width (pixels)
59
+ - Height (pixels)
60
+ - Duration (seconds)
61
+ - Angle (degrees)
62
+ - Display aspect ratio
63
+ - Audio (true if file has an audio channel, false if not)
64
+ - Video (true if file has an video channel, false if not)
65
+
66
+ ## Addons
67
+ Active Analysis allows additional features to be added to the image analyzers through addons. To create an addon simply inherit the `Addon` class and add it to the addons array in the configuration.
68
+ ```ruby
69
+ Rails.application.configure do |config|
70
+ config.active_analysis.addons << ActiveAnalysis::Addon::ImageAddon::OptimalQuality
71
+ end
72
+ ```
73
+
74
+ The following addons available:
75
+ - ImageAddon::OptimalQuality: An EXPERIMENTAL addon that calculates the optimal image quality using a DSSIM of 0.001. This addon is SLOOOOOOW.
76
+ - ImageAddon::WhiteBackground: An EXPERIMENTAL addon that checks if the image has a white background. Requires both vips and image magick to be installed.
26
77
 
27
78
  ## Development
28
79
 
@@ -7,6 +7,12 @@ module ActiveAnalysis
7
7
  autoload :FixtureSet
8
8
 
9
9
  mattr_accessor :logger
10
- mattr_accessor :analyzers
10
+
11
11
  mattr_accessor :image_library
12
+ mattr_accessor :image_analyzer
13
+ mattr_accessor :audio_analyzer
14
+ mattr_accessor :pdf_analyzer
15
+ mattr_accessor :video_analyzer
16
+
17
+ mattr_accessor :addons
12
18
  end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveAnalysis
4
+ # This is an abstract base class for analyzer addons, which extract extra metadata from blobs.
5
+ class Addon
6
+ attr_reader :file
7
+
8
+ def self.accept?(blob)
9
+ false
10
+ end
11
+
12
+ def initialize(file)
13
+ @file = file
14
+ end
15
+
16
+ def metadata
17
+ raise NotImplementedError
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../addon"
4
+
5
+ module ActiveAnalysis
6
+ # This is an abstract base class for image addons
7
+ class Addon::ImageAddon < Addon
8
+ def self.accept?(blob)
9
+ blob.image?
10
+ end
11
+
12
+ def metadata
13
+ raise NotImplementedError
14
+ end
15
+ end
16
+ end
17
+
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../image_addon"
4
+
5
+ module ActiveAnalysis
6
+ class Addon::ImageAddon::OptimalQuality < Addon::ImageAddon
7
+ def metadata
8
+ { optimal_quality: calculate_optimal_quality }
9
+ end
10
+
11
+ private
12
+ def calculate_optimal_quality
13
+ quality = 85
14
+
15
+ loop do
16
+ new_quality = quality - 5
17
+ dssim = calculate_dssim(new_quality)
18
+ break if dssim > 0.001 || quality < 55
19
+ quality = new_quality
20
+ end
21
+
22
+ quality
23
+ rescue
24
+ nil
25
+ end
26
+
27
+ def calculate_dssim(quality)
28
+ image_with_quality(quality) do |image|
29
+ dssim = `dssim #{filepath} #{image.path}`
30
+ Float dssim.split.first
31
+ end
32
+ end
33
+
34
+ def image_with_quality(quality)
35
+ extname = File.extname(filepath)
36
+ basename = File.basename(filepath, extname)
37
+
38
+ Tempfile.create(["#{basename}_#{quality}", extname]) do |tempfile|
39
+ processor.apply(saver: { format: "jpg", quality: quality }).call(filepath, destination: tempfile.path)
40
+ yield tempfile
41
+ end
42
+ end
43
+
44
+ def filepath
45
+ ActiveAnalysis.image_library == :vips ? file.filename : file.path
46
+ end
47
+
48
+ def processor
49
+ ActiveAnalysis.image_library == :vips ? ::ImageProcessing::Vips : ::ImageProcessing::MiniMagick
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../image_addon"
4
+
5
+ module ActiveAnalysis
6
+ class Addon::ImageAddon::WhiteBackground < Addon::ImageAddon
7
+ def metadata
8
+ { white_background: white_background? }
9
+ end
10
+
11
+ private
12
+ def white_background?
13
+ corners = extract_corner_areas(file)
14
+ colors = corners.map { |corner| primary_color_for(corner) }
15
+ colors.all? { |color| color.all? { |value| value > 250 } }
16
+ rescue
17
+ nil
18
+ end
19
+
20
+ def extract_corner_areas(image)
21
+ paths = []
22
+
23
+ image_path = ActiveAnalysis.image_analyzer == :vips ? image.filename : image.path
24
+ basename = SecureRandom.urlsafe_base64
25
+ width = image.width
26
+ height = image.height
27
+ size = 8
28
+
29
+ paths << Rails.root.join("tmp", "#{basename}_top_left.jpg")
30
+ `vips im_extract_area #{image_path} #{paths.last} 0 0 #{size} #{size}`
31
+
32
+ paths << Rails.root.join("tmp", "#{basename}_top_right.jpg")
33
+ `vips im_extract_area #{image_path} #{paths.last} #{width - size} 0 #{size} #{size}`
34
+
35
+ paths << Rails.root.join("tmp", "#{basename}_bottom_right.jpg")
36
+ `vips im_extract_area #{image_path} #{paths.last} #{width - size} #{height - size} #{size} #{size}`
37
+
38
+ paths << Rails.root.join("tmp", "#{basename}_bottom_left.jpg")
39
+ `vips im_extract_area #{image_path} #{paths.last} 0 #{height - size} #{size} #{size}`
40
+
41
+ paths
42
+ end
43
+
44
+ def primary_color_for(filepath)
45
+ histogram = generate_color_histogram(filepath)
46
+ sorted = sort_by_frequency(histogram)
47
+ extract_dominant_rgb(sorted)
48
+ end
49
+
50
+ def generate_color_histogram(path)
51
+ `convert #{path} +dither -colors 5 -define histogram:unique-colors=true -format "%c" histogram:info:`
52
+ end
53
+
54
+ def sort_by_frequency(histogram)
55
+ histogram.each_line.map { |line| parts = line.split(":"); [parts[0].to_i, parts[1]] }.sort_by { |line| line[0] }.reverse
56
+ end
57
+
58
+ def extract_dominant_rgb(array)
59
+ array.map { |line| line[1].match(/\(([\d.,]+)/).captures.first.split(",").take(3).map(&:to_i) }.first
60
+ end
61
+ end
62
+ end
63
+
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "../analyzer"
4
+
3
5
  module ActiveAnalysis
4
6
  # Extracts duration (seconds) and bit_rate (bits/s) from an audio blob.
5
7
  #
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "../analyzer"
4
+
3
5
  module ActiveAnalysis
4
6
  # This is an abstract base class for image analyzers, which extract width and height from an image blob.
5
7
  #
@@ -7,7 +9,7 @@ module ActiveAnalysis
7
9
  #
8
10
  # Example:
9
11
  #
10
- # ActiveAnalysis::CoreExtensionsAnalyzer::ImageAnalyzer::ImageMagick.new(blob).metadata
12
+ # ActiveAnalysis::Analyzer::ImageAnalyzer::ImageMagick.new(blob).metadata
11
13
  # # => { width: 4104, height: 2736 }
12
14
  class Analyzer::ImageAnalyzer < Analyzer
13
15
  def self.accept?(blob)
@@ -17,12 +19,29 @@ module ActiveAnalysis
17
19
  def metadata
18
20
  read_image do |image|
19
21
  if rotated_image?(image)
20
- { width: image.height, height: image.width }
22
+ { width: image.height, height: image.width, opaque: opaque?(image), **addons(image) }.compact
21
23
  else
22
- { width: image.width, height: image.height }
24
+ { width: image.width, height: image.height, opaque: opaque?(image), **addons(image) }.compact
23
25
  end
24
26
  end
25
27
  end
28
+
29
+ private
30
+ def read_image
31
+ raise NotImplementedError
32
+ end
33
+
34
+ def rotated_image?(image)
35
+ raise NotImplementedError
36
+ end
37
+
38
+ def opaque?(image)
39
+ raise NotImplementedError
40
+ end
41
+
42
+ def addons(image)
43
+ ActiveAnalysis.addons.select { |addon| addon.accept?(blob) }.map { |addon_class| addon_class.new(image).metadata }.reduce({}, :merge).compact
44
+ end
26
45
  end
27
46
  end
28
47
 
@@ -1,11 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "../image_analyzer"
4
+
3
5
  module ActiveAnalysis
4
6
  # This analyzer relies on the third-party {MiniMagick}[https://github.com/minimagick/minimagick] gem. MiniMagick requires
5
7
  # the {ImageMagick}[http://www.imagemagick.org] system library.
6
8
  class Analyzer::ImageAnalyzer::ImageMagick < Analyzer::ImageAnalyzer
7
9
  def self.accept?(blob)
8
- super && ActiveStorage.variant_processor == :mini_magick
10
+ super && ActiveAnalysis.image_library == :mini_magick
9
11
  end
10
12
 
11
13
  private
@@ -32,6 +34,13 @@ module ActiveAnalysis
32
34
  def rotated_image?(image)
33
35
  %w[ RightTop LeftBottom TopRight BottomLeft ].include?(image["%[orientation]"])
34
36
  end
37
+
38
+ def opaque?(image)
39
+ return true unless image.data["channelDepth"].key?("alpha")
40
+
41
+ value = image.data["version"] =~ /7.\d/ ? 255 : 0
42
+ image.data["channelStatistics"]["alpha"]["mean"] == value
43
+ end
35
44
  end
36
45
  end
37
46
 
@@ -1,18 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "../image_analyzer"
4
+
3
5
  module ActiveAnalysis
4
6
  # This analyzer relies on the third-party {ruby-vips}[https://github.com/libvips/ruby-vips] gem. Ruby-vips requires
5
7
  # the {libvips}[https://libvips.github.io/libvips/] system library.
6
8
  class Analyzer::ImageAnalyzer::Vips < Analyzer::ImageAnalyzer
7
9
  def self.accept?(blob)
8
- super && ActiveStorage.variant_processor == :vips
10
+ super && ActiveAnalysis.image_library == :vips
9
11
  end
10
12
 
11
13
  private
12
14
  def read_image
13
15
  download_blob_to_tempfile do |file|
14
16
  require "ruby-vips"
15
- image = ::Vips::Image.new_from_file(file.path, access: :sequential)
17
+ image = ::Vips::Image.new_from_file(file.path)
16
18
 
17
19
  if valid_image?(image)
18
20
  yield image
@@ -37,6 +39,11 @@ module ActiveAnalysis
37
39
  false
38
40
  end
39
41
 
42
+ def opaque?(image)
43
+ return true unless image.has_alpha?
44
+ image[image.bands - 1].min == 255
45
+ end
46
+
40
47
  def valid_image?(image)
41
48
  image.avg
42
49
  true
@@ -45,4 +52,3 @@ module ActiveAnalysis
45
52
  end
46
53
  end
47
54
  end
48
-
@@ -1,11 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "../analyzer"
4
+
3
5
  module ActiveAnalysis
4
6
  # Extracts width, height in pixels and number of pages from a pdf blob.
5
7
  #
6
8
  # Example:
7
9
  #
8
- # ActiveAnalysis::CoreExtensionsAnalyzer::PDFAnalyzer::Poppler.new(blob).metadata
10
+ # ActiveAnalysis::Analyzer::PDFAnalyzer::Poppler.new(blob).metadata
9
11
  # # => { width: 4104, height: 2736, pages: 10 }
10
12
  #
11
13
  # This analyzer requires the {poppler}[https://poppler.freedesktop.org/] system library, which is not provided by Rails.
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "../analyzer"
4
+
3
5
  module ActiveAnalysis
4
6
  # Extracts the following from a video blob:
5
7
  #
@@ -3,6 +3,7 @@
3
3
  require "active_storage"
4
4
 
5
5
  require "marcel"
6
+ require "image_processing"
6
7
  require "ruby-vips"
7
8
  require "mini_magick"
8
9
 
@@ -14,31 +15,54 @@ require_relative "analyzer/audio_analyzer"
14
15
  require_relative "analyzer/video_analyzer"
15
16
  require_relative "analyzer/pdf_analyzer"
16
17
 
18
+ require_relative "addon"
19
+ require_relative "addon/image_addon"
20
+ require_relative "addon/image_addon/optimal_quality"
21
+ require_relative "addon/image_addon/white_background"
22
+
17
23
  module ActiveAnalysis
18
24
  class Engine < ::Rails::Engine
19
25
  isolate_namespace ActiveAnalysis
20
26
 
21
- config.active_analysis = ActiveSupport::OrderedOptions.new
27
+ config.active_analysis = ActiveSupport::OrderedOptions.new
28
+ config.active_analysis.addons = []
29
+
22
30
  config.eager_load_namespaces << ActiveAnalysis
23
31
 
24
32
  initializer "active_analysis.configs" do
25
33
  config.after_initialize do |app|
26
- ActiveAnalysis.logger = app.config.active_analysis.logger || Rails.logger
27
- ActiveAnalysis.analyzers = app.config.active_analysis.analyzers || []
28
- ActiveAnalysis.image_library = app.config.active_analysis.image_library || app.config.active_storage.variant_processor
34
+ ActiveAnalysis.logger = app.config.active_analysis.logger || Rails.logger
35
+
36
+ ActiveAnalysis.image_library = app.config.active_analysis.image_library || app.config.active_storage.variant_processor || :mini_magick
37
+ ActiveAnalysis.image_analyzer = app.config.active_analysis.image_analyzer || true
38
+ ActiveAnalysis.audio_analyzer = app.config.active_analysis.audio_analyzer || true
39
+ ActiveAnalysis.pdf_analyzer = app.config.active_analysis.pdf_analyzer || true
40
+ ActiveAnalysis.video_analyzer = app.config.active_analysis.video_analyzer || true
41
+ ActiveAnalysis.addons = app.config.active_analysis.addons || []
29
42
  end
30
43
  end
31
44
 
32
- initializer "active_analysis.core_extensions" do
45
+ initializer "active_analysis.analyzers" do
33
46
  config.after_initialize do |app|
34
- app.config.active_storage.analyzers.delete ActiveStorage::Analyzer::ImageAnalyzer
35
- app.config.active_storage.analyzers.delete ActiveStorage::Analyzer::VideoAnalyzer
36
-
37
- app.config.active_storage.analyzers.append Analyzer::ImageAnalyzer::Vips
38
- app.config.active_storage.analyzers.append Analyzer::ImageAnalyzer::ImageMagick
39
- app.config.active_storage.analyzers.append Analyzer::VideoAnalyzer
40
- app.config.active_storage.analyzers.append Analyzer::AudioAnalyzer
41
- app.config.active_storage.analyzers.append Analyzer::PDFAnalyzer
47
+ if ActiveAnalysis.image_analyzer
48
+ app.config.active_storage.analyzers.delete ActiveStorage::Analyzer::ImageAnalyzer
49
+ app.config.active_storage.analyzers.append Analyzer::ImageAnalyzer::Vips
50
+ app.config.active_storage.analyzers.append Analyzer::ImageAnalyzer::ImageMagick
51
+ end
52
+
53
+ if ActiveAnalysis.video_analyzer
54
+ app.config.active_storage.analyzers.delete ActiveStorage::Analyzer::VideoAnalyzer
55
+ app.config.active_storage.analyzers.append Analyzer::VideoAnalyzer
56
+ end
57
+
58
+ if ActiveAnalysis.audio_analyzer
59
+ app.config.active_storage.analyzers.delete ActiveStorage::Analyzer::ImageAnalyzer if defined?(ActiveStorage::Analyzer::ImageAnalyzer)
60
+ app.config.active_storage.analyzers.append Analyzer::AudioAnalyzer
61
+ end
62
+
63
+ if ActiveAnalysis.pdf_analyzer
64
+ app.config.active_storage.analyzers.append Analyzer::PDFAnalyzer
65
+ end
42
66
  end
43
67
  end
44
68
  end
@@ -8,8 +8,8 @@ module ActiveAnalysis
8
8
 
9
9
  module VERSION
10
10
  MAJOR = 0
11
- MINOR = 1
12
- TINY = 2
11
+ MINOR = 3
12
+ TINY = 1
13
13
  PRE = nil
14
14
 
15
15
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_analysis
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Breno Gazzola
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-06-11 00:00:00.000000000 Z
11
+ date: 2021-06-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activestorage
@@ -16,70 +16,42 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '6.1'
19
+ version: '6.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '6.1'
26
+ version: '6.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: activesupport
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '6.1'
33
+ version: '6.0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '6.1'
40
+ version: '6.0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: mini_magick
42
+ name: image_processing
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '4.1'
47
+ version: '1.2'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '4.1'
55
- - !ruby/object:Gem::Dependency
56
- name: ruby-vips
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '2.0'
62
- type: :runtime
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '2.0'
69
- - !ruby/object:Gem::Dependency
70
- name: platform_agent
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '1.0'
76
- type: :runtime
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '1.0'
54
+ version: '1.2'
83
55
  - !ruby/object:Gem::Dependency
84
56
  name: sqlite3
85
57
  requirement: !ruby/object:Gem::Requirement
@@ -185,6 +157,10 @@ files:
185
157
  - app/views/layouts/active_analysis/application.html.erb
186
158
  - config/routes.rb
187
159
  - lib/active_analysis.rb
160
+ - lib/active_analysis/addon.rb
161
+ - lib/active_analysis/addon/image_addon.rb
162
+ - lib/active_analysis/addon/image_addon/optimal_quality.rb
163
+ - lib/active_analysis/addon/image_addon/white_background.rb
188
164
  - lib/active_analysis/analyzer.rb
189
165
  - lib/active_analysis/analyzer/audio_analyzer.rb
190
166
  - lib/active_analysis/analyzer/image_analyzer.rb
@@ -219,7 +195,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
219
195
  - !ruby/object:Gem::Version
220
196
  version: '0'
221
197
  requirements: []
222
- rubygems_version: 3.0.3
198
+ rubygems_version: 3.2.17
223
199
  signing_key:
224
200
  specification_version: 4
225
201
  summary: Collection of Active Storage analyzers