easyimg_utils 0.6.6 → 0.7.4
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 +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
|