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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/lib/easyimg_utils.rb +87 -6
- 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: c09e7c063bbd8a5c1060c74338346317b3432f46e53a0e3cdc6e0d4a64553520
|
4
|
+
data.tar.gz: 8d73c424b106e51dea74394557e601b8ea78bfca66fd43bf80a10088527ba726
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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(
|
99
|
+
def self.calc_resize(geometry, new_geometry, force: false)
|
93
100
|
|
94
|
-
|
95
|
-
|
96
|
-
|
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(
|
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.
|
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-
|
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
|