easyimg_utils 0.4.3 → 0.6.3

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: 4d14e8e346eadfa36ea43f336f4b8bb161e2c38e216c162d97e67439767fb84b
4
- data.tar.gz: 9f27d41d4938f8c5b4249c90566062a5841ff24d9b1bf86506b2354fe0c070a4
3
+ metadata.gz: f68eb15dfa8aa18281bb8b71b6ad4ac8e0da01c5da5424d981388cfdee8cae7f
4
+ data.tar.gz: 10d4a0d5ad92f28723c9b4d2b025952723b8566d8cc9418e0e11191c70a407fe
5
5
  SHA512:
6
- metadata.gz: 3df7e8b76c8860579e2801664a3a14dcfb24c36eeb79607c0aeb944b37183db7b5cc0905790bd38a124a63abbba2ac0f1b72ca714a6456d937fab99a5efde938
7
- data.tar.gz: 5e845353a3f9b335712cb262c5272de9b5d6a71a4fb3efa291863104d4fbe8b8bf7de90a935a2e87a5a0a0da7c4771da1fcfd42742ceee7449bc4f4bfaf96c07
6
+ metadata.gz: c900ec2015da02a1eb2178feb88418792f19c8b806d84700931e8efa7cbdfef3cfe1144154d25b04c5fd4696e29fd4864d153a4906c8d637e57c50d08e7eca64
7
+ data.tar.gz: c1bdfcc930995773ffb921ad88d261d37a91c356a21accd1f18ffbcf4997ecd7d288b2d7fd70a42e54a5f9df6195e4f78e95097281749b15b61601485a16a7a3
checksums.yaml.gz.sig CHANGED
Binary file
data.tar.gz.sig CHANGED
Binary file
data/lib/easyimg_utils.rb CHANGED
@@ -3,9 +3,10 @@
3
3
  # file: easyimg_utils.rb
4
4
 
5
5
  require 'c32'
6
- require 'rxfhelper'
6
+ require 'x4ss'
7
7
  require 'rmagick'
8
8
  require 'webp_ffi'
9
+ require 'rxfhelper'
9
10
 
10
11
  # requirements:
11
12
  #
@@ -46,13 +47,16 @@ class EasyImgUtils
46
47
  extend CommandHelper
47
48
  include Magick
48
49
  include RXFHelperModule
50
+
49
51
 
50
52
  @commands = "
51
53
  * add rectangle # usage: add_rectangle(color: 'green', x1: 12, y1: 12, x2: 24, y2: 24)
52
54
  * add_svg # adds an SVG transparency overlay. usage: add_svg('/tmp/image1.svg')
53
55
  * add_text # e.g. add_text('some text')
56
+ * animate Creates an animated gif e.g. animate('/tmp/a%d.png', '/tmp/b.gif')
54
57
  * blur # e.g. blur(x: 231, y: 123, w: 85, h: 85)
55
58
  * capture_screen # takes a screenshot of the desktop
59
+ * calc_resize # e.g. EasyImgUtils.calc_resize '1449x1932', '640x480' #=> 480x640
56
60
  * center_crop # crops from the centre of an image. Usage center_crop(width, height)
57
61
  * composite # overlay a smaller image on top of an image
58
62
  * contrast # changes the intensity between lighter and darker elements
@@ -68,6 +72,7 @@ class EasyImgUtils
68
72
  * rotate_left
69
73
  * rotate_right
70
74
  * scale # Scales an image by the given factor e.g. 0.75 is 75%. see also resize
75
+ * screencast # records a screencast and saves it as animated gif. e.g. (out: '/tmp/fun.gif').screencast
71
76
  * sketch # renders an artistic sketch, ideal with simplistic photos
72
77
  * view # view the output
73
78
  * vignette # Feathers the edge of an image in a circular path
@@ -82,18 +87,32 @@ class EasyImgUtils
82
87
 
83
88
  end
84
89
 
90
+ # e.g. calc_resize '1449x1932', '640x480' #=> 480x640
91
+ #
92
+ def self.calc_resize(s, s2)
93
+
94
+ a = s.split('x',2).map(&:to_i).sort
95
+ a2 = s2.split('x',2).map(&:to_i).sort
96
+
97
+ factor = a2.last / a.last.to_f
98
+
99
+ a.map {|x| (x * factor).to_i}.join('x')
100
+
101
+ end
102
+
85
103
  def add_rectangle(a=[], quality: nil, color: 'green', stroke_width: 5,
86
104
  x1: 0, y1: 0, x2: 0, y2: 0)
87
105
 
88
106
  x1, y1, x2, y2 = *a if a
89
- img = read()
90
- gc = Magick::Draw.new
91
- gc.stroke('green')
92
- gc.stroke_width(5)
93
- gc.fill('transparent')
94
- gc.rectangle(x1, y1, x2, y2)
95
- gc.draw(img)
96
- write img, quality
107
+ read() do |img|
108
+ gc = Magick::Draw.new
109
+ gc.stroke('green')
110
+ gc.stroke_width(5)
111
+ gc.fill('transparent')
112
+ gc.rectangle(x1, y1, x2, y2)
113
+ gc.draw(img)
114
+ write img, quality
115
+ end
97
116
 
98
117
  end
99
118
 
@@ -113,38 +132,56 @@ class EasyImgUtils
113
132
 
114
133
  def add_text(s='your text goes here', quality: nil)
115
134
 
116
- img = read()
135
+ read() do |img|
117
136
 
118
- d = Draw.new
119
- img.annotate(d, 0,0,0,0, s) do
120
- d.gravity = Magick::SouthGravity
121
- d.pointsize = 26
122
- d.stroke = '#000000'
123
- d.fill = '#ffffff'
124
- d.font_weight = Magick::BoldWeight
137
+ d = Draw.new
138
+ img.annotate(d, 0,0,0,0, s) do
139
+ d.gravity = Magick::SouthGravity
140
+ d.pointsize = 26
141
+ d.stroke = '#000000'
142
+ d.fill = '#ffffff'
143
+ d.font_weight = Magick::BoldWeight
144
+ end
145
+
146
+ write img, quality
147
+
125
148
  end
126
149
 
127
- write img, quality
128
-
129
150
  end
130
151
 
152
+ def animate()
153
+
154
+ anim = Magick::ImageList.new
155
+
156
+ read() {|img| anim << img }
157
+ anim.ticks_per_second = 100
158
+ anim.delay = 20
159
+
160
+ @file_out ? anim.write(@file_out) : anim.animate
161
+
162
+ end
131
163
 
132
164
  def blur(x: 0, y: 0, w: 80, h: 80, strength: 8, quality: nil)
133
165
 
134
166
  width, height = w, h
135
- img = read()
136
- region = img.dispatch(x, y, width, height, 'RGB')
137
- face_img = Magick::Image.constitute(width, height, "RGB", region)
138
- img.composite!(face_img.gaussian_blur(0, strength), x, y,
139
- Magick::OverCompositeOp)
140
- write img, quality
167
+
168
+ read() do |img|
169
+
170
+ region = img.dispatch(x, y, width, height, 'RGB')
171
+ face_img = Magick::Image.constitute(width, height, "RGB", region)
172
+ img.composite!(face_img.gaussian_blur(0, strength), x, y,
173
+ Magick::OverCompositeOp)
174
+ write img, quality
175
+
176
+ end
141
177
 
142
178
  end
143
179
 
144
180
  def brightness(quality: nil)
145
- img = read()
146
- img2 = imglevel(-Magick::QuantumRange * 0.25, Magick::QuantumRange * 1.25, 1.0)
147
- write img2, quality
181
+ read() do |img|
182
+ img2 = imglevel(-Magick::QuantumRange * 0.25, Magick::QuantumRange * 1.25, 1.0)
183
+ write img2, quality
184
+ end
148
185
  end
149
186
 
150
187
  def capture_screen(quality: nil)
@@ -163,9 +200,10 @@ class EasyImgUtils
163
200
 
164
201
  return unless w
165
202
 
166
- img = read()
167
- img.crop!(CenterGravity, width, height)
168
- write img, quality
203
+ read() do |img|
204
+ img.crop!(CenterGravity, width, height)
205
+ write img, quality
206
+ end
169
207
 
170
208
  end
171
209
 
@@ -173,18 +211,19 @@ class EasyImgUtils
173
211
 
174
212
  return unless filex
175
213
 
176
- img = read()
214
+ read() do |img|
177
215
 
178
- imgx = Magick::ImageList.new(filex)
216
+ imgx = Magick::ImageList.new(filex)
179
217
 
180
- # Change the white pixels in the sign to transparent.
181
- imgx = imgx.matte_replace(0,0)
218
+ # Change the white pixels in the sign to transparent.
219
+ imgx = imgx.matte_replace(0,0)
182
220
 
183
- img2 = Magick::Draw.new
184
- img2.composite(x, y, 0, 0, imgx)
185
- img2.draw(img)
186
-
187
- write img, quality
221
+ img2 = Magick::Draw.new
222
+ img2.composite(x, y, 0, 0, imgx)
223
+ img2.draw(img)
224
+
225
+ write img, quality
226
+ end
188
227
 
189
228
  end
190
229
 
@@ -200,13 +239,14 @@ class EasyImgUtils
200
239
 
201
240
  return if level == neutral
202
241
 
203
- img ||= read()
242
+ read() do |img|
204
243
 
205
- n = neutral - level
206
- sharpen = n > 0
207
- n.abs.times { img = img.contrast(sharpen) }
208
-
209
- write img, quality
244
+ n = neutral - level
245
+ sharpen = n > 0
246
+ n.abs.times { img = img.contrast(sharpen) }
247
+
248
+ write img, quality
249
+ end
210
250
 
211
251
  end
212
252
 
@@ -241,28 +281,31 @@ class EasyImgUtils
241
281
 
242
282
  return unless w
243
283
 
244
- img = read()
245
- img.crop!(x,y, width=w, height=h)
246
- write img, quality
284
+ read() do |img|
285
+ img.crop!(x,y, width=w, height=h)
286
+ write img, quality
287
+ end
247
288
 
248
289
  end
249
290
 
250
291
  def fax_effect(threshold: 0.55, quality: nil)
251
292
 
252
- img = read()
253
-
254
- # Use a threshold of 55% of MaxRGB.
255
- img = img.threshold(Magick::MaxRGB*threshold)
293
+ read() do |img|
256
294
 
257
- write img, quality
295
+ # Use a threshold of 55% of MaxRGB.
296
+ img = img.threshold(Magick::MaxRGB*threshold)
297
+ write img, quality
298
+
299
+ end
258
300
 
259
301
  end
260
302
 
261
303
  def greyscale(quality: nil)
262
304
 
263
- img = read()
264
- img2 = img.quantize(256, GRAYColorspace)
265
- write img2, quality
305
+ read() do |img|
306
+ img2 = img.quantize(256, GRAYColorspace)
307
+ write img2, quality
308
+ end
266
309
 
267
310
  end
268
311
 
@@ -282,9 +325,10 @@ class EasyImgUtils
282
325
 
283
326
  def make_thumbnail(width=125, height=125)
284
327
 
285
- img = read()
286
- img2 = img.thumbnail(width, height)
287
- write img2, quality
328
+ read() do |img|
329
+ img2 = img.thumbnail(width, height)
330
+ write img2, quality
331
+ end
288
332
 
289
333
  end
290
334
 
@@ -294,45 +338,50 @@ class EasyImgUtils
294
338
  #
295
339
  def resize(geometry='320x240', quality: nil)
296
340
 
297
- preview = read()
341
+ read() do |preview|
298
342
 
299
- preview.change_geometry!(geometry) do |cols, rows, img|
300
- img.resize!(cols, rows)
343
+ preview.change_geometry!(geometry) do |cols, rows, img|
344
+ img.resize!(cols, rows)
345
+ end
346
+
347
+ write preview, quality
301
348
  end
302
349
 
303
- write preview, quality
304
-
305
350
  end
306
351
 
307
352
  def rotate(degrees)
308
353
 
309
- img = read()
310
- img2 = img.rotate(degrees.to_i)
311
- write img2, quality
354
+ read() do |img|
355
+ img2 = img.rotate(degrees.to_i)
356
+ write img2, quality
357
+ end
312
358
 
313
359
  end
314
360
 
315
361
  def rotate_180()
316
362
 
317
- img = read()
318
- img2 = img.rotate(180)
319
- write img2, quality
363
+ read() do |img|
364
+ img2 = img.rotate(180)
365
+ write img2, quality
366
+ end
320
367
 
321
368
  end
322
369
 
323
370
  def rotate_left()
324
371
 
325
- img = read()
326
- img2 = img.rotate(-45)
327
- write img2, quality
372
+ read() do |img|
373
+ img2 = img.rotate(-45)
374
+ write img2, quality
375
+ end
328
376
 
329
377
  end
330
378
 
331
379
  def rotate_right()
332
380
 
333
- img = read()
334
- img2 = img.rotate(45)
335
- write img2, quality
381
+ read() do |img|
382
+ img2 = img.rotate(45)
383
+ write img2, quality
384
+ end
336
385
 
337
386
  end
338
387
 
@@ -340,30 +389,50 @@ class EasyImgUtils
340
389
  #
341
390
  def scale(factor=0.75, quality: nil)
342
391
 
343
- img = read()
344
-
345
- img2 = img.scale(factor)
392
+ read() do |img|
346
393
 
347
- write img2, quality
394
+ img2 = img.scale(factor)
395
+ write img2, quality
396
+
397
+ end
348
398
 
349
399
  end
400
+
401
+ # Takes a screenshot every second to create an animated gif
402
+ #
403
+ def screencast(duration: 6, scale: 1, window: true)
404
+
405
+ fileout = @file_out.sub(/\.\w+$/,'%d.png')
406
+
407
+ puts 'fileout: ' + fileout if @debug
350
408
 
409
+ x4ss = X4ss.new fileout, mouse: true, window: true
410
+ mode = window ? :window : :screen
411
+ sleep 2; x4ss.record duration: duration, mode: mode
412
+ x4ss.save
351
413
 
414
+ fileout2 = fileout.sub(/(?=%)/,'b')
415
+ EasyImgUtils.new(fileout, fileout2).scale(scale) unless scale == 1
416
+ EasyImgUtils.new(fileout2, @file_out).animate
417
+
418
+ end
352
419
 
353
420
  def sketch(quality: nil)
354
421
 
355
- img = read()
422
+ read() do |img|
356
423
 
357
- # Convert to grayscale
358
- sketch = img.quantize(256, Magick::GRAYColorspace)
424
+ # Convert to grayscale
425
+ sketch = img.quantize(256, Magick::GRAYColorspace)
359
426
 
360
- # Apply histogram equalization
361
- sketch = sketch.equalize
427
+ # Apply histogram equalization
428
+ sketch = sketch.equalize
362
429
 
363
- sketch = sketch.sketch(0, 10, 135)
364
- img = img.dissolve(sketch, 0.75, 0.25)
430
+ sketch = sketch.sketch(0, 10, 135)
431
+ img = img.dissolve(sketch, 0.75, 0.25)
365
432
 
366
- write img, quality
433
+ write img, quality
434
+
435
+ end
367
436
 
368
437
  end
369
438
 
@@ -379,10 +448,12 @@ class EasyImgUtils
379
448
 
380
449
  def vignette(quality: nil)
381
450
 
382
- img = read()
383
- img2 = img.vignette
384
-
385
- write img2, quality
451
+ read() do |img|
452
+
453
+ img2 = img.vignette
454
+ write img2, quality
455
+
456
+ end
386
457
 
387
458
  end
388
459
 
@@ -391,8 +462,28 @@ class EasyImgUtils
391
462
  private
392
463
 
393
464
  def read(file=@file_in)
394
- data, type = RXFHelper.read(file)
395
- Magick::Image.from_blob(data).first
465
+
466
+ files = if file =~ /%d/ then
467
+
468
+ regfilepath = file.sub('%d','(\d+)')
469
+ globfilepath = file.sub('%d','*')
470
+
471
+ a = Dir[globfilepath]
472
+ puts 'a: ' + a.inspect if @debug
473
+ a.sort_by {|x| Regexp.new(regfilepath).match(x).captures[0].to_i }
474
+
475
+ else
476
+ [file]
477
+ end
478
+
479
+ files.each do |filex|
480
+
481
+ @filex_in = filex
482
+ data, type = RXFHelper.read(filex)
483
+ yield(Magick::Image.from_blob(data).first)
484
+
485
+ end
486
+
396
487
  end
397
488
 
398
489
  def run(command, show=false)
@@ -410,19 +501,27 @@ class EasyImgUtils
410
501
 
411
502
  return img.to_blob unless @file_out
412
503
 
413
- if @file_out =~ /^dfs:/ then
504
+ file_out = if @file_out =~ /%d/ then
505
+ regpath = @file_in.sub('%d','(\d+)')
506
+ n = @filex_in[/#{regpath}/,1]
507
+ @file_out.sub('%d',n)
508
+ else
509
+ @file_out
510
+ end
511
+
512
+ if file_out =~ /^dfs:/ then
414
513
 
415
- outfile = File.join(@working_dir, File.basename(@file_out))
514
+ outfile = File.join(@working_dir, File.basename(file_out))
416
515
 
417
516
  img.write outfile do
418
517
  self.quality = quality.to_i if quality
419
518
  end
420
519
 
421
- FileX.cp outfile, @file_out
520
+ FileX.cp outfile, file_out
422
521
 
423
522
  else
424
523
 
425
- img.write @file_out do
524
+ img.write file_out do
426
525
  self.quality = quality.to_i if quality
427
526
  end
428
527
 
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.3
4
+ version: 0.6.3
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: 2020-05-12 00:00:00.000000000 Z
38
+ date: 2021-03-20 00:00:00.000000000 Z
39
39
  dependencies:
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: rmagick
@@ -43,62 +43,82 @@ dependencies:
43
43
  requirements:
44
44
  - - "~>"
45
45
  - !ruby/object:Gem::Version
46
- version: '4.1'
46
+ version: '4.2'
47
47
  - - ">="
48
48
  - !ruby/object:Gem::Version
49
- version: 4.1.2
49
+ version: 4.2.2
50
50
  type: :runtime
51
51
  prerelease: false
52
52
  version_requirements: !ruby/object:Gem::Requirement
53
53
  requirements:
54
54
  - - "~>"
55
55
  - !ruby/object:Gem::Version
56
- version: '4.1'
56
+ version: '4.2'
57
57
  - - ">="
58
58
  - !ruby/object:Gem::Version
59
- version: 4.1.2
59
+ version: 4.2.2
60
60
  - !ruby/object:Gem::Dependency
61
61
  name: rxfhelper
62
62
  requirement: !ruby/object:Gem::Requirement
63
63
  requirements:
64
64
  - - "~>"
65
65
  - !ruby/object:Gem::Version
66
- version: '0.9'
66
+ version: '1.1'
67
67
  - - ">="
68
68
  - !ruby/object:Gem::Version
69
- version: 0.9.4
69
+ version: 1.1.3
70
70
  type: :runtime
71
71
  prerelease: false
72
72
  version_requirements: !ruby/object:Gem::Requirement
73
73
  requirements:
74
74
  - - "~>"
75
75
  - !ruby/object:Gem::Version
76
- version: '0.9'
76
+ version: '1.1'
77
77
  - - ">="
78
78
  - !ruby/object:Gem::Version
79
- version: 0.9.4
79
+ version: 1.1.3
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: webp-ffi
82
82
  requirement: !ruby/object:Gem::Requirement
83
83
  requirements:
84
84
  - - "~>"
85
85
  - !ruby/object:Gem::Version
86
- version: '0.2'
86
+ version: '0.3'
87
87
  - - ">="
88
88
  - !ruby/object:Gem::Version
89
- version: 0.2.7
89
+ version: 0.3.1
90
90
  type: :runtime
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.3'
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: 0.3.1
100
+ - !ruby/object:Gem::Dependency
101
+ name: x4ss
102
+ requirement: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: 0.2.0
94
107
  - - "~>"
95
108
  - !ruby/object:Gem::Version
96
109
  version: '0.2'
110
+ type: :runtime
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
97
114
  - - ">="
98
115
  - !ruby/object:Gem::Version
99
- version: 0.2.7
116
+ version: 0.2.0
117
+ - - "~>"
118
+ - !ruby/object:Gem::Version
119
+ version: '0.2'
100
120
  description:
101
- email: james@jamesrobertson.eu
121
+ email: digital.robertson@gmail.com
102
122
  executables: []
103
123
  extensions: []
104
124
  extra_rdoc_files: []
@@ -123,7 +143,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
123
143
  - !ruby/object:Gem::Version
124
144
  version: '0'
125
145
  requirements: []
126
- rubygems_version: 3.0.3
146
+ rubyforge_project:
147
+ rubygems_version: 2.7.10
127
148
  signing_key:
128
149
  specification_version: 4
129
150
  summary: Makes manipulating images from 1 line of code easier.
metadata.gz.sig CHANGED
Binary file