easyimg_utils 0.6.6 → 0.7.4

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: 4d9ac6449342efa070a858c26d96378947ca77231bcdc97339321b5dac0a316b
4
- data.tar.gz: 22617abf8420c0cf4276e2198e02cae542aa29555d8579fcd66c60127e70afbe
3
+ metadata.gz: 491f7066a8af2e40049a6986c894498d507d99b2b02caf4321f59abb25a05dd1
4
+ data.tar.gz: e6d42410ed62a4a0829c648b5622b28845930fa18853202e6ac507d0e7e34186
5
5
  SHA512:
6
- metadata.gz: 947e70b56bfeb36bf1c4d0e51bf5ba02bca9124083d46c27a55dd2669fcc3b06dbbfc48c9e2b0acfc6f42db89d6c71df1a125e30b6ff0d1f8431a5c535234828
7
- data.tar.gz: a19e9e5da426cf4ab50f7040419158c30fede078f8545c6f6fa7e4fb4a3d3b2dfdcd3e41ebdce4ee3e43e6dfba2f8d75a76262e516190f7e8ee2ee0f45c4e41d
6
+ metadata.gz: 57a595c6b1b171e44600bcdd043a36f90ce89453fc5d57e40fd8016a5f6518be8753c247bd613b2e5318ee6db05ababb9735a0c47b928775b96a4ef5bd99dac0
7
+ data.tar.gz: aa6f56c7307732c2f4f93f2298d32d0e2de8d164a2cee099f5ebdc18e433bccb162e43c5b3bd2e4ad9d2c87d0398c131531d10dcceb8099bbce4873d19d5fd19
checksums.yaml.gz.sig CHANGED
Binary file
data.tar.gz.sig CHANGED
Binary file
data/lib/easyimg_utils.rb CHANGED
@@ -7,6 +7,7 @@ require 'x4ss'
7
7
  require 'rmagick'
8
8
  require 'webp_ffi'
9
9
  require 'rxfhelper'
10
+ require 'detectfaces'
10
11
 
11
12
  # requirements:
12
13
  #
@@ -19,6 +20,8 @@ require 'rxfhelper'
19
20
  # webp-ffi dependencies
20
21
  # apt-get install libjpeg-dev libpng-dev libtiff-dev libwebp-dev
21
22
  #
23
+ # detectfaces dependencies
24
+ # apt-get install libopencv-dev
22
25
 
23
26
 
24
27
 
@@ -54,6 +57,7 @@ class EasyImgUtils
54
57
  * add_svg # adds an SVG transparency overlay. usage: add_svg('/tmp/image1.svg')
55
58
  * add_text # e.g. add_text('some text')
56
59
  * animate Creates an animated gif e.g. animate('/tmp/a%d.png', '/tmp/b.gif')
60
+ * best_viewport # returns the best viewing region on the y-axis
57
61
  * blur # e.g. blur(x: 231, y: 123, w: 85, h: 85)
58
62
  * capture_screen # takes a screenshot of the desktop
59
63
  * calc_resize # e.g. calc_resize '640x480' #=> 640x491
@@ -63,6 +67,7 @@ class EasyImgUtils
63
67
  * convert # convert from 1 img format to another
64
68
  * crop # e.g. crop(x: 231, y: 123, w: 85, h: 85)
65
69
  * fax_effect # Produces a high-contrast, two colour image
70
+ * faces # Returns an array of bounding boxes for detected faces
66
71
  * greyscale # Reduces the image to 256 shades of grey
67
72
  * info # returns the dimension of the image in a Hash object
68
73
  * make_thumbnail # similar to resize but faster for sizes less than 10% of original image
@@ -89,20 +94,35 @@ class EasyImgUtils
89
94
 
90
95
  # e.g. calc_resize '1449x1932', '640x480' #=> 480x640
91
96
  # e.g. calc_resize '518x1024', '*518x500' #=> "518x1024"
92
- # the asterisk denotes a guaranteed the image will be resized using x or y
97
+ # the asterisk denotes a guarantee the image will be resized to a
98
+ # minimum size on either dimension
93
99
  #
94
- def self.calc_resize(geometry, new_geometry, force: false)
100
+ # e.g. calc_resize '1920x1088', '*518x*500' #=> "882x500"
101
+ # 2 asterisks denotes a guaranteed minumum size on both dimensions
102
+ #
103
+ def self.calc_resize(geometry, new_geometry)
95
104
 
96
105
  xy = geometry.split('x',2)
97
106
  xy2 = new_geometry.split('x',2)
98
107
 
99
108
  # find any locked geometry which guarantees the resize on either x or y
100
- lock = xy2.find {|x| x =~ /^\*/}
109
+ locks = xy2.select {|x| x =~ /^\*/}
101
110
 
102
111
  a = xy.map {|x| x[/\d+/].to_i}
103
112
  a2 = xy2.map {|x| x[/\d+/].to_i}
113
+
114
+ i = if locks.length > 1 then
104
115
 
105
- i = lock ? a2.index(lock[1..-1].to_i) : a.index(a.max)
116
+ a.index(a.min)
117
+
118
+ elsif locks.any?
119
+
120
+ lock = locks.first
121
+ a2.index(lock[1..-1].to_i)
122
+
123
+ else
124
+ a.index(a.max)
125
+ end
106
126
 
107
127
  factor = a2[i] / a[i].to_f
108
128
 
@@ -171,6 +191,42 @@ class EasyImgUtils
171
191
 
172
192
  end
173
193
 
194
+ # Used where images are perhaps cropped using CSS to a letterbox size image.
195
+ # Works best with portrait mode photos of selfies or natural
196
+ # landscapes with a lot of sky
197
+ #
198
+ # Returns the starting y pos as a percentage of the image using face
199
+ # detection and high contrast detection on the y-axis
200
+ #
201
+ def best_viewport()
202
+
203
+ percentage = 0
204
+
205
+ read() do |img|
206
+
207
+ found = faces()
208
+
209
+ index = if found.any? then
210
+
211
+ # find the top y
212
+ box = found.max_by {|x, y, width, height| y}
213
+ y, height = box.values_at 1, 3
214
+ y - (height / 2)
215
+
216
+ else
217
+
218
+ y_maxcontrast(img)
219
+
220
+ end
221
+
222
+ percentage = (100 / (img.rows / index.to_f)).round
223
+
224
+ end
225
+
226
+ return percentage
227
+
228
+ end
229
+
174
230
  def blur(x: 0, y: 0, w: 80, h: 80, strength: 8, quality: nil)
175
231
 
176
232
  width, height = w, h
@@ -304,6 +360,10 @@ class EasyImgUtils
304
360
 
305
361
  end
306
362
 
363
+ def faces()
364
+ DetectFaces.new(@file_in).faces
365
+ end
366
+
307
367
  def fax_effect(threshold: 0.55, quality: nil)
308
368
 
309
369
  read() do |img|
@@ -475,7 +535,7 @@ class EasyImgUtils
475
535
 
476
536
  end
477
537
 
478
- alias feathered_around vignette
538
+ alias feathered_around vignette
479
539
 
480
540
  private
481
541
 
@@ -545,5 +605,37 @@ class EasyImgUtils
545
605
 
546
606
  end
547
607
  end
608
+
609
+ # returns the y index of the pixel containing the most contrast using the
610
+ # y-axis center of the image
611
+ #
612
+ def y_maxcontrast(img)
548
613
 
614
+ rows, cols = img.rows, img.columns
615
+ center = (cols / 2).round
616
+ pixels = img.get_pixels(center,0,1,rows)
617
+
618
+ rgb = []
619
+ px = pixels[0]
620
+ rgb = [px.red, px.green, px.blue].map { |v| 255*(v/65535.0) }
621
+
622
+ a = pixels[1..-1].map do |pixel,i|
623
+
624
+ c = [pixel.red, pixel.green, pixel.blue].map { |v| 255*(v/65535.0) }
625
+ rgb[0] - c[0]
626
+ rgb.map.with_index {|x,i| (x - c[i]).abs.to_i}
627
+
628
+ end
629
+
630
+ a2 = a.map(&:sum)
631
+ puts 'a2: ' + a2.inspect if @debug
632
+ #a2.index(a2.max) + 1
633
+ # attempt to detect the 1st occurrence of contrast
634
+ r = a2.detect {|x| x > 600}
635
+ # otherwise select any occurrence of high contrast
636
+ r = a2.max unless r
637
+ a2.index(r) + 1
638
+
639
+ end
640
+
549
641
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: easyimg_utils
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.6
4
+ version: 0.7.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Robertson
@@ -35,7 +35,7 @@ cert_chain:
35
35
  KY48n99T12IOioQ4ghCO1L/UAg2taLOcZbMv4WpV1p9bXKhnrow81zeogZjjiNGS
36
36
  OmTAjCfyGFPC/1eXnSV5Smv8
37
37
  -----END CERTIFICATE-----
38
- date: 2021-03-22 00:00:00.000000000 Z
38
+ date: 2021-03-30 00:00:00.000000000 Z
39
39
  dependencies:
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: rmagick
@@ -117,6 +117,26 @@ dependencies:
117
117
  - - "~>"
118
118
  - !ruby/object:Gem::Version
119
119
  version: '0.2'
120
+ - !ruby/object:Gem::Dependency
121
+ name: detectfaces
122
+ requirement: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: 0.1.0
127
+ - - "~>"
128
+ - !ruby/object:Gem::Version
129
+ version: '0.1'
130
+ type: :runtime
131
+ prerelease: false
132
+ version_requirements: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ version: 0.1.0
137
+ - - "~>"
138
+ - !ruby/object:Gem::Version
139
+ version: '0.1'
120
140
  description:
121
141
  email: digital.robertson@gmail.com
122
142
  executables: []
metadata.gz.sig CHANGED
Binary file