dynamic_image 2.0.20 → 2.0.25

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: f0a95aa4e97d054b1bd7d757c14f0a98790061806a930b6a2c8bc9294d85d00a
4
- data.tar.gz: dbe583ffcfe362d0406c0b272bc1f7a53d625be553d0e804baa5bf6753100cae
3
+ metadata.gz: 20b1cfa9c326762d6b3d1bca63b4d8d65516cc266abd03f55328b4cca8086dc3
4
+ data.tar.gz: 4a0496d6507534664dc8e39bc59358a2607df6aaaa966ee0eda3990f72cae8bf
5
5
  SHA512:
6
- metadata.gz: 681e4621406b2e6c4eae033dcba0ca1ea085c3429307a29e897eed62cbf22f2810183107142aae0432c351e2a8a47f5a25aa7ca901afe4e908109cf6126d54d3
7
- data.tar.gz: a7e5975010f4eb0f3dfaa3bf9185ea5a8e4d134f6f963d353da7d7dca0c4894094aee2a8557083bf1870ef9770fc26e3a5e58346fe55742f0af07f73e691f612
6
+ metadata.gz: c04933c776c41870142473869f983fd0d8d1a0b98602abf41b3fb5392f6d6ef8c4cb2f77c875044f32cbc7903d1dd9de06c644fcfc73c913bd414583ee27dfae
7
+ data.tar.gz: 79ad9d9b59398d56765878253170eae968d2d8320c31b992fd9758ff2dd00b8131db1fae2746f6af359eeb8b9934dfe4020b30cd91602f1b6872302c95b2d1d6
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  [![Version](https://img.shields.io/gem/v/dynamic_image.svg?style=flat)](https://rubygems.org/gems/dynamic_image)
2
- [![Build Status](https://travis-ci.org/elektronaut/dynamic_image.svg?branch=master)](https://travis-ci.org/elektronaut/dynamic_image)
2
+ ![Build](https://github.com/elektronaut/dynamic_image/workflows/Build/badge.svg)
3
3
  [![Code Climate](https://codeclimate.com/github/elektronaut/dynamic_image/badges/gpa.svg)](https://codeclimate.com/github/elektronaut/dynamic_image)
4
4
  [![Code Climate](https://codeclimate.com/github/elektronaut/dynamic_image/badges/coverage.svg)](https://codeclimate.com/github/elektronaut/dynamic_image)
5
5
  [![Inline docs](http://inch-ci.org/github/elektronaut/dynamic_image.svg)](http://inch-ci.org/github/elektronaut/dynamic_image)
@@ -12,11 +12,12 @@ require "dynamic_image/errors"
12
12
  require "dynamic_image/helper"
13
13
  require "dynamic_image/image_reader"
14
14
  require "dynamic_image/image_sizing"
15
+ require "dynamic_image/jobs"
15
16
  require "dynamic_image/metadata"
16
17
  require "dynamic_image/model"
17
18
  require "dynamic_image/processed_image"
18
19
  require "dynamic_image/routing"
19
20
 
20
21
  module DynamicImage
21
- cattr_accessor :digest_verifier
22
+ cattr_accessor :digest_verifier, :process_later_limit
22
23
  end
@@ -8,7 +8,7 @@ module DynamicImage
8
8
 
9
9
  module ClassMethods
10
10
  def belongs_to_image(name, scope = nil, **options)
11
- belongs_to(name, scope, options)
11
+ belongs_to(name, scope, **options)
12
12
 
13
13
  define_method "#{name}=" do |new_image|
14
14
  if new_image.present? && !new_image.is_a?(DynamicImage::Model)
@@ -44,13 +44,21 @@ module DynamicImage
44
44
  private
45
45
 
46
46
  def cache_expiration_header
47
- expires_in 30.days, public: true
47
+ expires_in 30.days, public: true if response.status == 200
48
48
  end
49
49
 
50
50
  def find_record
51
51
  @record = model.find(params[:id])
52
52
  end
53
53
 
54
+ def process_later?(processed_image, size)
55
+ return false unless DynamicImage.process_later_limit
56
+
57
+ image_size = processed_image.record.size.x * processed_image.record.size.y
58
+ image_size > DynamicImage.process_later_limit &&
59
+ !processed_image.find_variant(size)
60
+ end
61
+
54
62
  def render_image(options)
55
63
  return unless stale?(@record)
56
64
 
@@ -59,8 +67,8 @@ module DynamicImage
59
67
  render(file: File.join(File.dirname(__FILE__), "templates/show"),
60
68
  layout: false, locals: { options: options })
61
69
  end
62
- format.any(:gif, :jpeg, :png, :tiff, :webp) do
63
- send_image(DynamicImage::ProcessedImage.new(@record, options))
70
+ format.any(:gif, :jpeg, :jpg, :png, :tiff, :webp) do
71
+ send_image(@record, options)
64
72
  end
65
73
  end
66
74
  end
@@ -69,7 +77,7 @@ module DynamicImage
69
77
  return unless stale?(@record)
70
78
 
71
79
  respond_to do |format|
72
- format.any(:gif, :jpeg, :png, :tiff, :webp) do
80
+ format.any(:gif, :jpeg, :jpg, :png, :tiff, :webp) do
73
81
  send_data(@record.data,
74
82
  filename: filename,
75
83
  content_type: @record.content_type,
@@ -82,12 +90,17 @@ module DynamicImage
82
90
  params[:format]
83
91
  end
84
92
 
85
- def send_image(processed_image)
86
- send_data(
87
- processed_image.cropped_and_resized(requested_size),
88
- content_type: processed_image.content_type,
89
- disposition: "inline"
90
- )
93
+ def send_image(image, options)
94
+ processed_image = DynamicImage::ProcessedImage.new(image, options)
95
+ if process_later?(processed_image, requested_size)
96
+ DynamicImage::Jobs::CreateVariant
97
+ .perform_later(image, options, requested_size.to_s)
98
+ head 503, retry_after: 10
99
+ else
100
+ send_data(processed_image.cropped_and_resized(requested_size),
101
+ content_type: processed_image.content_type,
102
+ disposition: "inline")
103
+ end
91
104
  end
92
105
 
93
106
  def verify_signed_params
@@ -17,11 +17,21 @@ module DynamicImage
17
17
  end
18
18
  end
19
19
 
20
+ initializer "dynamic_image.mime_types" do
21
+ Mime::Type.register "image/bmp", :bmp
22
+ Mime::Type.register "image/gif", :gif
23
+ Mime::Type.register "image/jpeg", :jpg
24
+ Mime::Type.register "image/jpeg", :jpeg
25
+ Mime::Type.register "image/png", :png
26
+ Mime::Type.register "image/tiff", :tiff
27
+ Mime::Type.register "image/webp", :webp
28
+ end
29
+
20
30
  initializer "dynamic_image.extensions", before: :load_active_support do
21
31
  ActiveSupport.on_load(:active_record) do
22
32
  send :include, DynamicImage::BelongsTo
23
33
  end
24
- ActionDispatch::Routing::Mapper.send :include, DynamicImage::Routing
34
+ ActionDispatch::Routing::Mapper.include DynamicImage::Routing
25
35
 
26
36
  ActionDispatch::ExceptionWrapper.rescue_responses.merge!(
27
37
  "DynamicImage::Errors::InvalidSignature" => :unauthorized
@@ -149,8 +149,8 @@ module DynamicImage
149
149
  @uncropped
150
150
  end
151
151
 
152
- def vector(x, y)
153
- Vector2d.new(x, y)
152
+ def vector(width, height)
153
+ Vector2d.new(width, height)
154
154
  end
155
155
  end
156
156
  end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dynamic_image/jobs/create_variant"
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DynamicImage
4
+ module Jobs
5
+ # = Create variant
6
+ #
7
+ # Creates an image variant.
8
+ class CreateVariant < ActiveJob::Base
9
+ queue_as :dis
10
+
11
+ def perform(record, options, size)
12
+ size_v = Vector2d.parse(size)
13
+ DynamicImage::ProcessedImage.new(record, options)
14
+ .find_or_create_variant(size_v)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -82,8 +82,8 @@ module DynamicImage
82
82
 
83
83
  private
84
84
 
85
- def vector(x, y)
86
- Vector2d.new(x, y)
85
+ def vector(width, height)
86
+ Vector2d.new(width, height)
87
87
  end
88
88
  end
89
89
  end
@@ -6,6 +6,8 @@ module DynamicImage
6
6
  # Handles all processing of images. Takes an instance of
7
7
  # +DynamicImage::Model+ as argument.
8
8
  class ProcessedImage
9
+ attr_reader :record
10
+
9
11
  def initialize(record, options = {})
10
12
  @record = record
11
13
  @uncropped = options[:uncropped] ? true : false
@@ -40,10 +42,24 @@ module DynamicImage
40
42
  find_or_create_variant(size).data
41
43
  end
42
44
 
45
+ # Find or create a variant with the given size.
46
+ def find_or_create_variant(size)
47
+ find_variant(size) || create_variant(size)
48
+ rescue ActiveRecord::RecordNotUnique
49
+ find_variant(size)
50
+ end
51
+
52
+ # Find a variant with the given size.
53
+ def find_variant(size)
54
+ return nil unless record.persisted?
55
+
56
+ record.variants.find_by(variant_params(size))
57
+ end
58
+
43
59
  # Normalizes the image.
44
60
  #
45
61
  # * Applies EXIF rotation
46
- # * CMYK images are converted to sRGB
62
+ # * Converts to sRGB
47
63
  # * Strips metadata
48
64
  # * Optimizes GIFs
49
65
  # * Performs format conversion if the requested format is different
@@ -59,7 +75,7 @@ module DynamicImage
59
75
  process_data do |image|
60
76
  image.combine_options do |combined|
61
77
  combined.auto_orient
62
- combined.colorspace("sRGB") if needs_colorspace_conversion?
78
+ convert_to_srgb(image, combined)
63
79
  yield(combined) if block_given?
64
80
  optimize(combined)
65
81
  end
@@ -70,27 +86,29 @@ module DynamicImage
70
86
  private
71
87
 
72
88
  def coalesced(image)
73
- return image unless gif?
89
+ gif? ? DynamicImage::ImageReader.new(image.coalesce.to_blob).read : image
90
+ end
91
+
92
+ def convert_to_srgb(image, combined)
93
+ combined.profile(srgb_profile) if image.data["profiles"].present?
94
+ combined.colorspace("sRGB") if record.cmyk?
95
+ end
74
96
 
75
- DynamicImage::ImageReader.new(image.coalesce.to_blob).read
97
+ def create_variant(size)
98
+ record.variants.create(
99
+ variant_params(size).merge(filename: record.filename,
100
+ content_type: content_type,
101
+ data: crop_and_resize(size))
102
+ )
76
103
  end
77
104
 
78
105
  def crop_and_resize(size)
79
106
  normalized do |image|
80
- if record.cropped? || size != record.size
81
- image.crop(image_sizing.crop_geometry_string(size))
82
- image.resize(size)
83
- end
84
- end
85
- end
107
+ next unless record.cropped? || size != record.size
86
108
 
87
- def find_or_create_variant(size)
88
- record.variants.find_by(variant_params(size)) ||
89
- record.variants.create(
90
- variant_params(size).merge(filename: record.filename,
91
- content_type: content_type,
92
- data: crop_and_resize(size))
93
- )
109
+ image.crop(image_sizing.crop_geometry_string(size))
110
+ image.resize(size)
111
+ end
94
112
  end
95
113
 
96
114
  def format
@@ -102,7 +120,7 @@ module DynamicImage
102
120
  end
103
121
 
104
122
  def jpeg?
105
- content_type == "image/jpeg" || content_type == "image/jpeg"
123
+ content_type == "image/jpeg"
106
124
  end
107
125
 
108
126
  def image_sizing
@@ -110,10 +128,6 @@ module DynamicImage
110
128
  DynamicImage::ImageSizing.new(record, uncropped: @uncropped)
111
129
  end
112
130
 
113
- def needs_colorspace_conversion?
114
- record.cmyk?
115
- end
116
-
117
131
  def needs_format_conversion?
118
132
  format != record_format
119
133
  end
@@ -133,15 +147,9 @@ module DynamicImage
133
147
  result
134
148
  end
135
149
 
136
- attr_reader :record
137
-
138
150
  def record_format
139
- { "image/bmp" => "BMP",
140
- "image/png" => "PNG",
141
- "image/gif" => "GIF",
142
- "image/jpeg" => "JPEG",
143
- "image/pjpeg" => "JPEG",
144
- "image/tiff" => "TIFF",
151
+ { "image/bmp" => "BMP", "image/png" => "PNG", "image/gif" => "GIF",
152
+ "image/jpeg" => "JPEG", "image/pjpeg" => "JPEG", "image/tiff" => "TIFF",
145
153
  "image/webp" => "WEBP" }[record.content_type]
146
154
  end
147
155
 
@@ -149,15 +157,16 @@ module DynamicImage
149
157
  raise DynamicImage::Errors::InvalidImage unless record.valid?
150
158
  end
151
159
 
160
+ def srgb_profile
161
+ File.join(File.dirname(__FILE__), "profiles/sRGB_ICC_v4_Appearance.icc")
162
+ end
163
+
152
164
  def variant_params(size)
153
165
  crop_size, crop_start = image_sizing.crop_geometry(size)
154
166
 
155
- { width: size.x.round,
156
- height: size.y.round,
157
- crop_width: crop_size.x,
158
- crop_height: crop_size.y,
159
- crop_start_x: crop_start.x,
160
- crop_start_y: crop_start.y,
167
+ { width: size.x.round, height: size.y.round,
168
+ crop_width: crop_size.x, crop_height: crop_size.y,
169
+ crop_start_x: crop_start.x, crop_start_y: crop_start.y,
161
170
  format: format }
162
171
  end
163
172
  end
@@ -13,8 +13,9 @@ module DynamicImage
13
13
  options = {
14
14
  path: "#{resource_name}/:digest(/:size)",
15
15
  constraints: { size: /\d+x\d+/ },
16
- only: [:show]
16
+ only: %i[show]
17
17
  }.merge(options)
18
+
18
19
  resources resource_name, options do
19
20
  get :uncropped, on: :member
20
21
  get :original, on: :member
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DynamicImage
4
- VERSION = "2.0.20"
4
+ VERSION = "2.0.25"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dynamic_image
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.20
4
+ version: 2.0.25
5
5
  platform: ruby
6
6
  authors:
7
7
  - Inge Jørgensen
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-03-13 00:00:00.000000000 Z
11
+ date: 2020-11-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dis
@@ -78,6 +78,20 @@ dependencies:
78
78
  - - ">="
79
79
  - !ruby/object:Gem::Version
80
80
  version: 2.2.1
81
+ - !ruby/object:Gem::Dependency
82
+ name: rails-controller-testing
83
+ requirement: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
81
95
  - !ruby/object:Gem::Dependency
82
96
  name: rspec-rails
83
97
  requirement: !ruby/object:Gem::Requirement
@@ -92,6 +106,20 @@ dependencies:
92
106
  - - "~>"
93
107
  - !ruby/object:Gem::Version
94
108
  version: 3.7.0
109
+ - !ruby/object:Gem::Dependency
110
+ name: simplecov
111
+ requirement: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - "~>"
114
+ - !ruby/object:Gem::Version
115
+ version: 0.17.1
116
+ type: :development
117
+ prerelease: false
118
+ version_requirements: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - "~>"
121
+ - !ruby/object:Gem::Version
122
+ version: 0.17.1
95
123
  - !ruby/object:Gem::Dependency
96
124
  name: sqlite3
97
125
  requirement: !ruby/object:Gem::Requirement
@@ -127,6 +155,8 @@ files:
127
155
  - lib/dynamic_image/helper.rb
128
156
  - lib/dynamic_image/image_reader.rb
129
157
  - lib/dynamic_image/image_sizing.rb
158
+ - lib/dynamic_image/jobs.rb
159
+ - lib/dynamic_image/jobs/create_variant.rb
130
160
  - lib/dynamic_image/metadata.rb
131
161
  - lib/dynamic_image/model.rb
132
162
  - lib/dynamic_image/model/dimensions.rb
@@ -134,6 +164,7 @@ files:
134
164
  - lib/dynamic_image/model/validations.rb
135
165
  - lib/dynamic_image/model/variants.rb
136
166
  - lib/dynamic_image/processed_image.rb
167
+ - lib/dynamic_image/profiles/sRGB_ICC_v4_Appearance.icc
137
168
  - lib/dynamic_image/routing.rb
138
169
  - lib/dynamic_image/templates/show.html.erb
139
170
  - lib/dynamic_image/version.rb
@@ -142,7 +173,7 @@ homepage: https://github.com/elektronaut/dynamic_image
142
173
  licenses:
143
174
  - MIT
144
175
  metadata: {}
145
- post_install_message:
176
+ post_install_message:
146
177
  rdoc_options: []
147
178
  require_paths:
148
179
  - lib
@@ -158,7 +189,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
158
189
  version: '0'
159
190
  requirements: []
160
191
  rubygems_version: 3.1.2
161
- signing_key:
192
+ signing_key:
162
193
  specification_version: 4
163
194
  summary: Rails plugin that simplifies image uploading and processing
164
195
  test_files: []