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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/lib/easyimg_utils.rb +97 -5
- metadata +22 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 491f7066a8af2e40049a6986c894498d507d99b2b02caf4321f59abb25a05dd1
|
4
|
+
data.tar.gz: e6d42410ed62a4a0829c648b5622b28845930fa18853202e6ac507d0e7e34186
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
97
|
+
# the asterisk denotes a guarantee the image will be resized to a
|
98
|
+
# minimum size on either dimension
|
93
99
|
#
|
94
|
-
|
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
|
-
|
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
|
-
|
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.
|
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-
|
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
|