imglab 0.2.1 → 0.3.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.
- checksums.yaml +4 -4
- data/README.md +310 -11
- data/lib/imglab/color.rb +2 -2
- data/lib/imglab/position.rb +12 -12
- data/lib/imglab/sequence.rb +45 -0
- data/lib/imglab/signature.rb +6 -4
- data/lib/imglab/source.rb +3 -3
- data/lib/imglab/srcset/utils.rb +89 -0
- data/lib/imglab/srcset.rb +73 -0
- data/lib/imglab/url/utils.rb +55 -0
- data/lib/imglab/url.rb +79 -0
- data/lib/imglab/version.rb +1 -1
- data/lib/imglab.rb +5 -81
- metadata +7 -3
- data/lib/imglab/utils.rb +0 -49
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9b66cec4bc8fd3fb132c6deae52a45fee6282e40a15e31ba1c15a8fa54868705
|
|
4
|
+
data.tar.gz: 41a3f77bb418201e13167b89c86c03d59359061dd116381508cfb76517a8d462
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d2a4c896cfdf4db54f0f2521cc50c085b87ca80ff49024341d8cc63c4be178edfdf1895b0075566c1636747d4db7cc23cb7a102d20c9e7f24b3d4beab9e7c683
|
|
7
|
+
data.tar.gz: 0e938c85258bf827bbf80dc93c330f994fcab7cb967ee882c6ae3ec37f05e4b7bd7e6c40e7fdac401e3738832d4b0728266ac3041650c2e37bc97849e21b6caf
|
data/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
Add this line to your application's Gemfile:
|
|
8
8
|
|
|
9
9
|
```ruby
|
|
10
|
-
gem "imglab", "~> 0.
|
|
10
|
+
gem "imglab", "~> 0.3"
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
And then execute:
|
|
@@ -24,7 +24,7 @@ $ gem install imglab
|
|
|
24
24
|
|
|
25
25
|
## Ruby compatibility
|
|
26
26
|
|
|
27
|
-
`imglab` has been successfully tested on the following Ruby versions: `3.1`, `3.0`, `2.7`, `2.6`, `2.5`, `2.4`, `2.3`, `2.2`, `2.1` and `2.0`.
|
|
27
|
+
`imglab` has been successfully tested on the following Ruby versions: `3.2`, `3.1`, `3.0`, `2.7`, `2.6`, `2.5`, `2.4`, `2.3`, `2.2`, `2.1` and `2.0`.
|
|
28
28
|
|
|
29
29
|
## Generating URLs
|
|
30
30
|
|
|
@@ -178,7 +178,7 @@ Imglab.url("assets", "image.jpeg", width: 500, height: 500, mode: "crop", crop:
|
|
|
178
178
|
|
|
179
179
|
### Specifying URL parameters
|
|
180
180
|
|
|
181
|
-
Some imglab parameters can receive URLs as values. It is possible to specify these parameter values as strings
|
|
181
|
+
Some imglab parameters can receive URLs as values. It is possible to specify these parameter values as strings:
|
|
182
182
|
|
|
183
183
|
```ruby
|
|
184
184
|
Imglab.url("assets", "image.jpeg", width: 500, height: 600, watermark: "logo.svg")
|
|
@@ -200,7 +200,7 @@ Imglab.url(
|
|
|
200
200
|
"image.jpeg",
|
|
201
201
|
width: 500,
|
|
202
202
|
height: 600,
|
|
203
|
-
watermark: Imglab.url("assets", "logo.svg", width: 100, format:
|
|
203
|
+
watermark: Imglab.url("assets", "logo.svg", width: 100, format: :png)
|
|
204
204
|
)
|
|
205
205
|
"https://assets.imglab-cdn.net/image.jpeg?width=500&height=600&watermark=https%3A%2F%2Fassets.imglab-cdn.net%2Flogo.svg%3Fwidth%3D100%26format%3Dpng"
|
|
206
206
|
```
|
|
@@ -213,7 +213,7 @@ Imglab.url(
|
|
|
213
213
|
"image.jpeg",
|
|
214
214
|
width: 500,
|
|
215
215
|
height: 600,
|
|
216
|
-
watermark: Imglab.url("marketing", "logo.svg", width: 100, format:
|
|
216
|
+
watermark: Imglab.url("marketing", "logo.svg", width: 100, format: :png)
|
|
217
217
|
)
|
|
218
218
|
"https://assets.imglab-cdn.net/image.jpeg?width=500&height=600&watermark=https%3A%2F%2Fmarketing.imglab-cdn.net%2Flogo.svg%3Fwidth%3D100%26format%3Dpng"
|
|
219
219
|
```
|
|
@@ -228,7 +228,7 @@ Imglab.url(
|
|
|
228
228
|
"image.jpeg",
|
|
229
229
|
width: 500,
|
|
230
230
|
height: 600,
|
|
231
|
-
watermark: Imglab.url(marketing_source, "logo.svg", width: 100, format:
|
|
231
|
+
watermark: Imglab.url(marketing_source, "logo.svg", width: 100, format: :png)
|
|
232
232
|
)
|
|
233
233
|
```
|
|
234
234
|
|
|
@@ -257,8 +257,8 @@ Imglab.url("assets", "image.jpeg", width: 500, expires: 1.hour.from_now)
|
|
|
257
257
|
For on-premises imglab server is possible to define custom sources pointing to your server location.
|
|
258
258
|
|
|
259
259
|
* `:https` - a `boolean` value specifying if the source should use https or not (default: `true`)
|
|
260
|
-
* `:host` - a `string` specifying the host where the imglab server is located. (default: `imglab-cdn.net`)
|
|
261
|
-
* `:port` -
|
|
260
|
+
* `:host` - a `string` specifying the host where the imglab server is located. (default: `"imglab-cdn.net"`)
|
|
261
|
+
* `:port` - an `integer` specifying a port where the imglab server is located. (default: `nil`)
|
|
262
262
|
* `:subdomains` - a `boolean` value specifying if the source should be specified using subdomains instead of using the path. (default: `true`)
|
|
263
263
|
|
|
264
264
|
If we have our on-premises imglab server at `http://my-company.com:8080` with a source named `images` we can use the following source settings to access a `logo.png` image:
|
|
@@ -266,7 +266,7 @@ If we have our on-premises imglab server at `http://my-company.com:8080` with a
|
|
|
266
266
|
```ruby
|
|
267
267
|
source = Imglab::Source.new("images", https: false, host: "my-company.com", port: 8080)
|
|
268
268
|
|
|
269
|
-
Imglab.url(source, "logo.png", width: 300, height: 300, format:
|
|
269
|
+
Imglab.url(source, "logo.png", width: 300, height: 300, format: :png)
|
|
270
270
|
"http://images.my-company.com:8080/logo.png?width=300&height=300&format=png"
|
|
271
271
|
```
|
|
272
272
|
|
|
@@ -282,7 +282,7 @@ source = Imglab::Source.new(
|
|
|
282
282
|
secure_salt: "images-secure-salt"
|
|
283
283
|
)
|
|
284
284
|
|
|
285
|
-
Imglab.url(source, "logo.png", width: 300, height: 300, format:
|
|
285
|
+
Imglab.url(source, "logo.png", width: 300, height: 300, format: :png)
|
|
286
286
|
"http://images.my-company.com:8080/logo.png?width=300&height=300&format=png&signature=generated-signature"
|
|
287
287
|
```
|
|
288
288
|
|
|
@@ -299,10 +299,309 @@ source = Imglab::Source.new(
|
|
|
299
299
|
subdomains: false
|
|
300
300
|
)
|
|
301
301
|
|
|
302
|
-
Imglab.url(source, "logo.png", width: 300, height: 300, format:
|
|
302
|
+
Imglab.url(source, "logo.png", width: 300, height: 300, format: :png)
|
|
303
303
|
"http://my-company.com:8080/images/logo.png?width=300&height=300&format=png"
|
|
304
304
|
```
|
|
305
305
|
|
|
306
|
+
## Generating srcsets
|
|
307
|
+
|
|
308
|
+
You can use `Imglab.srcset` function to generate custom string values for `srcset` attributes, to be used for Web responsive images inside an `<img>` HTML element or picture `<source>`.
|
|
309
|
+
|
|
310
|
+
This function works similarly to `Imglab.url`, expecting the same parameters and values, except for some specific query parameters that have a special meaning and can receive `Range` and arrays as values.
|
|
311
|
+
|
|
312
|
+
> To learn more about responsive images and the `srcset` attribute, you can take a look to the [MDN article about responsive images](https://developer.mozilla.org/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images).
|
|
313
|
+
|
|
314
|
+
### Fixed size
|
|
315
|
+
|
|
316
|
+
When enough information is provided about the image output size (using `width` or `height` parameters), `srcset` function will generate URLs with a default sequence of device pixel ratios:
|
|
317
|
+
|
|
318
|
+
For the following example we are specying a fixed value of `500` pixels for `width` parameter:
|
|
319
|
+
|
|
320
|
+
```ruby
|
|
321
|
+
Imglab.srcset("assets", "image.jpeg", width: 500)
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
Generating the following output:
|
|
325
|
+
|
|
326
|
+
```html
|
|
327
|
+
https://assets.imglab-cdn.net/image.jpeg?width=500&dpr=1 1x,
|
|
328
|
+
https://assets.imglab-cdn.net/image.jpeg?width=500&dpr=2 2x,
|
|
329
|
+
https://assets.imglab-cdn.net/image.jpeg?width=500&dpr=3 3x,
|
|
330
|
+
https://assets.imglab-cdn.net/image.jpeg?width=500&dpr=4 4x,
|
|
331
|
+
https://assets.imglab-cdn.net/image.jpeg?width=500&dpr=5 5x,
|
|
332
|
+
https://assets.imglab-cdn.net/image.jpeg?width=500&dpr=6 6x
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
A very common practice consists in reducing the quality of images with high pixel density, decreasing the final file size. To achieve this you can optionally specify a Ruby `Range` value for `quality` parameter, gradually reducing the file size while increasing the image size.
|
|
336
|
+
|
|
337
|
+
In this example we are specifying a fixed `width` value of `500` pixels and a `quality` range between `80` and `40`:
|
|
338
|
+
|
|
339
|
+
```ruby
|
|
340
|
+
Imglab.srcset("assets", "image.jpeg", width: 500, quality: 80..40)
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
```html
|
|
344
|
+
https://assets.imglab-cdn.net/image.jpeg?width=500&quality=80&dpr=1 1x,
|
|
345
|
+
https://assets.imglab-cdn.net/image.jpeg?width=500&quality=70&dpr=2 2x,
|
|
346
|
+
https://assets.imglab-cdn.net/image.jpeg?width=500&quality=61&dpr=3 3x,
|
|
347
|
+
https://assets.imglab-cdn.net/image.jpeg?width=500&quality=53&dpr=4 4x,
|
|
348
|
+
https://assets.imglab-cdn.net/image.jpeg?width=500&quality=46&dpr=5 5x,
|
|
349
|
+
https://assets.imglab-cdn.net/image.jpeg?width=500&quality=40&dpr=6 6x
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
A custom `Range` value can be set for `dpr` parameter too, overriding the default sequence of generated dprs:
|
|
353
|
+
|
|
354
|
+
```ruby
|
|
355
|
+
Imglab.srcset("assets", "image.jpeg", width: 500, dpr: 1..4)
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
```html
|
|
359
|
+
https://assets.imglab-cdn.net/image.jpeg?width=500&dpr=1 1x,
|
|
360
|
+
https://assets.imglab-cdn.net/image.jpeg?width=500&dpr=2 2x,
|
|
361
|
+
https://assets.imglab-cdn.net/image.jpeg?width=500&dpr=3 3x,
|
|
362
|
+
https://assets.imglab-cdn.net/image.jpeg?width=500&dpr=4 4x
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
Using `Range` values for `dpr` and `quality` parameters in the same `srcset` call is also possible:
|
|
366
|
+
|
|
367
|
+
```ruby
|
|
368
|
+
Imglab.srcset("assets", "image.jpeg", width: 500, dpr: 1..4, quality: 80..40)
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
```html
|
|
372
|
+
https://assets.imglab-cdn.net/image.jpeg?width=500&dpr=1&quality=80 1x,
|
|
373
|
+
https://assets.imglab-cdn.net/image.jpeg?width=500&dpr=2&quality=63 2x,
|
|
374
|
+
https://assets.imglab-cdn.net/image.jpeg?width=500&dpr=3&quality=50 3x,
|
|
375
|
+
https://assets.imglab-cdn.net/image.jpeg?width=500&dpr=4&quality=40 4x
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
If necessary you can also use arrays with explicit values for `dpr` and `quality`:
|
|
379
|
+
|
|
380
|
+
```ruby
|
|
381
|
+
Imglab.srcset("assets", "image.jpeg", width: 500, dpr: [1, 2, 3], quality: [80, 75, 60])
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
```html
|
|
385
|
+
https://assets.imglab-cdn.net/image.jpeg?width=500&dpr=1&quality=80 1x,
|
|
386
|
+
https://assets.imglab-cdn.net/image.jpeg?width=500&dpr=2&quality=75 2x,
|
|
387
|
+
https://assets.imglab-cdn.net/image.jpeg?width=500&dpr=3&quality=60 3x
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
Or even use a specific `quality` value for all the URLs in the same srcset:
|
|
391
|
+
|
|
392
|
+
```ruby
|
|
393
|
+
Imglab.srcset("assets", "image.jpeg", width: 500, dpr: [1, 2, 3], quality: 70)
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
```html
|
|
397
|
+
https://assets.imglab-cdn.net/image.jpeg?width=500&dpr=1&quality=70 1x,
|
|
398
|
+
https://assets.imglab-cdn.net/image.jpeg?width=500&dpr=2&quality=70 2x,
|
|
399
|
+
https://assets.imglab-cdn.net/image.jpeg?width=500&dpr=3&quality=70 3x
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
### Fluid width
|
|
403
|
+
|
|
404
|
+
When a specific sequence of widths is required you can use a `Range`, `sequence`, or array for `width` parameter.
|
|
405
|
+
|
|
406
|
+
When a `Range` value is used, a sequence with a default size of 16 URLs will be generated inside the specified interval:
|
|
407
|
+
|
|
408
|
+
```ruby
|
|
409
|
+
Imglab.srcset("assets", "image.jpeg", width: 100..2000)
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
```html
|
|
413
|
+
https://assets.imglab-cdn.net/image.jpeg?width=100 100w,
|
|
414
|
+
https://assets.imglab-cdn.net/image.jpeg?width=122 122w,
|
|
415
|
+
https://assets.imglab-cdn.net/image.jpeg?width=149 149w,
|
|
416
|
+
https://assets.imglab-cdn.net/image.jpeg?width=182 182w,
|
|
417
|
+
https://assets.imglab-cdn.net/image.jpeg?width=222 222w,
|
|
418
|
+
https://assets.imglab-cdn.net/image.jpeg?width=271 271w,
|
|
419
|
+
https://assets.imglab-cdn.net/image.jpeg?width=331 331w,
|
|
420
|
+
https://assets.imglab-cdn.net/image.jpeg?width=405 405w,
|
|
421
|
+
https://assets.imglab-cdn.net/image.jpeg?width=494 494w,
|
|
422
|
+
https://assets.imglab-cdn.net/image.jpeg?width=603 603w,
|
|
423
|
+
https://assets.imglab-cdn.net/image.jpeg?width=737 737w,
|
|
424
|
+
https://assets.imglab-cdn.net/image.jpeg?width=900 900w,
|
|
425
|
+
https://assets.imglab-cdn.net/image.jpeg?width=1099 1099w,
|
|
426
|
+
https://assets.imglab-cdn.net/image.jpeg?width=1341 1341w,
|
|
427
|
+
https://assets.imglab-cdn.net/image.jpeg?width=1638 1638w,
|
|
428
|
+
https://assets.imglab-cdn.net/image.jpeg?width=2000 2000w
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
If required you can specify a `Range` value for `quality` parameter too:
|
|
432
|
+
|
|
433
|
+
```ruby
|
|
434
|
+
Imglab.srcset("assets", "image.jpeg", width: 100..2000, quality: 80..40)
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
```html
|
|
438
|
+
https://assets.imglab-cdn.net/image.jpeg?width=100&quality=80 100w,
|
|
439
|
+
https://assets.imglab-cdn.net/image.jpeg?width=122&quality=76 122w,
|
|
440
|
+
https://assets.imglab-cdn.net/image.jpeg?width=149&quality=73 149w,
|
|
441
|
+
https://assets.imglab-cdn.net/image.jpeg?width=182&quality=70 182w,
|
|
442
|
+
https://assets.imglab-cdn.net/image.jpeg?width=222&quality=66 222w,
|
|
443
|
+
https://assets.imglab-cdn.net/image.jpeg?width=271&quality=63 271w,
|
|
444
|
+
https://assets.imglab-cdn.net/image.jpeg?width=331&quality=61 331w,
|
|
445
|
+
https://assets.imglab-cdn.net/image.jpeg?width=405&quality=58 405w,
|
|
446
|
+
https://assets.imglab-cdn.net/image.jpeg?width=494&quality=55 494w,
|
|
447
|
+
https://assets.imglab-cdn.net/image.jpeg?width=603&quality=53 603w,
|
|
448
|
+
https://assets.imglab-cdn.net/image.jpeg?width=737&quality=50 737w,
|
|
449
|
+
https://assets.imglab-cdn.net/image.jpeg?width=900&quality=48 900w,
|
|
450
|
+
https://assets.imglab-cdn.net/image.jpeg?width=1099&quality=46 1099w,
|
|
451
|
+
https://assets.imglab-cdn.net/image.jpeg?width=1341&quality=44 1341w,
|
|
452
|
+
https://assets.imglab-cdn.net/image.jpeg?width=1638&quality=42 1638w,
|
|
453
|
+
https://assets.imglab-cdn.net/image.jpeg?width=2000&quality=40 2000w
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
If you want to generate a sequence of numbers for `width` parameter with a specific number of URLs you can use `Imglab::Sequence` module helper:
|
|
457
|
+
|
|
458
|
+
```ruby
|
|
459
|
+
# Remember to include Imglab::Sequence module before using sequence helper
|
|
460
|
+
include Imglab::Sequence
|
|
461
|
+
|
|
462
|
+
# Generating a srcset string with a sequence between 100 and 2000 pixels for width parameter with a size of 5 URLs
|
|
463
|
+
Imglab.srcset("assets", "image.jpeg", width: sequence(100, 2000, 5))
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
```html
|
|
467
|
+
https://assets.imglab-cdn.net/image.jpeg?width=100 100w,
|
|
468
|
+
https://assets.imglab-cdn.net/image.jpeg?width=211 211w,
|
|
469
|
+
https://assets.imglab-cdn.net/image.jpeg?width=447 447w,
|
|
470
|
+
https://assets.imglab-cdn.net/image.jpeg?width=946 946w,
|
|
471
|
+
https://assets.imglab-cdn.net/image.jpeg?width=2000 2000w
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
Using an array with specific values will generate URLs only for those widths:
|
|
475
|
+
|
|
476
|
+
```ruby
|
|
477
|
+
Imglab.srcset("assets", "image.jpeg", width: [100, 300, 500])
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
```html
|
|
481
|
+
https://assets.imglab-cdn.net/image.jpeg?width=100 100w,
|
|
482
|
+
https://assets.imglab-cdn.net/image.jpeg?width=300 300w,
|
|
483
|
+
https://assets.imglab-cdn.net/image.jpeg?width=500 500w
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
It is also possible to specify an array of values for `height` and `quality` parameters:
|
|
487
|
+
|
|
488
|
+
```ruby
|
|
489
|
+
Imglab.srcset("assets", "image.jpeg", width: [100, 300, 500], height: [200, 400, 600], quality: [75, 70, 65])
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
```html
|
|
493
|
+
https://assets.imglab-cdn.net/image.jpeg?width=100&height=200&quality=75 100w,
|
|
494
|
+
https://assets.imglab-cdn.net/image.jpeg?width=300&height=400&quality=70 300w,
|
|
495
|
+
https://assets.imglab-cdn.net/image.jpeg?width=500&height=600&quality=65 500w
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
### No size
|
|
499
|
+
|
|
500
|
+
When `srcset` function doesn't have information about the image output size (`width` or `height` parameters are not set) it will generate a default sequence of 16 URLs specifying a `width` value with an interval between `100` and `8192` pixels:
|
|
501
|
+
|
|
502
|
+
```ruby
|
|
503
|
+
Imglab.srcset("assets", "image.jpeg")
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
```html
|
|
507
|
+
https://assets.imglab-cdn.net/image.jpeg?width=100 100w,
|
|
508
|
+
https://assets.imglab-cdn.net/image.jpeg?width=134 134w,
|
|
509
|
+
https://assets.imglab-cdn.net/image.jpeg?width=180 180w,
|
|
510
|
+
https://assets.imglab-cdn.net/image.jpeg?width=241 241w,
|
|
511
|
+
https://assets.imglab-cdn.net/image.jpeg?width=324 324w,
|
|
512
|
+
https://assets.imglab-cdn.net/image.jpeg?width=434 434w,
|
|
513
|
+
https://assets.imglab-cdn.net/image.jpeg?width=583 583w,
|
|
514
|
+
https://assets.imglab-cdn.net/image.jpeg?width=781 781w,
|
|
515
|
+
https://assets.imglab-cdn.net/image.jpeg?width=1048 1048w,
|
|
516
|
+
https://assets.imglab-cdn.net/image.jpeg?width=1406 1406w,
|
|
517
|
+
https://assets.imglab-cdn.net/image.jpeg?width=1886 1886w,
|
|
518
|
+
https://assets.imglab-cdn.net/image.jpeg?width=2530 2530w,
|
|
519
|
+
https://assets.imglab-cdn.net/image.jpeg?width=3394 3394w,
|
|
520
|
+
https://assets.imglab-cdn.net/image.jpeg?width=4553 4553w,
|
|
521
|
+
https://assets.imglab-cdn.net/image.jpeg?width=6107 6107w,
|
|
522
|
+
https://assets.imglab-cdn.net/image.jpeg?width=8192 8192w
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
It is always possible to change this default behavior using `Imglab::Sequence` helper. In the following example we are specifying a sequence between `320` and `4096` pixels and generating 10 different URLs:
|
|
526
|
+
|
|
527
|
+
```ruby
|
|
528
|
+
include Imglab::Sequence
|
|
529
|
+
|
|
530
|
+
Imglab.srcset("assets", "image.jpeg", width: sequence(320, 4096, 10))
|
|
531
|
+
```
|
|
532
|
+
|
|
533
|
+
```html
|
|
534
|
+
https://assets.imglab-cdn.net/image.jpeg?width=320 320w,
|
|
535
|
+
https://assets.imglab-cdn.net/image.jpeg?width=425 425w,
|
|
536
|
+
https://assets.imglab-cdn.net/image.jpeg?width=564 564w,
|
|
537
|
+
https://assets.imglab-cdn.net/image.jpeg?width=749 749w,
|
|
538
|
+
https://assets.imglab-cdn.net/image.jpeg?width=994 994w,
|
|
539
|
+
https://assets.imglab-cdn.net/image.jpeg?width=1319 1319w,
|
|
540
|
+
https://assets.imglab-cdn.net/image.jpeg?width=1751 1751w,
|
|
541
|
+
https://assets.imglab-cdn.net/image.jpeg?width=2324 2324w,
|
|
542
|
+
https://assets.imglab-cdn.net/image.jpeg?width=3086 3086w,
|
|
543
|
+
https://assets.imglab-cdn.net/image.jpeg?width=4096 4096w
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
### Image aspect ratio and srcset
|
|
547
|
+
|
|
548
|
+
A usual scenario is to generate multiple URLs while maintaining the same aspect ratio for all of them. If a specific image aspect ratio is required while using `srcset` function you can set a value to `aspect-ratio` parameter along with `mode` parameter using `crop`, `contain`, `face`, or `force` resize modes.
|
|
549
|
+
|
|
550
|
+
For the following example we are using a specific value of `300` pixels for `width` and an aspect ratio of `1:1` (square), cropping the image with `crop` resize mode and setting output format to `webp`:
|
|
551
|
+
|
|
552
|
+
```ruby
|
|
553
|
+
Imglab.srcset("assets", "image.jpeg", width: 300, aspect_ratio: "1:1", mode: :crop, format: :webp)
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
```html
|
|
557
|
+
https://assets.imglab-cdn.net/image.jpeg?width=300&aspect-ratio=1%3A1&mode=crop&format=webp&dpr=1 1x,
|
|
558
|
+
https://assets.imglab-cdn.net/image.jpeg?width=300&aspect-ratio=1%3A1&mode=crop&format=webp&dpr=2 2x,
|
|
559
|
+
https://assets.imglab-cdn.net/image.jpeg?width=300&aspect-ratio=1%3A1&mode=crop&format=webp&dpr=3 3x,
|
|
560
|
+
https://assets.imglab-cdn.net/image.jpeg?width=300&aspect-ratio=1%3A1&mode=crop&format=webp&dpr=4 4x,
|
|
561
|
+
https://assets.imglab-cdn.net/image.jpeg?width=300&aspect-ratio=1%3A1&mode=crop&format=webp&dpr=5 5x,
|
|
562
|
+
https://assets.imglab-cdn.net/image.jpeg?width=300&aspect-ratio=1%3A1&mode=crop&format=webp&dpr=6 6x
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
You can instead use `height` value. In this example we are specifying a fixed value of `300` pixels for `height` parameter, a `aspect-ratio` of `16:9` (widescreen) with `crop` resize mode, and `webp` output format:
|
|
566
|
+
|
|
567
|
+
```ruby
|
|
568
|
+
Imglab.srcset("assets", "image.jpeg", height: 300, aspect_ratio: "16:9", mode: :crop, format: :webp)
|
|
569
|
+
```
|
|
570
|
+
|
|
571
|
+
```html
|
|
572
|
+
https://assets.imglab-cdn.net/image.jpeg?height=300&aspect-ratio=16%3A9&mode=crop&format=webp&dpr=1 1x,
|
|
573
|
+
https://assets.imglab-cdn.net/image.jpeg?height=300&aspect-ratio=16%3A9&mode=crop&format=webp&dpr=2 2x,
|
|
574
|
+
https://assets.imglab-cdn.net/image.jpeg?height=300&aspect-ratio=16%3A9&mode=crop&format=webp&dpr=3 3x,
|
|
575
|
+
https://assets.imglab-cdn.net/image.jpeg?height=300&aspect-ratio=16%3A9&mode=crop&format=webp&dpr=4 4x,
|
|
576
|
+
https://assets.imglab-cdn.net/image.jpeg?height=300&aspect-ratio=16%3A9&mode=crop&format=webp&dpr=5 5x,
|
|
577
|
+
https://assets.imglab-cdn.net/image.jpeg?height=300&aspect-ratio=16%3A9&mode=crop&format=webp&dpr=6 6x
|
|
578
|
+
```
|
|
579
|
+
|
|
580
|
+
You can also use fluid values for `width` parameter while maintaining the same aspect ratio for all generated URLs. In this example, we are using a `range` value between `100` and `4096` for `width` parameter, a value of `1:1` for `aspect-ratio`, `crop` resize mode and `webp` output format:
|
|
581
|
+
|
|
582
|
+
```ruby
|
|
583
|
+
Imglab.srcset("assets", "image.jpeg", width: 100..4096, aspect_ratio: "1:1", mode: :crop, format: :webp)
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
```html
|
|
587
|
+
https://assets.imglab-cdn.net/image.jpeg?width=100&aspect-ratio=1%3A1&mode=crop&format=webp 100w,
|
|
588
|
+
https://assets.imglab-cdn.net/image.jpeg?width=128&aspect-ratio=1%3A1&mode=crop&format=webp 128w,
|
|
589
|
+
https://assets.imglab-cdn.net/image.jpeg?width=164&aspect-ratio=1%3A1&mode=crop&format=webp 164w,
|
|
590
|
+
https://assets.imglab-cdn.net/image.jpeg?width=210&aspect-ratio=1%3A1&mode=crop&format=webp 210w,
|
|
591
|
+
https://assets.imglab-cdn.net/image.jpeg?width=269&aspect-ratio=1%3A1&mode=crop&format=webp 269w,
|
|
592
|
+
https://assets.imglab-cdn.net/image.jpeg?width=345&aspect-ratio=1%3A1&mode=crop&format=webp 345w,
|
|
593
|
+
https://assets.imglab-cdn.net/image.jpeg?width=442&aspect-ratio=1%3A1&mode=crop&format=webp 442w,
|
|
594
|
+
https://assets.imglab-cdn.net/image.jpeg?width=566&aspect-ratio=1%3A1&mode=crop&format=webp 566w,
|
|
595
|
+
https://assets.imglab-cdn.net/image.jpeg?width=724&aspect-ratio=1%3A1&mode=crop&format=webp 724w,
|
|
596
|
+
https://assets.imglab-cdn.net/image.jpeg?width=928&aspect-ratio=1%3A1&mode=crop&format=webp 928w,
|
|
597
|
+
https://assets.imglab-cdn.net/image.jpeg?width=1188&aspect-ratio=1%3A1&mode=crop&format=webp 1188w,
|
|
598
|
+
https://assets.imglab-cdn.net/image.jpeg?width=1522&aspect-ratio=1%3A1&mode=crop&format=webp 1522w,
|
|
599
|
+
https://assets.imglab-cdn.net/image.jpeg?width=1949&aspect-ratio=1%3A1&mode=crop&format=webp 1949w,
|
|
600
|
+
https://assets.imglab-cdn.net/image.jpeg?width=2497&aspect-ratio=1%3A1&mode=crop&format=webp 2497w,
|
|
601
|
+
https://assets.imglab-cdn.net/image.jpeg?width=3198&aspect-ratio=1%3A1&mode=crop&format=webp 3198w,
|
|
602
|
+
https://assets.imglab-cdn.net/image.jpeg?width=4096&aspect-ratio=1%3A1&mode=crop&format=webp 4096w
|
|
603
|
+
```
|
|
604
|
+
|
|
306
605
|
## License
|
|
307
606
|
|
|
308
607
|
imglab source code is released under [MIT License](LICENSE).
|
data/lib/imglab/color.rb
CHANGED
|
@@ -150,7 +150,7 @@ module Imglab::Color
|
|
|
150
150
|
whitesmoke
|
|
151
151
|
yellow
|
|
152
152
|
yellowgreen
|
|
153
|
-
]
|
|
153
|
+
].freeze
|
|
154
154
|
|
|
155
155
|
# Returns a formatted color value as string.
|
|
156
156
|
#
|
|
@@ -179,7 +179,7 @@ module Imglab::Color
|
|
|
179
179
|
when args.size == 4 && valid_components?(*args)
|
|
180
180
|
args.join(",")
|
|
181
181
|
else
|
|
182
|
-
raise ArgumentError
|
|
182
|
+
raise ArgumentError, "Invalid color"
|
|
183
183
|
end
|
|
184
184
|
end
|
|
185
185
|
|
data/lib/imglab/position.rb
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
module Imglab::Position
|
|
2
2
|
extend self
|
|
3
3
|
|
|
4
|
-
HORIZONTAL = %w[left center right]
|
|
5
|
-
VERTICAL = %w[top middle bottom]
|
|
4
|
+
HORIZONTAL = %w[left center right].freeze
|
|
5
|
+
VERTICAL = %w[top middle bottom].freeze
|
|
6
6
|
|
|
7
7
|
# Returns a formatted position value as string.
|
|
8
8
|
#
|
|
9
|
-
# @param
|
|
9
|
+
# @param directions [Array<String>, String] the position with two directions or one single direction as strings.
|
|
10
10
|
# @return [String] the formatted position with the specified arguments.
|
|
11
11
|
# @raise [ArgumentError] when the specified arguments are not a valid position.
|
|
12
12
|
#
|
|
@@ -20,24 +20,24 @@ module Imglab::Position
|
|
|
20
20
|
# Imglab::Position.position("left", "center") #=> ArgumentError: Invalid position
|
|
21
21
|
# @example Specify an invalid single direction position (raising ArgumentError exception)
|
|
22
22
|
# Imglab::Position.position("lefts") #=> ArgumentError: Invalid position
|
|
23
|
-
def position(*
|
|
23
|
+
def position(*directions)
|
|
24
24
|
case
|
|
25
|
-
when
|
|
26
|
-
|
|
27
|
-
when
|
|
28
|
-
|
|
25
|
+
when directions.size == 1 && valid_position?(directions[0])
|
|
26
|
+
directions[0]
|
|
27
|
+
when directions.size == 2 && valid_position?(*directions)
|
|
28
|
+
directions.join(",")
|
|
29
29
|
else
|
|
30
|
-
raise ArgumentError
|
|
30
|
+
raise ArgumentError, "Invalid position"
|
|
31
31
|
end
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
private
|
|
35
35
|
|
|
36
|
-
def valid_position?(*
|
|
36
|
+
def valid_position?(*directions)
|
|
37
37
|
case
|
|
38
|
-
when
|
|
38
|
+
when directions.size == 1 && valid_direction?(directions[0])
|
|
39
39
|
true
|
|
40
|
-
when
|
|
40
|
+
when directions.size == 2 && valid_directions?(directions[0], directions[1])
|
|
41
41
|
true
|
|
42
42
|
else
|
|
43
43
|
false
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
module Imglab::Sequence
|
|
2
|
+
extend self
|
|
3
|
+
|
|
4
|
+
DEFAULT_SIZE = 16
|
|
5
|
+
|
|
6
|
+
# Returns a geometric sequence of integer numbers inside an interval and with specific size as array.
|
|
7
|
+
#
|
|
8
|
+
# @param first [Integer] the first integer number of the sequence.
|
|
9
|
+
# @param last [Integer] the last integer number of the sequence.
|
|
10
|
+
# @param size [Integer] the size of the sequence.
|
|
11
|
+
# @return [Array<Integer>] a sequence of integer numbers as array.
|
|
12
|
+
#
|
|
13
|
+
# @example Specify an ascending sequence of default size
|
|
14
|
+
# Imglab::Sequence.sequence(100, 8192) #=> [100, 134, 180, 241, 324, 434, 583, 781, 1048, 1406, 1886, 2530, 3394, 4553, 6107, 8192]
|
|
15
|
+
# @example Specify an ascending sequence of size 1
|
|
16
|
+
# Imglab::Sequence.sequence(100, 8192, 1) #=> [100]
|
|
17
|
+
# @example Specify an ascending sequence of size 2
|
|
18
|
+
# Imglab::Sequence.sequence(100, 8192, 2) #=> [100, 8192]
|
|
19
|
+
# @example Specify an ascending sequence of size 4
|
|
20
|
+
# Imglab::Sequence.sequence(100, 8192, 4) #=> [100, 434, 1886, 8192]
|
|
21
|
+
# @example Specify a descending sequence of size 6
|
|
22
|
+
# Imglab::Sequence.sequence(70, 60, 6) #=> [70, 68, 66, 64, 62, 60]
|
|
23
|
+
def sequence(first, last, size = DEFAULT_SIZE)
|
|
24
|
+
return [] if size <= 0
|
|
25
|
+
return [first] if size == 1
|
|
26
|
+
return [first, last] if size == 2
|
|
27
|
+
|
|
28
|
+
ratio = (last / first.to_f) ** (1 / (size - 1).to_f)
|
|
29
|
+
|
|
30
|
+
progression(first, ratio).take(size - 1).map(&:round).push(last)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def progression(first, ratio)
|
|
36
|
+
n = first
|
|
37
|
+
|
|
38
|
+
Enumerator.new do |y|
|
|
39
|
+
loop do
|
|
40
|
+
y << n
|
|
41
|
+
n *= ratio
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
data/lib/imglab/signature.rb
CHANGED
|
@@ -1,22 +1,24 @@
|
|
|
1
1
|
require "base64"
|
|
2
2
|
require "openssl"
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
module Imglab::Signature
|
|
5
|
+
extend self
|
|
6
|
+
|
|
5
7
|
# Returns a generated signature for a source, path and encoded parameters.
|
|
6
8
|
#
|
|
7
9
|
# @param source [Imglab::Source] the source used to generate the signature.
|
|
8
10
|
# @param path [String] the path of the resource.
|
|
9
11
|
# @param encoded_params [String] encoded query params of the URL to generate the signature.
|
|
10
12
|
# @return [String]
|
|
11
|
-
def
|
|
13
|
+
def generate(source, path, encoded_params = nil)
|
|
12
14
|
decoded_secure_key = Base64.decode64(source.secure_key)
|
|
13
15
|
decoded_secure_salt = Base64.decode64(source.secure_salt)
|
|
14
16
|
|
|
15
17
|
data = "#{decoded_secure_salt}/#{path}"
|
|
16
18
|
data = encoded_params ? "#{data}?#{encoded_params}" : data
|
|
17
19
|
|
|
18
|
-
|
|
20
|
+
digest = OpenSSL::HMAC.digest(OpenSSL::Digest.new("sha256"), decoded_secure_key, data)
|
|
19
21
|
|
|
20
|
-
Base64.urlsafe_encode64(
|
|
22
|
+
Base64.urlsafe_encode64(digest).tr("=", "")
|
|
21
23
|
end
|
|
22
24
|
end
|
data/lib/imglab/source.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
class Imglab::Source
|
|
2
2
|
DEFAULT_HTTPS = true
|
|
3
|
-
DEFAULT_HOST = "imglab-cdn.net"
|
|
3
|
+
DEFAULT_HOST = "imglab-cdn.net".freeze
|
|
4
4
|
DEFAULT_SUBDOMAINS = true
|
|
5
5
|
|
|
6
6
|
attr_reader :name, :https, :port, :secure_key, :secure_salt, :subdomains
|
|
@@ -39,7 +39,7 @@ class Imglab::Source
|
|
|
39
39
|
@subdomains ? "#{@name}.#{@host}" : @host
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
-
# Returns
|
|
42
|
+
# Returns the path to be used with the source.
|
|
43
43
|
#
|
|
44
44
|
# @param path [String]
|
|
45
45
|
# @return [String]
|
|
@@ -51,7 +51,7 @@ class Imglab::Source
|
|
|
51
51
|
#
|
|
52
52
|
# @return [Boolean]
|
|
53
53
|
def is_secure?
|
|
54
|
-
@secure_key && @secure_salt
|
|
54
|
+
!!(@secure_key && @secure_salt)
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
# Overrided inspect method to don't show sensitive attributes like secure_key and secure_salt.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
module Imglab::Srcset
|
|
2
|
+
module Utils
|
|
3
|
+
extend self
|
|
4
|
+
|
|
5
|
+
NORMALIZE_KEYS = %w[dpr width].freeze
|
|
6
|
+
|
|
7
|
+
SPLIT_DPR_KEYS = %w[dpr quality].freeze
|
|
8
|
+
SPLIT_WIDTH_KEYS = %w[width height quality].freeze
|
|
9
|
+
|
|
10
|
+
# Returns normalized params, rejecting values with keys included in normalized keys and with empty arrays.
|
|
11
|
+
#
|
|
12
|
+
# @param params [Hash]
|
|
13
|
+
# @return [Hash]
|
|
14
|
+
def normalize_params(params)
|
|
15
|
+
params.inject({}) do |normalized_params, (key, value)|
|
|
16
|
+
normalized_params.merge(normalize_param(key.to_s, value))
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Returns an array with the parameters to use in different URLs for a srcset split by dpr parameter.
|
|
21
|
+
#
|
|
22
|
+
# @param params [Hash]
|
|
23
|
+
# @return [Array]
|
|
24
|
+
def split_params_dpr(params)
|
|
25
|
+
split_values(params, SPLIT_DPR_KEYS, params.fetch("dpr").size).map do |dpr, quality|
|
|
26
|
+
params.merge(
|
|
27
|
+
{
|
|
28
|
+
"dpr" => dpr,
|
|
29
|
+
"quality" => quality
|
|
30
|
+
}.delete_if { |key, _value| !params.key?(key) }
|
|
31
|
+
)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Returns an array with the parameters to use in different URLs for a srcset split by width parameter.
|
|
36
|
+
#
|
|
37
|
+
# @param params [Hash]
|
|
38
|
+
# @return [Array]
|
|
39
|
+
def split_params_width(params)
|
|
40
|
+
split_values(params, SPLIT_WIDTH_KEYS, split_size(params.fetch("width"))).map do |width, height, quality|
|
|
41
|
+
params.merge(
|
|
42
|
+
{
|
|
43
|
+
"width" => width,
|
|
44
|
+
"height" => height,
|
|
45
|
+
"quality" => quality
|
|
46
|
+
}.delete_if { |key, _value| !params.key?(key) }
|
|
47
|
+
)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
|
|
53
|
+
def normalize_param(key, value)
|
|
54
|
+
case
|
|
55
|
+
when NORMALIZE_KEYS.include?(key) && value == []
|
|
56
|
+
{}
|
|
57
|
+
else
|
|
58
|
+
{ key => value }
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def split_size(value)
|
|
63
|
+
case value
|
|
64
|
+
when Range
|
|
65
|
+
Imglab::Sequence::DEFAULT_SIZE
|
|
66
|
+
when Array
|
|
67
|
+
value.size
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def split_values(params, keys, size)
|
|
72
|
+
values = keys.map { |key| split_value(key, params[key], size) }
|
|
73
|
+
values.first.zip(*values[1..-1])
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def split_value(key, value, size)
|
|
77
|
+
case
|
|
78
|
+
when key == "dpr" && value.instance_of?(Range)
|
|
79
|
+
value.to_a
|
|
80
|
+
when value.instance_of?(Range)
|
|
81
|
+
Imglab::Sequence.sequence(value.first, value.last, size)
|
|
82
|
+
when value.instance_of?(Array)
|
|
83
|
+
value
|
|
84
|
+
else
|
|
85
|
+
Array.new(size, value)
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
module Imglab
|
|
2
|
+
extend self
|
|
3
|
+
|
|
4
|
+
FLUID_CLASSES = [Array, Range].freeze
|
|
5
|
+
|
|
6
|
+
DEFAULT_DPRS = [1, 2, 3, 4, 5, 6].freeze
|
|
7
|
+
DEFAULT_WIDTHS = Sequence.sequence(100, 8192).freeze
|
|
8
|
+
|
|
9
|
+
# Returns a formatted srcset `string` with the specified parameters.
|
|
10
|
+
#
|
|
11
|
+
# @param source [String, Imglab::Source] the source name or source object
|
|
12
|
+
# @param path [String] the path where the resource is located
|
|
13
|
+
# @param params [Hash] the query parameters that we want to use
|
|
14
|
+
# @return [String] the srcset value as a list of formatted URLs with the specified arguments
|
|
15
|
+
# @raise [ArgumentError] when the source name or source parameter has a not expected type or params are using unexpected values
|
|
16
|
+
#
|
|
17
|
+
# @example Creating a srcset with three different device pixel ratios:
|
|
18
|
+
# Imglab.srcset("assets", "example.jpeg", width: 500, dpr: [1, 2, 3]) #=> "https://assets.imglab-cdn.net/example.jpeg?width=500&dpr=1 1x,\n..."
|
|
19
|
+
# @example Creating a srcset with three different device pixel ratios using a range:
|
|
20
|
+
# Imglab.srcset("assets", "example.jpeg", width: 500, dpr: 1..3) #=> "https://assets.imglab-cdn.net/example.jpeg?width=500&dpr=1 1x,\n..."
|
|
21
|
+
# @example Creating a srcset with three different width sizes:
|
|
22
|
+
# Imglab.srcset("assets", "example.jpeg", width: [400, 800, 1200], format: "webp") #=> "https://assets.imglab-cdn.net/example.jpeg?width=400&format=webp 400w,\n..."
|
|
23
|
+
# @example Creating a srcset with a range of width sizes:
|
|
24
|
+
# Imglab.srcset("assets", "example.jpeg", width: 400..1200, format: "webp") #=> "https://assets.imglab-cdn.net/example.jpeg?width=400&format=webp 400w,\n..."
|
|
25
|
+
def srcset(source, path, params = {})
|
|
26
|
+
params = Srcset::Utils.normalize_params(params)
|
|
27
|
+
|
|
28
|
+
width, height, dpr = params.values_at("width", "height", "dpr")
|
|
29
|
+
|
|
30
|
+
case
|
|
31
|
+
when is_fluid?(width)
|
|
32
|
+
if is_fluid?(dpr)
|
|
33
|
+
raise ArgumentError, "dpr as #{dpr.class} is not allowed when width is Array or Range"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
srcset_width(source, path, params)
|
|
37
|
+
when width || height
|
|
38
|
+
if is_fluid?(height)
|
|
39
|
+
raise ArgumentError, "height as #{height.class} is not allowed when width is not an Array or Range"
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
srcset_dpr(source, path, params.merge("dpr" => dprs(params)))
|
|
43
|
+
else
|
|
44
|
+
if is_fluid?(dpr)
|
|
45
|
+
raise ArgumentError, "dpr as #{dpr.class} is not allowed without specifying width or height"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
srcset_width(source, path, params.merge("width" => DEFAULT_WIDTHS))
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
private
|
|
53
|
+
|
|
54
|
+
def dprs(params)
|
|
55
|
+
is_fluid?(params["dpr"]) ? params["dpr"] : DEFAULT_DPRS
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def is_fluid?(value)
|
|
59
|
+
FLUID_CLASSES.include?(value.class)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def srcset_dpr(source, path, params)
|
|
63
|
+
Srcset::Utils.split_params_dpr(params).map do |split_params|
|
|
64
|
+
"#{url(source, path, split_params)} #{split_params.fetch('dpr')}x"
|
|
65
|
+
end.join(",\n")
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def srcset_width(source, path, params)
|
|
69
|
+
Srcset::Utils.split_params_width(params).map do |split_params|
|
|
70
|
+
"#{url(source, path, split_params)} #{split_params.fetch('width')}w"
|
|
71
|
+
end.join(",\n")
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
module Imglab::Url
|
|
2
|
+
module Utils
|
|
3
|
+
extend self
|
|
4
|
+
|
|
5
|
+
NORMALIZE_PATH_PREFIX_REGEXP = Regexp.compile(/\A\/*/)
|
|
6
|
+
NORMALIZE_PATH_SUFFIX_REGEXP = Regexp.compile(/\/*$/)
|
|
7
|
+
|
|
8
|
+
WEB_URI_SCHEMES = %w[https http].freeze
|
|
9
|
+
|
|
10
|
+
# Returns a normalized path where suffix and prefix slashes are removed.
|
|
11
|
+
#
|
|
12
|
+
# @param path [String]
|
|
13
|
+
# @return [String]
|
|
14
|
+
def normalize_path(path)
|
|
15
|
+
path.gsub(NORMALIZE_PATH_PREFIX_REGEXP, "").gsub(NORMALIZE_PATH_SUFFIX_REGEXP, "")
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Returns normalized params, transforming keys with undercores to hyphens.
|
|
19
|
+
#
|
|
20
|
+
# @param params [Hash]
|
|
21
|
+
# @return [Hash]
|
|
22
|
+
def normalize_params(params)
|
|
23
|
+
params.inject({}) do |normalized_params, value|
|
|
24
|
+
normalized_params.merge(normalize_param(dasherize(value[0]), value[1]))
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Returns a boolean value indicating whether a string is a valid HTTP/HTTPS URI or not.
|
|
29
|
+
#
|
|
30
|
+
# @param uri [String]
|
|
31
|
+
# @return [Boolean]
|
|
32
|
+
def web_uri?(uri)
|
|
33
|
+
WEB_URI_SCHEMES.include?(URI.parse(uri).scheme)
|
|
34
|
+
rescue URI::Error
|
|
35
|
+
false
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
def dasherize(value)
|
|
41
|
+
value.to_s.gsub("_", "-")
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def normalize_param(key, value)
|
|
45
|
+
case
|
|
46
|
+
when key == "expires" && value.instance_of?(Time)
|
|
47
|
+
{ key => value.to_i }
|
|
48
|
+
when value == nil
|
|
49
|
+
{ key => "" }
|
|
50
|
+
else
|
|
51
|
+
{ key => value }
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
data/lib/imglab/url.rb
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
module Imglab
|
|
2
|
+
extend self
|
|
3
|
+
|
|
4
|
+
# Returns a formatted URL `string` with the specified arguments.
|
|
5
|
+
#
|
|
6
|
+
# @param source [String, Imglab::Source] the source name or source object
|
|
7
|
+
# @param path [String] the path where the resource is located
|
|
8
|
+
# @param params [Hash] the query parameters that we want to use
|
|
9
|
+
# @return [String] the formatted URL with the specified arguments
|
|
10
|
+
# @raise [ArgumentError] when the source name or source parameter has a not expected type
|
|
11
|
+
#
|
|
12
|
+
# @example Creating a URL specifying source name as string
|
|
13
|
+
# Imglab.url("assets", "example.jpeg", width: 500, height: 600) #=> "https://assets.imglab-cdn.net/example.jpeg?width=500&height=600"
|
|
14
|
+
# @example Creating a URL specifying a Imglab::Source
|
|
15
|
+
# Imglab.url(Imglab::Source.new("assets"), "example.jpeg", width: 500, height: 600) #=> "https://assets.imglab-cdn.net/example.jpeg?width=500&height=600"
|
|
16
|
+
def url(source, path, params = {})
|
|
17
|
+
case source
|
|
18
|
+
when String
|
|
19
|
+
url_for_source(Source.new(source), path, params)
|
|
20
|
+
when Source
|
|
21
|
+
url_for_source(source, path, params)
|
|
22
|
+
else
|
|
23
|
+
raise ArgumentError, "Invalid source name or source. A string or a #{Source.name} instance is expected"
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def url_for_source(source, path, params)
|
|
30
|
+
normalized_path = Url::Utils.normalize_path(path)
|
|
31
|
+
normalized_params = Url::Utils.normalize_params(params)
|
|
32
|
+
|
|
33
|
+
URI::Generic.new(
|
|
34
|
+
source.scheme,
|
|
35
|
+
nil,
|
|
36
|
+
source.host,
|
|
37
|
+
source.port,
|
|
38
|
+
nil,
|
|
39
|
+
File.join("/", source.path(encode_path(normalized_path))),
|
|
40
|
+
nil,
|
|
41
|
+
encode_params(source, normalized_path, normalized_params),
|
|
42
|
+
nil
|
|
43
|
+
).to_s
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def encode_path(path)
|
|
47
|
+
if Url::Utils.web_uri?(path)
|
|
48
|
+
encode_path_component(path)
|
|
49
|
+
else
|
|
50
|
+
path.split("/").map do |path_component|
|
|
51
|
+
encode_path_component(path_component)
|
|
52
|
+
end.join("/")
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def encode_path_component(path_component)
|
|
57
|
+
ERB::Util.url_encode(path_component)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def encode_params(source, path, params)
|
|
61
|
+
return encode_empty_params(source, path) if params.empty?
|
|
62
|
+
|
|
63
|
+
if source.is_secure?
|
|
64
|
+
signature = Signature.generate(source, path, URI.encode_www_form(params))
|
|
65
|
+
|
|
66
|
+
URI.encode_www_form(params.merge(signature: signature))
|
|
67
|
+
else
|
|
68
|
+
URI.encode_www_form(params)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def encode_empty_params(source, path)
|
|
73
|
+
return unless source.is_secure?
|
|
74
|
+
|
|
75
|
+
signature = Signature.generate(source, path)
|
|
76
|
+
|
|
77
|
+
URI.encode_www_form(signature: signature)
|
|
78
|
+
end
|
|
79
|
+
end
|
data/lib/imglab/version.rb
CHANGED
data/lib/imglab.rb
CHANGED
|
@@ -5,84 +5,8 @@ require "imglab/source"
|
|
|
5
5
|
require "imglab/signature"
|
|
6
6
|
require "imglab/color"
|
|
7
7
|
require "imglab/position"
|
|
8
|
-
require "imglab/
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
# @param source_name_or_source [String, Imglab::Source] the source name or source object
|
|
14
|
-
# @param path [String] the path where the resource is located
|
|
15
|
-
# @param params [Hash] the query parameters that we want to use
|
|
16
|
-
# @return [String] the formatted URL with the specified arguments
|
|
17
|
-
# @raise [ArgumentError] when the source name or source parameter has a not expected type.
|
|
18
|
-
#
|
|
19
|
-
# @example Creating a URL specifying source name as string
|
|
20
|
-
# Imglab.url("assets", "example.jpeg", width: 500, height: 600) #=> "https://assets.imglab-cdn.net/example.jpeg?width=500&height=600"
|
|
21
|
-
# @example Creating a URL specifying a Imglab::Source
|
|
22
|
-
# Imglab.url(Imglab::Source.new("assets"), "example.jpeg", width: 500, height: 600) #=> "https://assets.imglab-cdn.net/example.jpeg?width=500&height=600"
|
|
23
|
-
def self.url(source_name_or_source, path, params = {})
|
|
24
|
-
case source_name_or_source
|
|
25
|
-
when String
|
|
26
|
-
url_for_source(Source.new(source_name_or_source), path, params)
|
|
27
|
-
when Source
|
|
28
|
-
url_for_source(source_name_or_source, path, params)
|
|
29
|
-
else
|
|
30
|
-
raise ArgumentError.new("Invalid source name or source. A string or #{Imglab::Source.name} is expected.")
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
private
|
|
35
|
-
|
|
36
|
-
def self.url_for_source(source, path, params)
|
|
37
|
-
normalized_path = Utils.normalize_path(path)
|
|
38
|
-
normalized_params = Utils.normalize_params(params)
|
|
39
|
-
|
|
40
|
-
URI::Generic.new(
|
|
41
|
-
source.scheme,
|
|
42
|
-
nil,
|
|
43
|
-
source.host,
|
|
44
|
-
source.port,
|
|
45
|
-
nil,
|
|
46
|
-
File.join("/", source.path(encode_path(normalized_path))),
|
|
47
|
-
nil,
|
|
48
|
-
encode_params(source, normalized_path, normalized_params),
|
|
49
|
-
nil
|
|
50
|
-
).to_s
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def self.encode_path(path)
|
|
54
|
-
if Utils.web_uri?(path)
|
|
55
|
-
encode_path_component(path)
|
|
56
|
-
else
|
|
57
|
-
path.split("/").map do |path_component|
|
|
58
|
-
encode_path_component(path_component)
|
|
59
|
-
end.join("/")
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def self.encode_path_component(path_component)
|
|
64
|
-
ERB::Util.url_encode(path_component)
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
def self.encode_params(source, path, params)
|
|
68
|
-
return encode_empty_params(source, path) if params.empty?
|
|
69
|
-
|
|
70
|
-
if source.is_secure?
|
|
71
|
-
signature = Signature.generate(source, path, URI.encode_www_form(params))
|
|
72
|
-
|
|
73
|
-
URI.encode_www_form(params.merge(signature: signature))
|
|
74
|
-
else
|
|
75
|
-
URI.encode_www_form(params)
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
def self.encode_empty_params(source, path)
|
|
80
|
-
if source.is_secure?
|
|
81
|
-
signature = Signature.generate(source, path)
|
|
82
|
-
|
|
83
|
-
URI.encode_www_form(signature: signature)
|
|
84
|
-
else
|
|
85
|
-
nil
|
|
86
|
-
end
|
|
87
|
-
end
|
|
88
|
-
end
|
|
8
|
+
require "imglab/sequence"
|
|
9
|
+
require "imglab/url/utils"
|
|
10
|
+
require "imglab/url"
|
|
11
|
+
require "imglab/srcset/utils"
|
|
12
|
+
require "imglab/srcset"
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: imglab
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- imglab
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2023-01-13 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: Official Ruby library to integrate with imglab services.
|
|
14
14
|
email:
|
|
@@ -29,9 +29,13 @@ files:
|
|
|
29
29
|
- lib/imglab.rb
|
|
30
30
|
- lib/imglab/color.rb
|
|
31
31
|
- lib/imglab/position.rb
|
|
32
|
+
- lib/imglab/sequence.rb
|
|
32
33
|
- lib/imglab/signature.rb
|
|
33
34
|
- lib/imglab/source.rb
|
|
34
|
-
- lib/imglab/
|
|
35
|
+
- lib/imglab/srcset.rb
|
|
36
|
+
- lib/imglab/srcset/utils.rb
|
|
37
|
+
- lib/imglab/url.rb
|
|
38
|
+
- lib/imglab/url/utils.rb
|
|
35
39
|
- lib/imglab/version.rb
|
|
36
40
|
homepage: https://github.com/imglab-io/imglab-rb
|
|
37
41
|
licenses:
|
data/lib/imglab/utils.rb
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
class Imglab::Utils
|
|
2
|
-
NORMALIZE_PATH_PREFIX_REGEXP = Regexp.compile(/\A\/*/)
|
|
3
|
-
NORMALIZE_PATH_SUFFIX_REGEXP = Regexp.compile(/\/*$/)
|
|
4
|
-
|
|
5
|
-
WEB_URI_SCHEMES = %w[https http]
|
|
6
|
-
|
|
7
|
-
# Returns a normalized path where suffix and prefix slashes are removed.
|
|
8
|
-
#
|
|
9
|
-
# @param path [String]
|
|
10
|
-
# @return [String]
|
|
11
|
-
def self.normalize_path(path)
|
|
12
|
-
path.gsub(NORMALIZE_PATH_PREFIX_REGEXP, "").gsub(NORMALIZE_PATH_SUFFIX_REGEXP, "")
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
# Returns normalized params, transforming keys with undercores to hyphens.
|
|
16
|
-
#
|
|
17
|
-
# @param params [Hash]
|
|
18
|
-
# @return [Hash]
|
|
19
|
-
def self.normalize_params(params)
|
|
20
|
-
params.inject({}) do |normalized_params, value|
|
|
21
|
-
normalized_params.merge(normalize_param(dasherize(value[0]), value[1]))
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
# Returns a boolean value indicating whether a string is a valid HTTP/HTTPS URI or not.
|
|
26
|
-
#
|
|
27
|
-
# @param uri [String]
|
|
28
|
-
# @return [Boolean]
|
|
29
|
-
def self.web_uri?(uri)
|
|
30
|
-
WEB_URI_SCHEMES.include?(URI.parse(uri).scheme)
|
|
31
|
-
rescue URI::Error
|
|
32
|
-
false
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
private
|
|
36
|
-
|
|
37
|
-
def self.dasherize(value)
|
|
38
|
-
value.to_s.gsub("_", "-")
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def self.normalize_param(key, value)
|
|
42
|
-
case
|
|
43
|
-
when key == "expires" && value.instance_of?(Time)
|
|
44
|
-
{key => value.to_i}
|
|
45
|
-
else
|
|
46
|
-
{key => value}
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
end
|