dynamic_image 2.0.2 → 2.0.3

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
  SHA1:
3
- metadata.gz: dee05cad2916e34c6f71212ac5cc79aca2c40caf
4
- data.tar.gz: 4e7eb46f42e851d3872f8733d033519bdc059167
3
+ metadata.gz: d1600a4e263630c8a9936e6f8309add967434b81
4
+ data.tar.gz: 1ad5ff2c9b894a0fd774797cc64395ed72d7b556
5
5
  SHA512:
6
- metadata.gz: 3078b6597ecd6ccc2b01a6724c06850517f266bfc7e71087bd7f4c1e22fccc107d4554062aa58fac90f47a2b46f70b00aca8e0d870bf9341117649eee2bddbd4
7
- data.tar.gz: 30aeeb19d93a6dac8de7aec60ac06fa4d287410bbc4231fcfadb51efbb59d05b1d0ba4d831f68c6a97132af3979d3c46d71cdba119401b8337b32ad882ce037a
6
+ metadata.gz: 6f60bf400b04b6c8b9b7fe9d59ea967796bd58171fbf258ba326349e128bd35bd50cbe49b779a82e6d7d3db0f70636ff7808d79dae2a1f0d1a4f15b96516bf00
7
+ data.tar.gz: 74063c221b4948e5121f0be2f5b6a8244ed4bb25b9c3a44609cfcab902e648ccfee69697b060bdda5186183061ad950f2e71b9e382d674939d7b1367953b7f20
data/Rakefile CHANGED
@@ -1,8 +1,8 @@
1
- require 'bundler/gem_tasks'
2
- require 'rspec/core/rake_task'
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
3
 
4
- APP_RAKEFILE = 'spec/internal/Rakefile'.freeze
5
- load 'rails/tasks/engine.rake'
4
+ APP_RAKEFILE = "spec/internal/Rakefile".freeze
5
+ load "rails/tasks/engine.rake"
6
6
 
7
7
  RSpec::Core::RakeTask.new
8
8
 
data/lib/dynamic_image.rb CHANGED
@@ -1,21 +1,21 @@
1
1
  # encoding: utf-8
2
2
 
3
- require 'mini_magick'
4
- require 'dis'
5
- require 'vector2d'
3
+ require "mini_magick"
4
+ require "dis"
5
+ require "vector2d"
6
6
 
7
- require 'dynamic_image/belongs_to'
8
- require 'dynamic_image/controller'
9
- require 'dynamic_image/digest_verifier'
10
- require 'dynamic_image/errors'
11
- require 'dynamic_image/helper'
12
- require 'dynamic_image/image_reader'
13
- require 'dynamic_image/image_sizing'
14
- require 'dynamic_image/metadata'
15
- require 'dynamic_image/model'
16
- require 'dynamic_image/processed_image'
17
- require 'dynamic_image/railtie'
18
- require 'dynamic_image/routing'
7
+ require "dynamic_image/belongs_to"
8
+ require "dynamic_image/controller"
9
+ require "dynamic_image/digest_verifier"
10
+ require "dynamic_image/errors"
11
+ require "dynamic_image/helper"
12
+ require "dynamic_image/image_reader"
13
+ require "dynamic_image/image_sizing"
14
+ require "dynamic_image/metadata"
15
+ require "dynamic_image/model"
16
+ require "dynamic_image/processed_image"
17
+ require "dynamic_image/railtie"
18
+ require "dynamic_image/routing"
19
19
 
20
20
  module DynamicImage
21
21
  cattr_accessor :digest_verifier
@@ -35,7 +35,7 @@ module DynamicImage
35
35
  send_data(
36
36
  @record.data,
37
37
  content_type: @record.content_type,
38
- disposition: 'inline'
38
+ disposition: "inline"
39
39
  )
40
40
  end
41
41
  end
@@ -60,7 +60,7 @@ module DynamicImage
60
60
  return unless stale?(@record)
61
61
  respond_to do |format|
62
62
  format.html do
63
- render(file: File.join(File.dirname(__FILE__), 'templates/show'),
63
+ render(file: File.join(File.dirname(__FILE__), "templates/show"),
64
64
  layout: false, locals: { options: options })
65
65
  end
66
66
  format.any(:gif, :jpeg, :png, :tiff) do
@@ -77,14 +77,14 @@ module DynamicImage
77
77
  send_data(
78
78
  image.cropped_and_resized(requested_size),
79
79
  content_type: image.content_type,
80
- disposition: 'inline'
80
+ disposition: "inline"
81
81
  )
82
82
  end
83
83
 
84
84
  def verify_signed_params
85
85
  key = [:action, :id, :size].map do |k|
86
86
  k == :id ? params.require(k).to_i : params.require(k)
87
- end.join('-')
87
+ end.join("-")
88
88
  DynamicImage.digest_verifier.verify(key, params[:digest])
89
89
  end
90
90
  end
@@ -20,7 +20,7 @@ module DynamicImage
20
20
  class DigestVerifier
21
21
  def initialize(secret, options = {})
22
22
  @secret = secret
23
- @digest = options[:digest] || 'SHA1'
23
+ @digest = options[:digest] || "SHA1"
24
24
  end
25
25
 
26
26
  # Generates a digest for a string.
@@ -47,11 +47,11 @@ module DynamicImage
47
47
 
48
48
  res = 0
49
49
  b.each_byte { |byte| res |= byte ^ l.shift }
50
- res == 0
50
+ res.zero?
51
51
  end
52
52
 
53
53
  def generate_digest(data)
54
- require 'openssl' unless defined?(OpenSSL)
54
+ require "openssl" unless defined?(OpenSSL)
55
55
  OpenSSL::HMAC.hexdigest(
56
56
  OpenSSL::Digest.const_get(@digest).new,
57
57
  @secret,
@@ -7,5 +7,6 @@ module DynamicImage
7
7
  class InvalidHeader < DynamicImage::Errors::Error; end
8
8
  class InvalidSignature < DynamicImage::Errors::Error; end
9
9
  class InvalidSizeOptions < DynamicImage::Errors::Error; end
10
+ class InvalidTransformation < DynamicImage::Errors::Error; end
10
11
  end
11
12
  end
@@ -115,7 +115,7 @@ module DynamicImage
115
115
  end
116
116
 
117
117
  def dynamic_image_digest(record, action, size = nil)
118
- key = [action || 'show', record.id, size].compact.join('-')
118
+ key = [action || "show", record.id, size].compact.join("-")
119
119
  DynamicImage.digest_verifier.generate(key)
120
120
  end
121
121
 
@@ -152,9 +152,9 @@ module DynamicImage
152
152
  action = options[:action].try(:to_s)
153
153
  size_opts = options.extract!(:size, :crop, :upscale)
154
154
  if size_opts[:size]
155
- image_sizing(record, size_opts, (action == 'uncropped'))
155
+ image_sizing(record, size_opts, (action == "uncropped"))
156
156
  else
157
- (action == 'original' ? record.real_size : record.size).floor.to_s
157
+ (action == "original" ? record.real_size : record.size).floor.to_s
158
158
  end
159
159
  end
160
160
 
@@ -27,21 +27,36 @@ module DynamicImage
27
27
  @file_header ||= StringIO.new(@data, "rb").read(10)
28
28
  end
29
29
 
30
- def magic_bytes
30
+ def gif_magic_bytes
31
31
  [
32
- # GIF
33
32
  "\x47\x49\x46\x38\x37\x61".force_encoding("binary"),
34
- "\x47\x49\x46\x38\x39\x61".force_encoding("binary"),
35
- # PNG
36
- "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a".force_encoding("binary"),
37
- # JPEG
33
+ "\x47\x49\x46\x38\x39\x61".force_encoding("binary")
34
+ ]
35
+ end
36
+
37
+ def jpeg_magic_bytes
38
+ [
38
39
  "\xff\xd8\xff\xdb".force_encoding("binary"),
39
40
  Regexp.new("\xff\xd8\xff\xe0(.*){2}JFIF".force_encoding("binary")),
40
41
  Regexp.new("\xff\xd8\xff\xe1(.*){2}Exif".force_encoding("binary")),
41
- "\xff\xd8\xff\xee\x00\x0e".force_encoding("binary"), # Adobe JPEG
42
- # TIFF
42
+ "\xff\xd8\xff\xee\x00\x0e".force_encoding("binary") # Adobe JPEG
43
+ ]
44
+ end
45
+
46
+ def magic_bytes
47
+ gif_magic_bytes + png_magic_bytes + jpeg_magic_bytes + tiff_magic_bytes
48
+ end
49
+
50
+ def png_magic_bytes
51
+ [
52
+ "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a".force_encoding("binary")
53
+ ]
54
+ end
55
+
56
+ def tiff_magic_bytes
57
+ [
43
58
  "\x49\x49\x2a\x00".force_encoding("binary"),
44
- "\x4d\x4d\x00\x2a".force_encoding("binary"),
59
+ "\x4d\x4d\x00\x2a".force_encoding("binary")
45
60
  ]
46
61
  end
47
62
  end
@@ -16,11 +16,11 @@ module DynamicImage
16
16
  if valid?
17
17
  case metadata[:colorspace]
18
18
  when /rgb/i
19
- 'rgb'
19
+ "rgb"
20
20
  when /cmyk/i
21
- 'cmyk'
21
+ "cmyk"
22
22
  when /gray/i
23
- 'gray'
23
+ "gray"
24
24
  end
25
25
  end
26
26
  end
@@ -1,7 +1,8 @@
1
1
  # encoding: utf-8
2
2
 
3
- require 'dynamic_image/model/dimensions'
4
- require 'dynamic_image/model/validations'
3
+ require "dynamic_image/model/dimensions"
4
+ require "dynamic_image/model/transformations"
5
+ require "dynamic_image/model/validations"
5
6
 
6
7
  module DynamicImage
7
8
  # = DynamicImage Model
@@ -62,6 +63,7 @@ module DynamicImage
62
63
  extend ActiveSupport::Concern
63
64
  include Dis::Model
64
65
  include DynamicImage::Model::Dimensions
66
+ include DynamicImage::Model::Transformations
65
67
  include DynamicImage::Model::Validations
66
68
 
67
69
  included do
@@ -70,17 +72,17 @@ module DynamicImage
70
72
 
71
73
  # Returns true if the image is in the CMYK colorspace
72
74
  def cmyk?
73
- colorspace == 'cmyk'
75
+ colorspace == "cmyk"
74
76
  end
75
77
 
76
78
  # Returns true if the image is in the grayscale colorspace
77
79
  def gray?
78
- colorspace == 'gray'
80
+ colorspace == "gray"
79
81
  end
80
82
 
81
83
  # Returns true if the image is in the RGB colorspace
82
84
  def rgb?
83
- colorspace == 'rgb'
85
+ colorspace == "rgb"
84
86
  end
85
87
 
86
88
  # Finds a web safe content type. GIF, JPEG and PNG images are allowed,
@@ -89,14 +91,14 @@ module DynamicImage
89
91
  if safe_content_types.include?(content_type)
90
92
  content_type
91
93
  else
92
- 'image/jpeg'
94
+ "image/jpeg"
93
95
  end
94
96
  end
95
97
 
96
98
  # Includes a timestamp fingerprint in the URL param, so
97
99
  # that rendered images can be cached indefinitely.
98
100
  def to_param
99
- [id, updated_at.utc.to_s(cache_timestamp_format)].join('-')
101
+ [id, updated_at.utc.to_s(cache_timestamp_format)].join("-")
100
102
  end
101
103
 
102
104
  private
@@ -0,0 +1,71 @@
1
+ # encoding: utf-8
2
+
3
+ module DynamicImage
4
+ module Model
5
+ # = DynamicImage Model Transformations
6
+ #
7
+ module Transformations
8
+ # Rotates the image
9
+ def rotate(degrees = 90)
10
+ degrees = degrees.to_i % 360
11
+
12
+ return self if degrees.zero?
13
+
14
+ if (degrees % 90).nonzero?
15
+ raise DynamicImage::Errors::InvalidTransformation,
16
+ "angle must be a multiple of 90 degrees"
17
+ end
18
+
19
+ transform_image do |image|
20
+ image.rotate(degrees)
21
+ rotate_dimensions(real_size.x, real_size.y, degrees)
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ def rotate_dimensions(width, height, degrees)
28
+ (degrees / 90).times do
29
+ width, height = height, width
30
+
31
+ self.real_width = width
32
+ self.real_height = height
33
+
34
+ self.crop_gravity_x, self.crop_gravity_y = rotated_crop_gravity(width)
35
+
36
+ next unless cropped?
37
+
38
+ self.crop_start_x, self.crop_start_y,
39
+ self.crop_width, self.crop_height = rotated_crop(width)
40
+ end
41
+ end
42
+
43
+ def rotated_crop(new_width)
44
+ return nil unless cropped?
45
+ [
46
+ new_width - (crop_start_y + crop_height),
47
+ crop_start_x,
48
+ crop_height,
49
+ crop_width
50
+ ]
51
+ end
52
+
53
+ def rotated_crop_gravity(new_width)
54
+ return nil unless crop_gravity?
55
+ [new_width - crop_gravity_y, crop_gravity_x]
56
+ end
57
+
58
+ def processed_image
59
+ DynamicImage::ProcessedImage.new(self, uncropped: true)
60
+ end
61
+
62
+ def transform_image
63
+ read_image_metadata if data_changed?
64
+ self.data = processed_image.normalized do |image|
65
+ yield(image) if block_given?
66
+ end
67
+ self
68
+ end
69
+ end
70
+ end
71
+ end
@@ -80,7 +80,7 @@ module DynamicImage
80
80
  def validate_crop_bounds
81
81
  required_size = crop_start + crop_size
82
82
  if required_size.x > real_size.x || required_size.y > real_size.y
83
- errors.add(:crop_size, 'is out of bounds')
83
+ errors.add(:crop_size, "is out of bounds")
84
84
  end
85
85
  end
86
86
 
@@ -10,7 +10,7 @@ module DynamicImage
10
10
  @record = record
11
11
  @uncropped = options[:uncropped] ? true : false
12
12
  @format = options[:format].to_s.upcase if options[:format]
13
- @format = 'JPEG' if defined?(@format) && @format == 'JPG'
13
+ @format = "JPEG" if defined?(@format) && @format == "JPG"
14
14
  end
15
15
 
16
16
  # Returns the content type of the processed image.
@@ -62,7 +62,7 @@ module DynamicImage
62
62
  process_data do |image|
63
63
  image.combine_options do |combined|
64
64
  combined.auto_orient
65
- combined.colorspace('sRGB') if needs_colorspace_conversion?
65
+ combined.colorspace("sRGB") if needs_colorspace_conversion?
66
66
  yield(combined) if block_given?
67
67
  optimize(combined)
68
68
  end
@@ -85,7 +85,7 @@ module DynamicImage
85
85
  end
86
86
 
87
87
  def gif?
88
- content_type == 'image/gif'
88
+ content_type == "image/gif"
89
89
  end
90
90
 
91
91
  def image_sizing
@@ -102,7 +102,7 @@ module DynamicImage
102
102
  end
103
103
 
104
104
  def optimize(image)
105
- image.layers 'optimize' if gif?
105
+ image.layers "optimize" if gif?
106
106
  image.strip
107
107
  end
108
108
 
@@ -118,14 +118,14 @@ module DynamicImage
118
118
 
119
119
  def record_format
120
120
  case record.content_type
121
- when 'image/png'
122
- 'PNG'
123
- when 'image/gif'
124
- 'GIF'
125
- when 'image/jpeg', 'image/pjpeg'
126
- 'JPEG'
127
- when 'image/tiff'
128
- 'TIFF'
121
+ when "image/png"
122
+ "PNG"
123
+ when "image/gif"
124
+ "GIF"
125
+ when "image/jpeg", "image/pjpeg"
126
+ "JPEG"
127
+ when "image/tiff"
128
+ "TIFF"
129
129
  end
130
130
  end
131
131
 
@@ -2,11 +2,11 @@
2
2
 
3
3
  module DynamicImage
4
4
  class Railtie < ::Rails::Railtie
5
- initializer 'dynamic_image' do
5
+ initializer "dynamic_image" do
6
6
  ActionDispatch::Routing::Mapper.send :include, DynamicImage::Routing
7
7
 
8
8
  config.after_initialize do |app|
9
- secret = app.key_generator.generate_key('dynamic_image')
9
+ secret = app.key_generator.generate_key("dynamic_image")
10
10
  DynamicImage.digest_verifier = DynamicImage::DigestVerifier.new(secret)
11
11
  end
12
12
 
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module DynamicImage
4
- VERSION = '2.0.2'.freeze
4
+ VERSION = "2.0.3".freeze
5
5
  end
@@ -1,12 +1,12 @@
1
1
  # encoding: utf-8
2
2
 
3
- require 'rails/generators'
4
- require 'rails/generators/rails/resource/resource_generator'
3
+ require "rails/generators"
4
+ require "rails/generators/rails/resource/resource_generator"
5
5
 
6
6
  module DynamicImage
7
7
  module Generators
8
8
  class ResourceGenerator < Rails::Generators::ResourceGenerator
9
- desc 'Creates a DynamicImage resource'
9
+ desc "Creates a DynamicImage resource"
10
10
 
11
11
  def initialize(args, *options)
12
12
  super(inject_dynamic_image_attributes(args), *options)
@@ -14,10 +14,9 @@ module DynamicImage
14
14
 
15
15
  def add_controller_extension
16
16
  inject_into_file(
17
- File.join(
18
- 'app/controllers',
19
- class_path,
20
- "#{file_name.pluralize}_controller.rb"),
17
+ File.join("app/controllers",
18
+ class_path,
19
+ "#{file_name.pluralize}_controller.rb"),
21
20
  after: "ApplicationController\n"
22
21
  ) do
23
22
  " include DynamicImage::Controller\n\n private\n\n" \
@@ -27,7 +26,7 @@ module DynamicImage
27
26
 
28
27
  def add_model_extension
29
28
  inject_into_file(
30
- File.join('app/models', class_path, "#{file_name}.rb"),
29
+ File.join("app/models", class_path, "#{file_name}.rb"),
31
30
  after: "ActiveRecord::Base\n"
32
31
  ) do
33
32
  " include DynamicImage::Model\n"
@@ -36,7 +35,7 @@ module DynamicImage
36
35
 
37
36
  def alter_resource_routes
38
37
  gsub_file(
39
- File.join('config', 'routes.rb'),
38
+ File.join("config", "routes.rb"),
40
39
  " resources :#{file_name.pluralize}",
41
40
  " image_resources :#{file_name.pluralize}"
42
41
  )
@@ -54,13 +53,13 @@ module DynamicImage
54
53
 
55
54
  def dynamic_image_attributes
56
55
  %w(
57
- content_hash:string content_type:string
56
+ content_hash:string content_type:string
58
57
  content_length:integer
59
58
  filename:string
60
59
  colorspace:string
61
- real_width:integer real_height:integer
62
- crop_width:integer crop_height:integer
63
- crop_start_x:integer crop_start_y:integer
60
+ real_width:integer real_height:integer
61
+ crop_width:integer crop_height:integer
62
+ crop_start_x:integer crop_start_y:integer
64
63
  crop_gravity_x:integer crop_gravity_y:integer
65
64
  )
66
65
  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.2
4
+ version: 2.0.3
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: 2016-08-01 00:00:00.000000000 Z
11
+ date: 2016-08-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -127,6 +127,7 @@ files:
127
127
  - lib/dynamic_image/metadata.rb
128
128
  - lib/dynamic_image/model.rb
129
129
  - lib/dynamic_image/model/dimensions.rb
130
+ - lib/dynamic_image/model/transformations.rb
130
131
  - lib/dynamic_image/model/validations.rb
131
132
  - lib/dynamic_image/processed_image.rb
132
133
  - lib/dynamic_image/railtie.rb