neofiles 1.0.4 → 1.0.5

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: d227855f99ea74fc7b13a202cca5d72689fd554c
4
- data.tar.gz: 48e527165016fd379303bcca7913cb236b422f4e
3
+ metadata.gz: aa7c4f908b80a9d8ba5b307b8530d61aca743fe4
4
+ data.tar.gz: 6777e03478b6e518aa531238d2ef8b4a9922512d
5
5
  SHA512:
6
- metadata.gz: b3d5d75d416021bb11f6c21cd60f807341198695080929c68fca7cde77a56740393310633850e7aa5972720642d6ba2210534d90be3ad74c11123c76b2d861b1
7
- data.tar.gz: 18814fd631099783c7f05f37a9bdab996a3a47b67d540aaef16d736a83123da08cd2cd618e32f6bdfe6146a6faf0bf318fc488c193675c17a8db735e195d792d
6
+ metadata.gz: 347e357315fcfd834992b69f2e802fdd96602d0e4ce3e57a733d9061dc1bb39958b936546d4fe04119affffee6bc30d9c4b5c86055a6fba555cb09adffe2ff0d
7
+ data.tar.gz: a38625dcf3f94134b783150b9d626a12d42f94cad746554789812c266ba91f4cba1a7131c829beb9c8fa29f9be0563719d3ad75077073d190e2af1ccb8bc87c2
data/README.md CHANGED
@@ -76,6 +76,7 @@ Add Neofiles and its dependencies to your gemfile:
76
76
  gem 'neofiles'
77
77
  gem 'ruby-imagespec', git: 'git://github.com/dim/ruby-imagespec.git'
78
78
  gem 'mini_magick', '3.7.0'
79
+ gem 'png_quantizator', '0.2.1'
79
80
  ```
80
81
 
81
82
  ***ruby-imagespec*** is needed to get an image file dimensions & content type.
@@ -83,6 +84,9 @@ gem 'mini_magick', '3.7.0'
83
84
  ***mini_magick*** does resizing & watermarking. Actually it is a lightweight wrapper around command-line utility
84
85
  ImageMagick, which must be installed also. Refer to the gem's description for installation instructions.
85
86
 
87
+ ***png_quantizator*** does lossless PNG compression. Actually it is a lightweight wrapper around command-line utility
88
+ Pngquant, which must be installed also. Refer to the gem's description for installation instructions.
89
+
86
90
  Also, you must have installed MongoDB with its default driver ***mongoid*** (5 version at least) and Rails framework
87
91
  with HAML templating engine. By default the gem needs `neofiles` mongoid client defined in `config/mongoid.yml`, which
88
92
  can be changed in ***Configuration*** section.
@@ -1,3 +1,5 @@
1
+ require 'png_quantizator'
2
+
1
3
  # Special controller for serving images from the database via single action #show.
2
4
  #
3
5
  class Neofiles::ImagesController < ActionController::Metal
@@ -21,9 +23,10 @@ class Neofiles::ImagesController < ActionController::Metal
21
23
  # format - resize image to no more than that size, example: '100x200'
22
24
  # crop - if '1' and params[:format] is present, then cut image sides if its aspect ratio differs from
23
25
  # params[:format] (otherwise image aspect ration will be preserved)
24
- # quality - output JPEG quality, integer from 1 till 100 (forces JPEG output, otherwise image type is preserved)
26
+ # quality - output quality, integer from 1 till 100 for JPEG input, default is 75
27
+ # for PNG input any value less than 75 triggers lossless compression using pngquant library
25
28
  # nowm - force returned image to not contain watermark - user must be admin or 403 Forbidden response is returned
26
- # @see #admin_or_die
29
+ # @see #admin_or_die (also this removes the default quality to let admins download image originals)
27
30
  #
28
31
  # Maximum allowed format dimensions are set via Rails.application.config.neofiles.image_max_crop_width/height.
29
32
  #
@@ -31,77 +34,41 @@ class Neofiles::ImagesController < ActionController::Metal
31
34
  # Rails.application.config.neofiles.watermarker if present.
32
35
  #
33
36
  def show
34
-
35
37
  # get image
36
38
  image_file = Neofiles::Image.find params[:id]
37
39
 
38
40
  # prepare headers
39
41
  data = image_file.data
40
42
  options = {
41
- filename: CGI::escape(image_file.filename),
42
- type: image_file.content_type || 'image/jpeg',
43
- disposition: 'inline',
43
+ filename: CGI::escape(image_file.filename),
44
+ type: image_file.content_type || 'image/jpeg',
45
+ disposition: 'inline',
44
46
  }
47
+ quality = [[Neofiles::quality_requested(params), 100].min, 1].max if Neofiles::quality_requested?(params)
48
+ quality ||= 75 unless nowm?(image_file)
45
49
 
46
- # is resizing needed?
47
- watermark_image, watermark_width, watermark_height = data, image_file.width, image_file.height
48
- if params[:format].present?
50
+ image = MiniMagick::Image.read(data)
49
51
 
52
+ if params[:format].present?
50
53
  width, height = params[:format].split('x').map(&:to_i)
51
- watermark_width, watermark_height = width, height
52
54
  raise Mongoid::Errors::DocumentNotFound unless width.between?(1, CROP_MAX_WIDTH) and height.between?(1, CROP_MAX_HEIGHT)
55
+ end
53
56
 
54
- quality = [[Neofiles::quality_requested(params), 100].min, 1].max if Neofiles::quality_requested?(params)
55
- setting_quality = quality && options[:type] == 'image/jpeg'
56
-
57
- image = MiniMagick::Image.read(data)
58
-
59
- if Neofiles.crop_requested? params
60
- # construct ImageMagick call:
61
- # 1) resize to WxH, allow the result to be bigger on one side
62
- # 2) allign resized to center
63
- # 3) cut the extending parts
64
- # 4) set quality if requested
65
- image.combine_options do |c|
66
- c.resize "#{width}x#{height}^"
67
- c.gravity 'center'
68
- c.extent "#{width}x#{height}"
69
- c.quality "#{quality}" if setting_quality
70
- end
71
- else
72
- # no cropping so just resize to fit in WxH, one side can be smaller than requested
73
- if image_file.width > width || image_file.height > height
74
- image.combine_options do |c|
75
- c.resize "#{width}x#{height}"
76
- c.quality "#{quality}" if setting_quality
77
- end
78
- else
79
- setting_quality = false
80
- watermark_width, watermark_height = image_file.width, image_file.height
81
- end
82
- end
83
-
84
- # quality requested, but we didn't have a chance to set it before -> forcibly resave as JPEG
85
- if quality && !setting_quality
86
- image.format 'jpeg'
87
- image.quality quality.to_s
88
- end
89
-
90
- # get image bytes and stuff
91
- data = image.to_blob
92
- watermark_image = image
93
- options[:type] = image.mime_type
57
+ crop_requested = Neofiles.crop_requested? params
58
+ need_resize_without_crop = width && height && (image_file.width > width || image_file.height > height)
59
+
60
+ image.combine_options do |mogrify|
61
+ resize_image(mogrify, width, height, crop_requested, need_resize_without_crop) if width && height
62
+ compress_image(mogrify, quality) if quality
94
63
  end
95
64
 
96
- watermark_image = MiniMagick::Image.read watermark_image unless watermark_image.is_a? MiniMagick::Image
65
+ # use pngquant when quality less than 75
66
+ ::PngQuantizator::Image.new(image.path).quantize! if options[:type] == 'image/png' && quality && quality < 75
97
67
 
98
68
  # set watermark
99
- data = Rails.application.config.neofiles.watermarker.(
100
- watermark_image,
101
- no_watermark: nowm?(image_file),
102
- watermark_width: watermark_width,
103
- watermark_height: watermark_height
104
- )
69
+ width, height = image_file.width, image_file.height if !crop_requested && !need_resize_without_crop
70
+
71
+ data = set_watermark(image, image_file, width, height)
105
72
 
106
73
  # stream image headers & bytes
107
74
  send_file_headers! options
@@ -132,4 +99,43 @@ class Neofiles::ImagesController < ActionController::Metal
132
99
  raise NotAdminException
133
100
  end
134
101
  end
135
- end
102
+
103
+ # Fill mogrify command pipe with resize commands
104
+ def resize_image(mogrify, width, height, crop_requested, need_resize_without_crop)
105
+ if crop_requested
106
+ mogrify.resize "#{width}x#{height}^"
107
+ mogrify.gravity 'center'
108
+ mogrify.extent "#{width}x#{height}"
109
+ elsif need_resize_without_crop
110
+ mogrify.resize "#{width}x#{height}"
111
+ end
112
+ end
113
+
114
+ # Fill mogrify command pipe with compression commands for JPEG and PNG
115
+ # More information: https://www.smashingmagazine.com/2015/06/efficient-image-resizing-with-imagemagick/
116
+ def compress_image(mogrify, quality)
117
+ mogrify.quality "#{quality}"
118
+ mogrify << '-unsharp' << '0.25x0.25+8+0.065'
119
+ mogrify << '-dither' << 'None'
120
+ mogrify << '-posterize' << '136'
121
+ mogrify << '-define' << 'jpeg:fancy-upsampling=off'
122
+ mogrify << '-define' << 'png:compression-filter=5'
123
+ mogrify << '-define' << 'png:compression-level=9'
124
+ mogrify << '-define' << 'png:compression-strategy=1'
125
+ mogrify << '-define' << 'png:exclude-chunk=all'
126
+ mogrify << '-interlace' << 'none'
127
+ mogrify << '-colorspace' << 'sRGB'
128
+ mogrify.strip
129
+ end
130
+
131
+ # Place watermark on the image, if needed
132
+ def set_watermark(image, image_file, width, height)
133
+ Rails.application.config.neofiles.watermarker.(
134
+ image,
135
+ no_watermark: nowm?(image_file),
136
+ watermark_width: width,
137
+ watermark_height: height
138
+ )
139
+ end
140
+
141
+ end
@@ -1,3 +1,3 @@
1
1
  module Neofiles
2
- VERSION = '1.0.4'
2
+ VERSION = '1.0.5'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: neofiles
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.4
4
+ version: 1.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Konanykhin Ilya
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-01-11 00:00:00.000000000 Z
11
+ date: 2017-02-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - '='
67
67
  - !ruby/object:Gem::Version
68
68
  version: 3.7.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: png_quantizator
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '='
74
+ - !ruby/object:Gem::Version
75
+ version: 0.2.1
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '='
81
+ - !ruby/object:Gem::Version
82
+ version: 0.2.1
69
83
  description: 'Library for managing files: creating & storing, linking to file owners,
70
84
  serving files from MongoDB'
71
85
  email: