skeptick 0.1.0
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.
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +584 -0
- data/Rakefile +10 -0
- data/foo.rb +1 -0
- data/lib/skeptick.rb +2 -0
- data/lib/skeptick/chain.rb +55 -0
- data/lib/skeptick/chain/dsl_context.rb +21 -0
- data/lib/skeptick/command.rb +46 -0
- data/lib/skeptick/convert.rb +109 -0
- data/lib/skeptick/convert/dsl_context.rb +27 -0
- data/lib/skeptick/core.rb +46 -0
- data/lib/skeptick/error.rb +4 -0
- data/lib/skeptick/helper.rb +26 -0
- data/lib/skeptick/image.rb +69 -0
- data/lib/skeptick/image/dsl_context.rb +29 -0
- data/lib/skeptick/railtie.rb +8 -0
- data/lib/skeptick/sugar.rb +8 -0
- data/lib/skeptick/sugar/composition.rb +55 -0
- data/lib/skeptick/sugar/debugging.rb +12 -0
- data/lib/skeptick/sugar/drawing.rb +32 -0
- data/lib/skeptick/sugar/edges.rb +70 -0
- data/lib/skeptick/sugar/formatting.rb +12 -0
- data/lib/skeptick/sugar/geometry.rb +38 -0
- data/lib/skeptick/sugar/resizing.rb +16 -0
- data/lib/skeptick/sugar/sequence_manipulation.rb +43 -0
- data/lib/skeptick/version.rb +3 -0
- data/logo.png +0 -0
- data/logo.rb +45 -0
- data/refresh_preview.scpt +2 -0
- data/skeptick.gemspec +21 -0
- data/test/chain_test.rb +94 -0
- data/test/convert_test.rb +177 -0
- data/test/image_test.rb +145 -0
- data/test/sugar/composition_test.rb +273 -0
- data/test/sugar/debugging_test.rb +24 -0
- data/test/sugar/drawing_test.rb +86 -0
- data/test/sugar/edges_test.rb +99 -0
- data/test/sugar/formatting_test.rb +19 -0
- data/test/sugar/geometry_test.rb +92 -0
- data/test/sugar/resizing_test.rb +25 -0
- data/test/sugar/sequence_manipulation_test.rb +98 -0
- data/test/test_helper.rb +11 -0
- metadata +117 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Maxim Chernyak
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,584 @@
|
|
1
|
+
# Skeptick
|
2
|
+
|
3
|
+
Skeptick is an all-purpose DSL for building and running ImageMagic commands.
|
4
|
+
It helps you build any transformations, from trivial resizes to complex mask
|
5
|
+
algorithms and free drawing. In a nutshell, Skeptick is nothing more than a
|
6
|
+
string manipulator and a process spawner. That's all it's meant to be. However,
|
7
|
+
with Skeptick you get quite a few advantages over using plain shell-out or other
|
8
|
+
libraries.
|
9
|
+
|
10
|
+
## What you get
|
11
|
+
|
12
|
+
* Clean Ruby syntax to build ImageMagick commands
|
13
|
+
* Composable Image objects
|
14
|
+
* ImageMagick's `STDERR` output revealed in a Ruby exception
|
15
|
+
* Ability to save intermediate images for debugging
|
16
|
+
* Minimal memory consumption on shell-outs thanks to
|
17
|
+
[posix-spawn](https://github.com/rtomayko/posix-spawn)
|
18
|
+
* Emphasis on performing the whole transformation in a single command
|
19
|
+
|
20
|
+
## Installation
|
21
|
+
|
22
|
+
Add this line to your application's Gemfile:
|
23
|
+
|
24
|
+
gem 'skeptick'
|
25
|
+
|
26
|
+
And then execute:
|
27
|
+
|
28
|
+
$ bundle
|
29
|
+
|
30
|
+
Or install it yourself as:
|
31
|
+
|
32
|
+
$ gem install skeptick
|
33
|
+
|
34
|
+
## Usage
|
35
|
+
|
36
|
+
To use Skeptick, you simply require it and include the module into your class.
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
require 'skeptick'
|
40
|
+
|
41
|
+
class MyClass
|
42
|
+
include Skeptick
|
43
|
+
|
44
|
+
def convert_some_image
|
45
|
+
cmd = convert(to: 'result.png') do
|
46
|
+
# ...
|
47
|
+
end
|
48
|
+
|
49
|
+
cmd.build
|
50
|
+
end
|
51
|
+
end
|
52
|
+
```
|
53
|
+
|
54
|
+
The `cmd` object seen in above example can be inspected to see the exact command
|
55
|
+
that Skeptick will run. Simply use `cmd.inspect` or `cmd.to_s`. Skeptick never
|
56
|
+
runs anything until you call `build` (except for one very special case), so you
|
57
|
+
can inspect commands all you want before executing them.
|
58
|
+
|
59
|
+
If you don't want to require all of Skeptick, you can just require the core, and
|
60
|
+
and select any specific sugar you want.
|
61
|
+
|
62
|
+
```ruby
|
63
|
+
require 'skeptick/core'
|
64
|
+
require 'skeptick/sugar/resizing'
|
65
|
+
require 'skeptick/sugar/composition'
|
66
|
+
```
|
67
|
+
|
68
|
+
See the `lib/skeptick/sugar` dir for all the goodies.
|
69
|
+
|
70
|
+
In Rails Skeptick will automatically use `Rails.logger` and `Rails.root` as
|
71
|
+
`cd_path`. You can also configure your own.
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
Skeptick.logger = MyLogger.new
|
75
|
+
Skeptick.cd_path = '/some/dir'
|
76
|
+
```
|
77
|
+
|
78
|
+
You can enable `debug_mode` to display every executed command in the log.
|
79
|
+
|
80
|
+
```ruby
|
81
|
+
Skeptick.debug_mode = true
|
82
|
+
```
|
83
|
+
|
84
|
+
## DSL
|
85
|
+
|
86
|
+

|
87
|
+
|
88
|
+
This picture is produced with the following script
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
include Skeptick
|
92
|
+
|
93
|
+
image_size = '400x120'
|
94
|
+
left, top = 8, 80
|
95
|
+
|
96
|
+
# Build a picture with built-in tile:granite: texture and using the
|
97
|
+
# skeptick-provided sugar method `rounded_corners_image`
|
98
|
+
paper = rounded_corners_image(size: image_size, radius: 25) do
|
99
|
+
set :size, image_size
|
100
|
+
image 'tile:granite:'
|
101
|
+
apply '-brightness-contrast', '38x-33'
|
102
|
+
apply :blur, '0x0.5'
|
103
|
+
end
|
104
|
+
|
105
|
+
# Build a text image that says "Skeptick" using specified font, add gradient
|
106
|
+
text = image do
|
107
|
+
canvas :none, size: '395x110'
|
108
|
+
font 'Handwriting - Dakota Regular'
|
109
|
+
set :pointsize, 90
|
110
|
+
set :fill, 'gradient:#37e-#007'
|
111
|
+
write 'Skeptick', left: left, top: top
|
112
|
+
apply :blur, '0x0.7'
|
113
|
+
end
|
114
|
+
|
115
|
+
bezier = \
|
116
|
+
"#{left + 17 }, #{top + 17} #{left + 457}, #{top - 13} " +
|
117
|
+
"#{left + 377}, #{top + 27} #{left + 267}, #{top + 27}"
|
118
|
+
|
119
|
+
# Draw a curve that will appear underneath the text using bezier coordinates
|
120
|
+
curve = image do
|
121
|
+
canvas :none, size: '395x110'
|
122
|
+
set :strokewidth, 2
|
123
|
+
set :stroke, 'gradient:#37e-#007'
|
124
|
+
draw "fill none bezier #{bezier}"
|
125
|
+
end
|
126
|
+
|
127
|
+
# Combine text and curve using `:over` blending, multiply it with paper using
|
128
|
+
# `:multiply` blending, and add a torn effect using Skeptick-provided sugar
|
129
|
+
# method `torn_paper_image`
|
130
|
+
torn = torn_paper_image(
|
131
|
+
paper * (text + curve),
|
132
|
+
spread: 50,
|
133
|
+
blur: '3x10'
|
134
|
+
)
|
135
|
+
|
136
|
+
# Create a convert command with all of the above and run it
|
137
|
+
logo = convert(torn, to: "#{File.dirname(__FILE__)}/logo.png")
|
138
|
+
logo.build
|
139
|
+
|
140
|
+
# This is what the resulting command looks like
|
141
|
+
# You can see it by running `logo.to_s`
|
142
|
+
#
|
143
|
+
# convert (
|
144
|
+
# (
|
145
|
+
# (
|
146
|
+
# -size 400x120 tile:granite:
|
147
|
+
# -brightness-contrast 38x-33 -blur 0x0.5
|
148
|
+
# (
|
149
|
+
# +clone -alpha transparent -background none
|
150
|
+
# -draw roundrectangle 1,1 400,120 25,25
|
151
|
+
# )
|
152
|
+
# -alpha set -compose dstin -composite
|
153
|
+
# )
|
154
|
+
#
|
155
|
+
# (
|
156
|
+
# -size 395x110 canvas:none
|
157
|
+
# -font Handwriting---Dakota-Regular -pointsize 90
|
158
|
+
# -fill gradient:#37e-#007 -draw text 8,80 'Skeptick'
|
159
|
+
# -blur 0x0.7 -size 395x110 canvas:none -strokewidth 2
|
160
|
+
# -stroke gradient:#37e-#007
|
161
|
+
# -draw fill none
|
162
|
+
# bezier 25, 97 465, 67 385, 107 275, 107
|
163
|
+
# -compose over -composite
|
164
|
+
# )
|
165
|
+
#
|
166
|
+
# -compose multiply -composite
|
167
|
+
# )
|
168
|
+
#
|
169
|
+
# (
|
170
|
+
# +clone -alpha extract -virtual-pixel black -spread 50
|
171
|
+
# -blur 0x3 -threshold 50% -spread 1 -blur 0x.7
|
172
|
+
# )
|
173
|
+
#
|
174
|
+
# -alpha off -compose copy_opacity -composite
|
175
|
+
# ) logo.png
|
176
|
+
|
177
|
+
```
|
178
|
+
|
179
|
+
## All those little commands
|
180
|
+
|
181
|
+
A lot of things happened in the above script, no worries, it's just a showcase.
|
182
|
+
I bet the first thing you noticed is a shitstorm of little method names like
|
183
|
+
`apply`, `canvas`, `font`, `write`, `draw`, etc. Well, they are all sugar. We
|
184
|
+
will cover sugar later in teh given parchment.
|
185
|
+
|
186
|
+
There are actually only three real commands in all of Skeptick: `convert`,
|
187
|
+
`set`, and `image`.
|
188
|
+
|
189
|
+
### Convert
|
190
|
+
|
191
|
+
`convert` can be used both outside and inside a transformation block. You could
|
192
|
+
say for example this.
|
193
|
+
|
194
|
+
```ruby
|
195
|
+
command = convert('image1.png', to: 'image2.png') do
|
196
|
+
set '-resize', '200x200'
|
197
|
+
end
|
198
|
+
|
199
|
+
# OUTPUT:
|
200
|
+
# convert image1.png -resize 200x200 image2.png
|
201
|
+
```
|
202
|
+
|
203
|
+
Or you could put it inside, and it will become a parenthesized subcommand.
|
204
|
+
|
205
|
+
```ruby
|
206
|
+
command = convert('image1.png', to: 'image2.png') do
|
207
|
+
convert do
|
208
|
+
set '+clone' # pull in image1 into parentheses
|
209
|
+
set '-resize 100x100' # resize image1's clone in memory
|
210
|
+
end
|
211
|
+
|
212
|
+
set '-compose over'
|
213
|
+
set '-composite'
|
214
|
+
end
|
215
|
+
|
216
|
+
# OUTPUT:
|
217
|
+
# convert image1.png ( +clone -resize 100x100 )
|
218
|
+
# -compose over -composite image2.png
|
219
|
+
```
|
220
|
+
|
221
|
+
If you love parentheses a lot, you could nest `convert` infinitely. However,
|
222
|
+
ImageMagick's `clone`, `delete`, and `swap` are your friends, learn them to
|
223
|
+
cure parenthethitis.
|
224
|
+
|
225
|
+
Oh, speaking of nesting — we can reuse that whole command inside another command
|
226
|
+
by passing it to `convert` in place of an image filepath.
|
227
|
+
|
228
|
+
```ruby
|
229
|
+
new_command = convert(command, to: 'whatever.png') do
|
230
|
+
set '-resize 300x300'
|
231
|
+
end
|
232
|
+
|
233
|
+
# OUTPUT:
|
234
|
+
# convert
|
235
|
+
# ( image1.png ( +clone -resize 100x100 ) -compose over -composite )
|
236
|
+
# -resize 300x300 whatever.png
|
237
|
+
```
|
238
|
+
|
239
|
+
See what I did there? It's composability. If you have a `convert` object in a
|
240
|
+
variable, you can use it inside another `convert` object down the line.
|
241
|
+
|
242
|
+
### Set
|
243
|
+
|
244
|
+
`set` appends a string to your command. You can give it any arguments, it
|
245
|
+
doesn't care, it will just `to_s` and concatenate them.
|
246
|
+
|
247
|
+
```ruby
|
248
|
+
# All same thing
|
249
|
+
set '-resize 100x100'
|
250
|
+
set '-resize', '100x100'
|
251
|
+
set :resize, '100x100'
|
252
|
+
```
|
253
|
+
|
254
|
+
Yeah that last one is special convenience. If an argument to `set` is a symbol,
|
255
|
+
it will convert it to `"-#{symbol}"`. If you need `+resize` type of thing you'd
|
256
|
+
just have to use a string, or sugar, but later on that.
|
257
|
+
|
258
|
+
### Image
|
259
|
+
|
260
|
+
`image` is very similar to `convert`. However, `convert` is a command object
|
261
|
+
that may contain many images, settings, operators, nested converts, etc. Image
|
262
|
+
is also a command object that can contain many settings and operators, but it
|
263
|
+
can only contain one image reference inside of it. The reference can be a path,
|
264
|
+
a nested convert, or a special string representing a built-in imagemagick image,
|
265
|
+
but it can be only one.
|
266
|
+
|
267
|
+
```ruby
|
268
|
+
command = convert(to: '/path/to/result.png') do
|
269
|
+
image '/path/to/image.png'
|
270
|
+
set :resize, '200x200'
|
271
|
+
end
|
272
|
+
|
273
|
+
# OUTPUT:
|
274
|
+
# convert /path/to/image.png -resize 200x200 /path/to/result.png
|
275
|
+
```
|
276
|
+
|
277
|
+
In this case we declared an image inside a `convert` which references a path.
|
278
|
+
Instead we could create an image that references a built-in image.
|
279
|
+
|
280
|
+
```ruby
|
281
|
+
command = convert(to: '/path/to/result.png') do
|
282
|
+
image 'rose:'
|
283
|
+
end
|
284
|
+
|
285
|
+
# OUTPUT:
|
286
|
+
# convert rose: /path/to/result.png
|
287
|
+
```
|
288
|
+
|
289
|
+
You can save image objects in variables, and pass them around, but unlike
|
290
|
+
`convert`, you cannot run them standalone.
|
291
|
+
|
292
|
+
```ruby
|
293
|
+
rose_image = image('rose:')
|
294
|
+
command = convert(rose_image, to: '/path/to/result.png')
|
295
|
+
|
296
|
+
# OUTPUT:
|
297
|
+
# convert rose: /path/to/result.png
|
298
|
+
```
|
299
|
+
See, we had to wrap it in a `convert` in order to use it. You could also append
|
300
|
+
this image at any point inside the convert block.
|
301
|
+
|
302
|
+
```ruby
|
303
|
+
rose_image = image('rose:')
|
304
|
+
command = convert(to: '/path/to/result.png') do
|
305
|
+
image rose_image
|
306
|
+
end
|
307
|
+
|
308
|
+
# OUTPUT:
|
309
|
+
# convert rose: /path/to/result.png
|
310
|
+
```
|
311
|
+
|
312
|
+
As mentioned above, an image can come with its own settings and operators.
|
313
|
+
|
314
|
+
```ruby
|
315
|
+
rose_image = image do
|
316
|
+
set :background, 'transparent'
|
317
|
+
image 'rose:'
|
318
|
+
apply :resize, '200x200'
|
319
|
+
end
|
320
|
+
|
321
|
+
command = convert(to: '/path/to/result.png') do
|
322
|
+
image rose_image
|
323
|
+
end
|
324
|
+
```
|
325
|
+
|
326
|
+
You could do all of this inline, the output will be the same.
|
327
|
+
|
328
|
+
```ruby
|
329
|
+
command = convert(to: '/path/to/result.png') do
|
330
|
+
image do
|
331
|
+
set :background, 'transparent'
|
332
|
+
image 'rose:'
|
333
|
+
apply :resize, '200x200'
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
# OUTPUT:
|
338
|
+
# convert -background transparent rose: -resize 200x200 /path/to/result.png
|
339
|
+
```
|
340
|
+
|
341
|
+
If you have a `convert` object you can pass it as an image too.
|
342
|
+
|
343
|
+
```ruby
|
344
|
+
saved_convert = convert(to: 'foo.png') do
|
345
|
+
image 'rose:'
|
346
|
+
set :resize, '200x200'
|
347
|
+
end
|
348
|
+
|
349
|
+
another_convert = convert(to: 'bar.png') do
|
350
|
+
image saved_convert
|
351
|
+
apply :blur, '0x0.5'
|
352
|
+
end
|
353
|
+
|
354
|
+
# OUTPUT
|
355
|
+
# convert ( rose: -resize 200x200 ) -blur 0x0.5 bar.png
|
356
|
+
```
|
357
|
+
|
358
|
+
Nesting possibilities are endless.
|
359
|
+
|
360
|
+
## Sugar
|
361
|
+
|
362
|
+
Skeptick comes with a bunch of sugar. When you require Skeptick, you can simply
|
363
|
+
require everything. This includes all the sugar.
|
364
|
+
|
365
|
+
```ruby
|
366
|
+
require 'skeptick'
|
367
|
+
```
|
368
|
+
|
369
|
+
However, you can require just the core stuff described above, and select any
|
370
|
+
sugar you want.
|
371
|
+
|
372
|
+
```ruby
|
373
|
+
require 'skeptick/core'
|
374
|
+
require 'skeptick/sugar/composition'
|
375
|
+
```
|
376
|
+
|
377
|
+
### Composition Sugar
|
378
|
+
|
379
|
+
Composition is sugar that adds `compose` shortcut to Skeptick's DSL.
|
380
|
+
|
381
|
+
```ruby
|
382
|
+
command = compose(:multiply, 'a.png', 'b.png', to: 'out.png') do
|
383
|
+
with '-resize', '200x200'
|
384
|
+
end
|
385
|
+
|
386
|
+
# OUTPUT:
|
387
|
+
# convert a.png b.png -compose multiply -resize 200x200 -composite out.png
|
388
|
+
```
|
389
|
+
|
390
|
+
It takes the blending type as the first argument, and injects some extra stuff
|
391
|
+
into the resulting command, but really it's just a wrapper around `convert` as
|
392
|
+
you could easily see in its implementation.
|
393
|
+
|
394
|
+
```ruby
|
395
|
+
def compose(blending, *args, &blk)
|
396
|
+
convert(*args, &blk).tap do |c|
|
397
|
+
c.append :compose, blending.to_s
|
398
|
+
c.append :composite
|
399
|
+
end
|
400
|
+
end
|
401
|
+
```
|
402
|
+
|
403
|
+
As usual, you don't have to list your images as method arguments like that.
|
404
|
+
Instead you could declare them inside the block using the `image` method. The
|
405
|
+
following command does the same thing.
|
406
|
+
|
407
|
+
```ruby
|
408
|
+
command = compose(:multiply, to: 'out.png') do
|
409
|
+
image 'a.png'
|
410
|
+
image 'b.png'
|
411
|
+
with '-resize', '200x200'
|
412
|
+
end
|
413
|
+
```
|
414
|
+
|
415
|
+
Since most of Skeptick's power comes from the ability to infinitely nest things,
|
416
|
+
here's a an example involving a nested `compose`.
|
417
|
+
|
418
|
+
```ruby
|
419
|
+
command = convert('image1.png', to: 'result.png') do
|
420
|
+
compose(:multiply) do
|
421
|
+
image 'image3.png[200x200]'
|
422
|
+
|
423
|
+
convert 'image4.png' do
|
424
|
+
with '-unsharp', '0x5'
|
425
|
+
end
|
426
|
+
|
427
|
+
end
|
428
|
+
end
|
429
|
+
|
430
|
+
# OUTPUT:
|
431
|
+
# convert
|
432
|
+
# image1.png ( image3.png[200x200] ( image4.png -unsharp 0x5 ) -compose
|
433
|
+
# multiply -composite ) result.png"
|
434
|
+
```
|
435
|
+
|
436
|
+
Notice how we nest `compose` inside of `convert`, and then `convert` inside of
|
437
|
+
`compose`. The output of each acts like any declared image. In other words,
|
438
|
+
wherever you would write `image "foo.png"` you could also write a nested
|
439
|
+
command.
|
440
|
+
|
441
|
+
### Composition Operators
|
442
|
+
|
443
|
+
This is more of a gimmick than a real feature, but you can use math operators
|
444
|
+
like `+`, `-`, `*`, `/`, `&`, `|` to compose images. These are all based on
|
445
|
+
`compose` method. Here's a multiply example.
|
446
|
+
|
447
|
+
```ruby
|
448
|
+
image1 = image('foo.png')
|
449
|
+
image2 = image('bar.png')
|
450
|
+
result = convert(image1 * image2, to: 'baz.png')
|
451
|
+
|
452
|
+
# OUTPUT:
|
453
|
+
# convert ( foo.png bar.png -compose multiply -composite ) baz.png
|
454
|
+
```
|
455
|
+
|
456
|
+
As you can see, this is equivalent of simply using `compose`.
|
457
|
+
|
458
|
+
```ruby
|
459
|
+
# Same thing
|
460
|
+
result = compose(:multiply, 'foo.png', 'bar.png', to: 'baz.png')
|
461
|
+
```
|
462
|
+
|
463
|
+
Check out `lib/skeptick/sugar/composition.rb` for what these operators do.
|
464
|
+
|
465
|
+
### Sequence Manipulation Sugar
|
466
|
+
|
467
|
+
Skeptick provides methods `clone`, `delete`, and `swap` to
|
468
|
+
manipulate declared images in a sequence, just like in ImageMagick CLI.
|
469
|
+
|
470
|
+
```ruby
|
471
|
+
command = compose(:over, 'image1.png', to: 'result.png') do
|
472
|
+
# You could think of image sequence as a ruby array. Here's what it would
|
473
|
+
# look like right now.
|
474
|
+
# [ 'image1.png' ]
|
475
|
+
|
476
|
+
compose(:multiply) do
|
477
|
+
image 'mask.png' # loading another image for this operation
|
478
|
+
clone(0) # cloning image1.png from outside "into parentheses"
|
479
|
+
end
|
480
|
+
|
481
|
+
# Sequence at this point:
|
482
|
+
# [ 'image1.png', 'result of compose(:multiply)' ]
|
483
|
+
|
484
|
+
delete(0) # deleting image1.png from the sequence and from memory
|
485
|
+
|
486
|
+
# Sequence at this point:
|
487
|
+
# [ 'result of compose(:multiply)' ]
|
488
|
+
|
489
|
+
# At this point the only image loaded in memory is the one produced by the
|
490
|
+
# compose(:multiply) command above. Let's load another one.
|
491
|
+
|
492
|
+
image 'image2.png'
|
493
|
+
|
494
|
+
# Sequence at this point:
|
495
|
+
# [ 'result of compose(:multiply)', 'image2.png' ]
|
496
|
+
|
497
|
+
# Now we have two images in the sequence. We can swap them in case we need
|
498
|
+
# to change their order.
|
499
|
+
|
500
|
+
swap
|
501
|
+
|
502
|
+
# Sequence at this point:
|
503
|
+
# [ 'image2.png', 'result of compose(:multiply)' ]
|
504
|
+
|
505
|
+
# Now image2.png is first in the sequence, and the output of
|
506
|
+
# compose(:multiply) is second. Since our outermost command is compose(:over),
|
507
|
+
# at this point these 2 images will be composed over each other, and the
|
508
|
+
# result written to result.png.
|
509
|
+
end
|
510
|
+
|
511
|
+
# OUTPUT
|
512
|
+
# convert
|
513
|
+
# image1.png ( mask.png -clone 0 -compose multiply -composite )
|
514
|
+
# -delete 0 image2.png +swap -compose over -composite result.png
|
515
|
+
```
|
516
|
+
|
517
|
+
You can use `clone` and `delete` to refer to multiple images at once by passing
|
518
|
+
mutliple indexes as arguments, like `clone(0,1,2)` or `delete(0,1)`. Ranges are
|
519
|
+
also accepted. Without any arguments `clone` and `delete` are translated to
|
520
|
+
ImageMagick's `+clone` and `+delete`. They then refer to the last image in the
|
521
|
+
sequence. Same with `swap` - you can provide two indexes in arguments like
|
522
|
+
`swap(1,3)` to swap any 2 images in the sequence, or without arguments it'll
|
523
|
+
act as `+swap` - which swaps last two images.
|
524
|
+
|
525
|
+
### Debugging Sugar
|
526
|
+
|
527
|
+
Sometimes you might want to take a look at an intermediate image that's being
|
528
|
+
generated inside parentheses, nested somewhere in your command. You can do so
|
529
|
+
with the help of `write('/path/to/img.png')`.
|
530
|
+
|
531
|
+
```ruby
|
532
|
+
command = convert(to: 'result.png') do
|
533
|
+
compose(:multiply, 'a.png', 'b.png') do
|
534
|
+
write('~/Desktop/debug.png')
|
535
|
+
end
|
536
|
+
|
537
|
+
set '-resize', '200x200'
|
538
|
+
end
|
539
|
+
```
|
540
|
+
|
541
|
+
In this case the result of inner `compose` command will be written to desktop,
|
542
|
+
without affecting anything else. Again, this is a feature that already exists
|
543
|
+
in ImageMagick, as becomes apparent from the resulting command.
|
544
|
+
|
545
|
+
convert
|
546
|
+
( a.png b.png -compose multiply -composite -write ~/Desktop/debug.png )
|
547
|
+
-resize 200x200 result.png
|
548
|
+
|
549
|
+
## Chain
|
550
|
+
|
551
|
+
This is rarely (if ever) needed, but with Skeptick you could easily create
|
552
|
+
piped commands.
|
553
|
+
|
554
|
+
```ruby
|
555
|
+
command = chain(to: 'result.png') do
|
556
|
+
compose(:hardlight, 'a.png', 'b.png') do
|
557
|
+
with '-brightness-contrast', '2x4'
|
558
|
+
end
|
559
|
+
|
560
|
+
compose(:atop, 'c.png', :pipe)
|
561
|
+
end
|
562
|
+
|
563
|
+
# OUTPUT:
|
564
|
+
convert
|
565
|
+
a.png b.png -compose hardlight -brightness-contrast 2x4 -composite miff:- |
|
566
|
+
convert
|
567
|
+
c.png miff:- -compose atop -composite result.png
|
568
|
+
```
|
569
|
+
|
570
|
+
Two things to note here. First of all, commands that are declared in the `chain`
|
571
|
+
block will become piped together. Second, we use a special `:pipe` symbol in
|
572
|
+
the last `compose` command. This symbol indicates where the piped-in image
|
573
|
+
should appear in the image sequence. You can see this in the output string. The
|
574
|
+
`miff:-` appears after c.png, as expected.
|
575
|
+
|
576
|
+
Documentation is to be continued...
|
577
|
+
|
578
|
+
## Contributing
|
579
|
+
|
580
|
+
1. Fork it
|
581
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
582
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
583
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
584
|
+
5. Create new Pull Request
|