dynamic_image 2.0.16 → 2.0.17

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: df3c91615696c4df8f094670ca324626be3a3d33f232b6dd483c22d36d547534
4
- data.tar.gz: b781ca35542805f1fe34446d60fe23a12d07603c560a1aa9e95f8b519551ea8c
3
+ metadata.gz: a62dce84fcc98c58fd62f1a59ef08bb918cfe77c3441542959609b0eb8e6b5da
4
+ data.tar.gz: 8dc11abb55c9cf425fd651f9017cd9477235bd712b185c268c36f36191833422
5
5
  SHA512:
6
- metadata.gz: ed8c8fdfe061bf189beb9946faa56c5bb631edd0f4fc1099a71c6fbd07aee2e815299d7acbf0385dfb001186122035d91d6a834bf002383a1d1fb3283ac3a5e7
7
- data.tar.gz: f80069f885761140e96a98d2aa0c0dc0b47a2b668d9fae06d0afefc49b0ada0c59013c7fe97f8d6f6f7102ab83c747076c0ba2982d1112f58f81ea39b3c028dc
6
+ metadata.gz: da083259103d212b5bc8909659b5e3110a18ac8ca34cc232c2a1d120e6927d8165ae04f9367661e96687cf43f1be9079002b54cd3947d9c5aa61d15eea5c44f7
7
+ data.tar.gz: fe2692f3948999720c135ce33e94e979d945bf985617d852bb10bd972e917519ea03f3e3e321bce2677da9f88c7fd70aea4f86f4d4fda1373adf547658542fa0
data/README.md CHANGED
@@ -28,8 +28,8 @@ and enumeration attacks.
28
28
 
29
29
  ## Requirements
30
30
 
31
- * Rails 4.2
32
- * Ruby 1.9.3+
31
+ * Rails 5
32
+ * Ruby 2.4+
33
33
  * ImageMagick command line tools
34
34
 
35
35
  ## Documentation
data/Rakefile CHANGED
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "bundler/gem_tasks"
2
4
  require "rspec/core/rake_task"
3
5
 
4
- APP_RAKEFILE = "spec/internal/Rakefile".freeze
6
+ APP_RAKEFILE = "spec/internal/Rakefile"
5
7
  load "rails/tasks/engine.rake"
6
8
 
7
9
  RSpec::Core::RakeTask.new
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DynamicImage
4
+ class Variant < ApplicationRecord
5
+ include Dis::Model
6
+
7
+ self.table_name = "dynamic_image_variants"
8
+ self.dis_type = "image-variants"
9
+
10
+ belongs_to :image, polymorphic: true, inverse_of: :variants
11
+
12
+ validates_data_presence
13
+
14
+ validates :format, presence: true
15
+
16
+ validates :width, :height, :crop_width, :crop_height,
17
+ numericality: { greater_than: 0, only_integer: true }
18
+
19
+ validates :crop_start_x, :crop_start_y,
20
+ numericality: { only_integer: true }
21
+ end
22
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreateDynamicImageVariants < ActiveRecord::Migration[5.2]
4
+ def change
5
+ create_table :dynamic_image_variants do |t|
6
+ t.references :image, polymorphic: true, null: false
7
+
8
+ # Dis attributes
9
+ t.string :content_hash, null: false
10
+ t.string :content_type, null: false
11
+ t.integer :content_length, null: false
12
+ t.string :filename, null: false
13
+
14
+ t.string :format, null: false
15
+ t.integer :width, :height, null: false
16
+ t.integer :crop_width, :crop_height, null: false
17
+ t.integer :crop_start_x, :crop_start_y, null: false
18
+
19
+ t.timestamps null: false
20
+ end
21
+
22
+ add_index(:dynamic_image_variants,
23
+ %i[image_id image_type],
24
+ name: "dynamic_image_variants_by_image")
25
+
26
+ add_index(:dynamic_image_variants,
27
+ %i[image_id image_type format width height crop_width
28
+ crop_height crop_start_x crop_start_y],
29
+ name: "dynamic_image_variants_by_format_and_size",
30
+ unique: true)
31
+ end
32
+ end
data/lib/dynamic_image.rb CHANGED
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require "mini_magick"
4
4
  require "dis"
@@ -7,6 +7,7 @@ require "vector2d"
7
7
  require "dynamic_image/belongs_to"
8
8
  require "dynamic_image/controller"
9
9
  require "dynamic_image/digest_verifier"
10
+ require "dynamic_image/engine"
10
11
  require "dynamic_image/errors"
11
12
  require "dynamic_image/helper"
12
13
  require "dynamic_image/image_reader"
@@ -14,7 +15,6 @@ require "dynamic_image/image_sizing"
14
15
  require "dynamic_image/metadata"
15
16
  require "dynamic_image/model"
16
17
  require "dynamic_image/processed_image"
17
- require "dynamic_image/railtie"
18
18
  require "dynamic_image/routing"
19
19
 
20
20
  module DynamicImage
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module DynamicImage
4
4
  # = DynamicImage Belongs To
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module DynamicImage
4
4
  # = DynamicImage Controller
@@ -53,6 +53,7 @@ module DynamicImage
53
53
 
54
54
  def render_image(options)
55
55
  return unless stale?(@record)
56
+
56
57
  respond_to do |format|
57
58
  format.html do
58
59
  render(file: File.join(File.dirname(__FILE__), "templates/show"),
@@ -66,14 +67,13 @@ module DynamicImage
66
67
 
67
68
  def render_raw_image(disposition: "inline", filename: nil)
68
69
  return unless stale?(@record)
70
+
69
71
  respond_to do |format|
70
72
  format.any(:gif, :jpeg, :png, :tiff) do
71
- send_data(
72
- @record.data,
73
- filename: filename,
74
- content_type: @record.content_type,
75
- disposition: disposition
76
- )
73
+ send_data(@record.data,
74
+ filename: filename,
75
+ content_type: @record.content_type,
76
+ disposition: disposition)
77
77
  end
78
78
  end
79
79
  end
@@ -82,16 +82,16 @@ module DynamicImage
82
82
  params[:format]
83
83
  end
84
84
 
85
- def send_image(image)
85
+ def send_image(processed_image)
86
86
  send_data(
87
- image.cropped_and_resized(requested_size),
88
- content_type: image.content_type,
89
- disposition: "inline"
87
+ processed_image.cropped_and_resized(requested_size),
88
+ content_type: processed_image.content_type,
89
+ disposition: "inline"
90
90
  )
91
91
  end
92
92
 
93
93
  def verify_signed_params
94
- key = [:action, :id, :size].map do |k|
94
+ key = %i[action id size].map do |k|
95
95
  k == :id ? params.require(k).to_i : params.require(k)
96
96
  end.join("-")
97
97
  DynamicImage.digest_verifier.verify(key, params[:digest])
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module DynamicImage
4
4
  # = DynamicImage Digest Verifier
@@ -31,22 +31,20 @@ module DynamicImage
31
31
  # Verifies that <tt>digest</tt> is valid for <tt>data</tt>.
32
32
  # Raises a +DynamicImage::Errors::InvalidSignature+ error if not.
33
33
  def verify(data, digest)
34
- if valid_digest?(data, digest)
35
- true
36
- else
37
- raise DynamicImage::Errors::InvalidSignature
38
- end
34
+ return true if valid_digest?(data, digest)
35
+
36
+ raise DynamicImage::Errors::InvalidSignature
39
37
  end
40
38
 
41
39
  private
42
40
 
43
- def secure_compare(a, b)
44
- return false unless a.bytesize == b.bytesize
41
+ def secure_compare(str, other)
42
+ return false unless str.bytesize == other.bytesize
45
43
 
46
- l = a.unpack "C#{a.bytesize}"
44
+ l = str.unpack "C#{str.bytesize}"
47
45
 
48
46
  res = 0
49
- b.each_byte { |byte| res |= byte ^ l.shift }
47
+ other.each_byte { |byte| res |= byte ^ l.shift }
50
48
  res.zero?
51
49
  end
52
50
 
@@ -1,29 +1,40 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module DynamicImage
4
- class Railtie < ::Rails::Railtie
5
- initializer "dynamic_image" do
4
+ class Engine < ::Rails::Engine
5
+ initializer "dynamic_image.digest_verifier" do
6
+ config.after_initialize do |app|
7
+ secret = app.key_generator.generate_key("dynamic_image")
8
+ DynamicImage.digest_verifier = DynamicImage::DigestVerifier.new(secret)
9
+ end
10
+ end
11
+
12
+ initializer "dynamic_image.migrations" do |app|
13
+ unless app.root.to_s.match?(root.to_s)
14
+ config.paths["db/migrate"].expanded.each do |expanded_path|
15
+ app.config.paths["db/migrate"] << expanded_path
16
+ end
17
+ end
18
+ end
19
+
20
+ initializer "dynamic_image.extensions", before: :load_active_support do
21
+ ActiveSupport.on_load(:active_record) do
22
+ send :include, DynamicImage::BelongsTo
23
+ end
6
24
  ActionDispatch::Routing::Mapper.send :include, DynamicImage::Routing
7
25
 
8
26
  ActionDispatch::ExceptionWrapper.rescue_responses.merge!(
9
27
  "DynamicImage::Errors::InvalidSignature" => :unauthorized
10
28
  )
29
+ end
11
30
 
31
+ initializer "dynamic_image.sentry" do
12
32
  # If Sentry is configured, exclude reporting of tampered signatures
13
33
  if Object.const_defined?("Raven")
14
34
  Raven.configure do |c|
15
35
  c.excluded_exceptions += ["DynamicImage::Errors::InvalidSignature"]
16
36
  end
17
37
  end
18
-
19
- config.after_initialize do |app|
20
- secret = app.key_generator.generate_key("dynamic_image")
21
- DynamicImage.digest_verifier = DynamicImage::DigestVerifier.new(secret)
22
- end
23
-
24
- ActiveSupport.on_load(:active_record) do
25
- send :include, DynamicImage::BelongsTo
26
- end
27
38
  end
28
39
  end
29
40
  end
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module DynamicImage
4
4
  module Errors
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module DynamicImage
4
4
  # = DynamicImage Helper
@@ -117,11 +117,9 @@ module DynamicImage
117
117
  private
118
118
 
119
119
  def allowed_dynamic_image_url_options
120
- [
121
- :format, :only_path, :protocol, :host, :subdomain, :domain,
122
- :tld_length, :port, :anchor, :trailing_slash, :script_name,
123
- :action, :routing_type
124
- ]
120
+ %i[format only_path protocol host subdomain domain
121
+ tld_length port anchor trailing_slash script_name
122
+ action routing_type ]
125
123
  end
126
124
 
127
125
  def default_format_for_image(record)
@@ -162,9 +160,9 @@ module DynamicImage
162
160
  end
163
161
 
164
162
  def filename_to_alt(str)
165
- File.basename(str, ".*".freeze)
166
- .sub(/-[[:xdigit:]]{32,64}\z/, "".freeze)
167
- .tr("-_".freeze, " ".freeze)
163
+ File.basename(str, ".*")
164
+ .sub(/-[[:xdigit:]]{32,64}\z/, "")
165
+ .tr("-_", " ")
168
166
  .capitalize
169
167
  end
170
168
 
@@ -1,19 +1,35 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module DynamicImage
4
4
  class ImageReader
5
+ class << self
6
+ def magic_bytes
7
+ @magic_bytes ||= [
8
+ "\x47\x49\x46\x38\x37\x61", # GIF
9
+ "\x47\x49\x46\x38\x39\x61",
10
+ "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a", # PNG
11
+ "\xff\xd8", # JPEG
12
+ "\x49\x49\x2a\x00", # TIFF
13
+ "\x4d\x4d\x00\x2a",
14
+ "\x42\x4d" # BMP
15
+ ].map { |s| s.dup.force_encoding("binary") }
16
+ end
17
+ end
18
+
5
19
  def initialize(data)
6
20
  @data = data
7
21
  end
8
22
 
9
23
  def read
10
24
  raise DynamicImage::Errors::InvalidHeader unless valid_header?
25
+
11
26
  MiniMagick::Image.read(@data)
12
27
  end
13
28
 
14
29
  def valid_header?
15
30
  return false if file_header.blank?
16
- magic_bytes.each do |str|
31
+
32
+ self.class.magic_bytes.each do |str|
17
33
  return true if file_header.start_with?(str)
18
34
  end
19
35
  false
@@ -24,17 +40,5 @@ module DynamicImage
24
40
  def file_header
25
41
  @file_header ||= StringIO.new(@data, "rb").read(8)
26
42
  end
27
-
28
- def magic_bytes
29
- [
30
- "\x47\x49\x46\x38\x37\x61".force_encoding("binary"), # GIF
31
- "\x47\x49\x46\x38\x39\x61".force_encoding("binary"),
32
- "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a".force_encoding("binary"), # PNG
33
- "\xff\xd8".force_encoding("binary"), # JPEG
34
- "\x49\x49\x2a\x00".force_encoding("binary"), # TIFF
35
- "\x4d\x4d\x00\x2a".force_encoding("binary"),
36
- "\x42\x4d".force_encoding("binary") # BMP
37
- ]
38
- end
39
43
  end
40
44
  end
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module DynamicImage
4
4
  # = DynamicImage Image Sizing
@@ -121,20 +121,22 @@ module DynamicImage
121
121
  start
122
122
  end
123
123
 
124
- def parse_vector(v)
125
- v.is_a?(String) ? str_to_vector(v) : v
124
+ def parse_vector(vector)
125
+ vector.is_a?(String) ? str_to_vector(vector) : vector
126
126
  end
127
127
 
128
128
  attr_reader :record
129
129
 
130
- def require_dimensions!(v)
131
- raise DynamicImage::Errors::InvalidSizeOptions unless v.x > 0 && v.y > 0
130
+ def require_dimensions!(vector)
131
+ return if vector.x.positive? && vector.y.positive?
132
+
133
+ raise DynamicImage::Errors::InvalidSizeOptions
132
134
  end
133
135
 
134
136
  def shift_vector(vect)
135
137
  vector(
136
- vect.x < 0 ? vect.x.abs : 0,
137
- vect.y < 0 ? vect.y.abs : 0
138
+ vect.x.negative? ? vect.x.abs : 0,
139
+ vect.y.negative? ? vect.y.abs : 0
138
140
  )
139
141
  end
140
142
 
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module DynamicImage
4
4
  # = DynamicImage Metadata
@@ -13,15 +13,15 @@ module DynamicImage
13
13
  # Returns the color space of the image as a string. The result will be one
14
14
  # of the following: "rgb", "cmyk", "gray".
15
15
  def colorspace
16
- if valid?
17
- case metadata[:colorspace]
18
- when /rgb/i
19
- "rgb"
20
- when /cmyk/i
21
- "cmyk"
22
- when /gray/i
23
- "gray"
24
- end
16
+ return unless valid?
17
+
18
+ case metadata[:colorspace]
19
+ when /rgb/i
20
+ "rgb"
21
+ when /cmyk/i
22
+ "cmyk"
23
+ when /gray/i
24
+ "gray"
25
25
  end
26
26
  end
27
27
 
@@ -80,7 +80,7 @@ module DynamicImage
80
80
  {
81
81
  colorspace: image[:colorspace],
82
82
  dimensions: image[:dimensions],
83
- format: image[:format]
83
+ format: image[:format]
84
84
  }
85
85
  end
86
86
  end
@@ -1,8 +1,9 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require "dynamic_image/model/dimensions"
4
4
  require "dynamic_image/model/transformations"
5
5
  require "dynamic_image/model/validations"
6
+ require "dynamic_image/model/variants"
6
7
 
7
8
  module DynamicImage
8
9
  # = DynamicImage Model
@@ -65,6 +66,7 @@ module DynamicImage
65
66
  include DynamicImage::Model::Dimensions
66
67
  include DynamicImage::Model::Transformations
67
68
  include DynamicImage::Model::Validations
69
+ include DynamicImage::Model::Variants
68
70
 
69
71
  included do
70
72
  before_validation :read_image_metadata, if: :data_changed?
@@ -121,11 +123,9 @@ module DynamicImage
121
123
  end
122
124
 
123
125
  def safe_content_types
124
- %w(
125
- image/png
126
- image/gif
127
- image/jpeg
128
- )
126
+ %w[image/png
127
+ image/gif
128
+ image/jpeg]
129
129
  end
130
130
  end
131
131
  end
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module DynamicImage
4
4
  module Model
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module DynamicImage
4
4
  module Model
@@ -59,6 +59,7 @@ module DynamicImage
59
59
 
60
60
  def rotated_crop(new_width)
61
61
  return nil unless cropped?
62
+
62
63
  [
63
64
  new_width - (crop_start_y + crop_height),
64
65
  crop_start_x,
@@ -69,6 +70,7 @@ module DynamicImage
69
70
 
70
71
  def rotated_crop_gravity(new_width)
71
72
  return nil unless crop_gravity?
73
+
72
74
  [new_width - crop_gravity_y, crop_gravity_x]
73
75
  end
74
76
 
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module DynamicImage
4
4
  module Model
@@ -9,6 +9,7 @@ module DynamicImage
9
9
  # integrity.
10
10
  module Validations
11
11
  extend ActiveSupport::Concern
12
+
12
13
  included do
13
14
  validates_data_presence
14
15
 
@@ -57,22 +58,18 @@ module DynamicImage
57
58
 
58
59
  module ClassMethods
59
60
  def allowed_colorspaces
60
- %w(
61
- rgb
62
- cmyk
63
- gray
64
- )
61
+ %w[rgb
62
+ cmyk
63
+ gray]
65
64
  end
66
65
 
67
66
  def allowed_content_types
68
- %w(
69
- image/bmp
70
- image/gif
71
- image/jpeg
72
- image/pjpeg
73
- image/png
74
- image/tiff
75
- )
67
+ %w[image/bmp
68
+ image/gif
69
+ image/jpeg
70
+ image/pjpeg
71
+ image/png
72
+ image/tiff]
76
73
  end
77
74
  end
78
75
 
@@ -80,9 +77,10 @@ module DynamicImage
80
77
 
81
78
  def validate_crop_bounds
82
79
  required_size = crop_start + crop_size
83
- if required_size.x > real_size.x || required_size.y > real_size.y
84
- errors.add(:crop_size, "is out of bounds")
85
- end
80
+ return unless required_size.x > real_size.x ||
81
+ required_size.y > real_size.y
82
+
83
+ errors.add(:crop_size, "is out of bounds")
86
84
  end
87
85
 
88
86
  def validate_image
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DynamicImage
4
+ module Model
5
+ # = DynamicImage Model Variants
6
+ #
7
+ # Validates that all necessary attributes are valid. All of these are
8
+ # managed by +DynamicImage::Model+, so this is mostly for enforcing
9
+ # integrity.
10
+ module Variants
11
+ extend ActiveSupport::Concern
12
+
13
+ included do
14
+ has_many :variants,
15
+ as: :image,
16
+ class_name: "DynamicImage::Variant",
17
+ dependent: :destroy
18
+
19
+ before_update :clear_variants, if: :data_changed?
20
+ end
21
+
22
+ private
23
+
24
+ def clear_variants
25
+ variants.destroy_all
26
+ end
27
+ end
28
+ end
29
+ end
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module DynamicImage
4
4
  # = DynamicImage Processed Image
@@ -35,12 +35,9 @@ module DynamicImage
35
35
  #
36
36
  # Returns a binary string.
37
37
  def cropped_and_resized(size)
38
- normalized do |image|
39
- if record.cropped? || size != record.size
40
- image.crop(image_sizing.crop_geometry_string(size))
41
- image.resize(size)
42
- end
43
- end
38
+ return crop_and_resize(size) unless record.persisted?
39
+
40
+ find_or_create_variant(size).data
44
41
  end
45
42
 
46
43
  # Normalizes the image.
@@ -73,11 +70,27 @@ module DynamicImage
73
70
  private
74
71
 
75
72
  def coalesced(image)
76
- if gif?
77
- image.coalesce
78
- image = DynamicImage::ImageReader.new(image.to_blob).read
73
+ return image unless gif?
74
+
75
+ DynamicImage::ImageReader.new(image.coalesce.to_blob).read
76
+ end
77
+
78
+ def crop_and_resize(size)
79
+ 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
79
84
  end
80
- image
85
+ end
86
+
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
+ )
81
94
  end
82
95
 
83
96
  def format
@@ -93,8 +106,8 @@ module DynamicImage
93
106
  end
94
107
 
95
108
  def image_sizing
96
- @image_sizing ||= DynamicImage::ImageSizing.new(record,
97
- uncropped: @uncropped)
109
+ @image_sizing ||=
110
+ DynamicImage::ImageSizing.new(record, uncropped: @uncropped)
98
111
  end
99
112
 
100
113
  def needs_colorspace_conversion?
@@ -108,11 +121,8 @@ module DynamicImage
108
121
  def optimize(image)
109
122
  image.layers "optimize" if gif?
110
123
  image.strip
111
- if jpeg?
112
- image.quality(85)
113
- image.sampling_factor "4:2:0"
114
- image.interlace "JPEG"
115
- end
124
+ image.quality(85).sampling_factor("4:2:0").interlace("JPEG") if jpeg?
125
+ image
116
126
  end
117
127
 
118
128
  def process_data
@@ -126,22 +136,28 @@ module DynamicImage
126
136
  attr_reader :record
127
137
 
128
138
  def record_format
129
- case record.content_type
130
- when "image/bmp"
131
- "BMP"
132
- when "image/png"
133
- "PNG"
134
- when "image/gif"
135
- "GIF"
136
- when "image/jpeg", "image/pjpeg"
137
- "JPEG"
138
- when "image/tiff"
139
- "TIFF"
140
- end
139
+ { "image/bmp" => "BMP",
140
+ "image/png" => "PNG",
141
+ "image/gif" => "GIF",
142
+ "image/jpeg" => "JPEG",
143
+ "image/pjpeg" => "JPEG",
144
+ "image/tiff" => "TIFF" }[record.content_type]
141
145
  end
142
146
 
143
147
  def require_valid_image!
144
148
  raise DynamicImage::Errors::InvalidImage unless record.valid?
145
149
  end
150
+
151
+ def variant_params(size)
152
+ crop_size, crop_start = image_sizing.crop_geometry(size)
153
+
154
+ { width: size.x,
155
+ height: size.y,
156
+ crop_width: crop_size.x,
157
+ crop_height: crop_size.y,
158
+ crop_start_x: crop_start.x,
159
+ crop_start_y: crop_start.y,
160
+ format: format }
161
+ end
146
162
  end
147
163
  end
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module DynamicImage
4
4
  # = DynamicImage Routing
@@ -11,9 +11,9 @@ module DynamicImage
11
11
  # image_resources :avatars
12
12
  def image_resources(resource_name, options = {})
13
13
  options = {
14
- path: "#{resource_name}/:digest(/:size)",
14
+ path: "#{resource_name}/:digest(/:size)",
15
15
  constraints: { size: /\d+x\d+/ },
16
- only: [:show]
16
+ only: [:show]
17
17
  }.merge(options)
18
18
  resources resource_name, options do
19
19
  get :uncropped, on: :member
@@ -1,5 +1,5 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module DynamicImage
4
- VERSION = "2.0.16".freeze
4
+ VERSION = "2.0.17"
5
5
  end
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require "rails/generators"
4
4
  require "rails/generators/rails/resource/resource_generator"
@@ -52,16 +52,14 @@ module DynamicImage
52
52
  end
53
53
 
54
54
  def dynamic_image_attributes
55
- %w(
56
- content_hash:string content_type:string
57
- content_length:integer
58
- filename:string
59
- colorspace:string
60
- real_width:integer real_height:integer
61
- crop_width:integer crop_height:integer
62
- crop_start_x:integer crop_start_y:integer
63
- crop_gravity_x:integer crop_gravity_y:integer
64
- )
55
+ %w[content_hash:string content_type:string
56
+ content_length:integer
57
+ filename:string
58
+ colorspace:string
59
+ real_width:integer real_height:integer
60
+ crop_width:integer crop_height:integer
61
+ crop_start_x:integer crop_start_y:integer
62
+ crop_gravity_x:integer crop_gravity_y:integer]
65
63
  end
66
64
  end
67
65
  end
metadata CHANGED
@@ -1,111 +1,111 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dynamic_image
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.16
4
+ version: 2.0.17
5
5
  platform: ruby
6
6
  authors:
7
7
  - Inge Jørgensen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-10-11 00:00:00.000000000 Z
11
+ date: 2019-08-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: rails
14
+ name: dis
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 1.0.6
17
20
  - - "~>"
18
21
  - !ruby/object:Gem::Version
19
- version: '5.0'
22
+ version: '1.1'
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 1.0.6
24
30
  - - "~>"
25
31
  - !ruby/object:Gem::Version
26
- version: '5.0'
32
+ version: '1.1'
27
33
  - !ruby/object:Gem::Dependency
28
- name: vector2d
34
+ name: mini_magick
29
35
  requirement: !ruby/object:Gem::Requirement
30
36
  requirements:
31
37
  - - "~>"
32
38
  - !ruby/object:Gem::Version
33
- version: '2.2'
34
- - - ">="
35
- - !ruby/object:Gem::Version
36
- version: 2.2.1
39
+ version: '4.9'
37
40
  type: :runtime
38
41
  prerelease: false
39
42
  version_requirements: !ruby/object:Gem::Requirement
40
43
  requirements:
41
44
  - - "~>"
42
45
  - !ruby/object:Gem::Version
43
- version: '2.2'
44
- - - ">="
45
- - !ruby/object:Gem::Version
46
- version: 2.2.1
46
+ version: '4.9'
47
47
  - !ruby/object:Gem::Dependency
48
- name: mini_magick
48
+ name: rails
49
49
  requirement: !ruby/object:Gem::Requirement
50
50
  requirements:
51
51
  - - "~>"
52
52
  - !ruby/object:Gem::Version
53
- version: 4.6.0
53
+ version: '5.0'
54
54
  type: :runtime
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
57
57
  requirements:
58
58
  - - "~>"
59
59
  - !ruby/object:Gem::Version
60
- version: 4.6.0
60
+ version: '5.0'
61
61
  - !ruby/object:Gem::Dependency
62
- name: dis
62
+ name: vector2d
63
63
  requirement: !ruby/object:Gem::Requirement
64
64
  requirements:
65
65
  - - "~>"
66
66
  - !ruby/object:Gem::Version
67
- version: '1.1'
67
+ version: '2.2'
68
68
  - - ">="
69
69
  - !ruby/object:Gem::Version
70
- version: 1.0.6
70
+ version: 2.2.1
71
71
  type: :runtime
72
72
  prerelease: false
73
73
  version_requirements: !ruby/object:Gem::Requirement
74
74
  requirements:
75
75
  - - "~>"
76
76
  - !ruby/object:Gem::Version
77
- version: '1.1'
77
+ version: '2.2'
78
78
  - - ">="
79
79
  - !ruby/object:Gem::Version
80
- version: 1.0.6
80
+ version: 2.2.1
81
81
  - !ruby/object:Gem::Dependency
82
- name: sqlite3
82
+ name: rspec-rails
83
83
  requirement: !ruby/object:Gem::Requirement
84
84
  requirements:
85
- - - ">="
85
+ - - "~>"
86
86
  - !ruby/object:Gem::Version
87
- version: '0'
87
+ version: 3.7.0
88
88
  type: :development
89
89
  prerelease: false
90
90
  version_requirements: !ruby/object:Gem::Requirement
91
91
  requirements:
92
- - - ">="
92
+ - - "~>"
93
93
  - !ruby/object:Gem::Version
94
- version: '0'
94
+ version: 3.7.0
95
95
  - !ruby/object:Gem::Dependency
96
- name: rspec-rails
96
+ name: sqlite3
97
97
  requirement: !ruby/object:Gem::Requirement
98
98
  requirements:
99
- - - "~>"
99
+ - - ">="
100
100
  - !ruby/object:Gem::Version
101
- version: 3.7.0
101
+ version: '0'
102
102
  type: :development
103
103
  prerelease: false
104
104
  version_requirements: !ruby/object:Gem::Requirement
105
105
  requirements:
106
- - - "~>"
106
+ - - ">="
107
107
  - !ruby/object:Gem::Version
108
- version: 3.7.0
108
+ version: '0'
109
109
  description: DynamicImage is a Rails plugin that simplifies image uploading and processing
110
110
  email:
111
111
  - inge@elektronaut.no
@@ -116,10 +116,13 @@ files:
116
116
  - MIT-LICENSE
117
117
  - README.md
118
118
  - Rakefile
119
+ - app/models/dynamic_image/variant.rb
120
+ - db/migrate/20190620160500_create_dynamic_image_variants.rb
119
121
  - lib/dynamic_image.rb
120
122
  - lib/dynamic_image/belongs_to.rb
121
123
  - lib/dynamic_image/controller.rb
122
124
  - lib/dynamic_image/digest_verifier.rb
125
+ - lib/dynamic_image/engine.rb
123
126
  - lib/dynamic_image/errors.rb
124
127
  - lib/dynamic_image/helper.rb
125
128
  - lib/dynamic_image/image_reader.rb
@@ -129,8 +132,8 @@ files:
129
132
  - lib/dynamic_image/model/dimensions.rb
130
133
  - lib/dynamic_image/model/transformations.rb
131
134
  - lib/dynamic_image/model/validations.rb
135
+ - lib/dynamic_image/model/variants.rb
132
136
  - lib/dynamic_image/processed_image.rb
133
- - lib/dynamic_image/railtie.rb
134
137
  - lib/dynamic_image/routing.rb
135
138
  - lib/dynamic_image/templates/show.html.erb
136
139
  - lib/dynamic_image/version.rb
@@ -147,15 +150,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
147
150
  requirements:
148
151
  - - ">="
149
152
  - !ruby/object:Gem::Version
150
- version: 1.9.2
153
+ version: 2.4.0
151
154
  required_rubygems_version: !ruby/object:Gem::Requirement
152
155
  requirements:
153
156
  - - ">="
154
157
  - !ruby/object:Gem::Version
155
158
  version: '0'
156
159
  requirements: []
157
- rubyforge_project:
158
- rubygems_version: 2.7.6
160
+ rubygems_version: 3.0.1
159
161
  signing_key:
160
162
  specification_version: 4
161
163
  summary: Rails plugin that simplifies image uploading and processing