easyimg_utils 0.6.4 → 0.7.2

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: e12a8d7ad03689334172c8068730efef5acd22474b4f3b3a0d0f73994fa6f0c3
4
- data.tar.gz: a2e24819dc0efd620fa16797286034f0cce333d1ef360eb6bb2e6a4b106ca36e
3
+ metadata.gz: c09e7c063bbd8a5c1060c74338346317b3432f46e53a0e3cdc6e0d4a64553520
4
+ data.tar.gz: 8d73c424b106e51dea74394557e601b8ea78bfca66fd43bf80a10088527ba726
5
5
  SHA512:
6
- metadata.gz: 2d5acd5bfef69e8cec1dc304f92e440070be9412d189fee2ce6d6c2b884593d9776b1bf04978dd572d62aea372fc0f636c6bf68c5dfd5338dcafbb9742647620
7
- data.tar.gz: 4ea3afa5a48559a84d38e7806cf7ab27b3827ffcd1f6d2ef9cfbe0240f0d06e71987e9b2ef9316a2b510f8584ad605c67aa0512e41bd973c745d9c82ede407b1
6
+ metadata.gz: 602af329751d96be2d89a4b6487d35d9c1920a4e56fb8d5330014e8e924b0edb44db1f74bd926224bcf3ee62435cba1b3b209ccea1f2301b0618a299534702b9
7
+ data.tar.gz: abd50555f42ad809647180e58325578951b653f545fc7411c8b58e3132625ff90e82666509d1933ecf75d48409437b27dad9718fa60a4183c4d0174bc85e0fa5
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
@@ -88,12 +93,21 @@ class EasyImgUtils
88
93
  end
89
94
 
90
95
  # e.g. calc_resize '1449x1932', '640x480' #=> 480x640
96
+ # e.g. calc_resize '518x1024', '*518x500' #=> "518x1024"
97
+ # the asterisk denotes a guaranteed the image will be resized using x or y
91
98
  #
92
- def self.calc_resize(s, s2)
99
+ def self.calc_resize(geometry, new_geometry, force: false)
93
100
 
94
- a = s.split('x',2).map(&:to_i)
95
- a2 = s2.split('x',2).map(&:to_i)
96
- i = a.index a.max
101
+ xy = geometry.split('x',2)
102
+ xy2 = new_geometry.split('x',2)
103
+
104
+ # find any locked geometry which guarantees the resize on either x or y
105
+ lock = xy2.find {|x| x =~ /^\*/}
106
+
107
+ a = xy.map {|x| x[/\d+/].to_i}
108
+ a2 = xy2.map {|x| x[/\d+/].to_i}
109
+
110
+ i = lock ? a2.index(lock[1..-1].to_i) : a.index(a.max)
97
111
 
98
112
  factor = a2[i] / a[i].to_f
99
113
 
@@ -162,6 +176,41 @@ class EasyImgUtils
162
176
 
163
177
  end
164
178
 
179
+ # Used where images are perhaps cropped using CSS to a letterbox size image.
180
+ # Works best with portrait mode photos of selfies or natural
181
+ # landscapes with a lot of sky
182
+ #
183
+ # Returns the starting y pos as a percentage of the image using face
184
+ # detection and high contrast detection on the y-axis
185
+ #
186
+ def best_viewport()
187
+
188
+ percentage = 0
189
+
190
+ read() do |img|
191
+
192
+ found = faces()
193
+
194
+ index = if found.any? then
195
+
196
+ # find the top y
197
+ box = found.max_by {|x, y, width, height| y}
198
+ box[1]
199
+
200
+ else
201
+
202
+ y_maxcontrast(img)
203
+
204
+ end
205
+
206
+ percentage = (100 / (img.rows / index.to_f)).round
207
+
208
+ end
209
+
210
+ return percentage
211
+
212
+ end
213
+
165
214
  def blur(x: 0, y: 0, w: 80, h: 80, strength: 8, quality: nil)
166
215
 
167
216
  width, height = w, h
@@ -295,6 +344,10 @@ class EasyImgUtils
295
344
 
296
345
  end
297
346
 
347
+ def faces()
348
+ DetectFaces.new(@file_in).faces
349
+ end
350
+
298
351
  def fax_effect(threshold: 0.55, quality: nil)
299
352
 
300
353
  read() do |img|
@@ -343,8 +396,10 @@ class EasyImgUtils
343
396
 
344
397
  # defines the maximum size of an image while maintaining aspect ratio
345
398
  #
346
- def resize(geometry='320x240', quality: nil)
399
+ def resize(raw_geometry='320x240', quality: nil)
347
400
 
401
+ geometry = calc_resize(raw_geometry
402
+ )
348
403
  read() do |preview|
349
404
 
350
405
  preview.change_geometry!(geometry) do |cols, rows, img|
@@ -464,7 +519,7 @@ class EasyImgUtils
464
519
 
465
520
  end
466
521
 
467
- alias feathered_around vignette
522
+ alias feathered_around vignette
468
523
 
469
524
  private
470
525
 
@@ -534,5 +589,31 @@ class EasyImgUtils
534
589
 
535
590
  end
536
591
  end
592
+
593
+ # returns the y index of the pixel containing the most contrast using the
594
+ # y-axis center of the image
595
+ #
596
+ def y_maxcontrast(img)
537
597
 
598
+ rows, cols = img.rows, img.columns
599
+ center = (cols / 2).round
600
+ pixels = img.get_pixels(center,0,1,rows)
601
+
602
+ rgb = []
603
+ px = pixels[0]
604
+ rgb = [px.red, px.green, px.blue].map { |v| 255*(v/65535.0) }
605
+
606
+ a = pixels[1..-1].map do |pixel,i|
607
+
608
+ c = [pixel.red, pixel.green, pixel.blue].map { |v| 255*(v/65535.0) }
609
+ rgb[0] - c[0]
610
+ rgb.map.with_index {|x,i| (x - c[i]).abs.to_i}
611
+
612
+ end
613
+
614
+ a2 = a.map(&:sum)
615
+ a2.index(a2.max) + 1
616
+
617
+ end
618
+
538
619
  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.4
4
+ version: 0.7.2
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-20 00:00:00.000000000 Z
38
+ date: 2021-03-23 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