jekyll_picture_tag 1.8.0 → 1.11.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.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -0
  3. data/.travis.yml +4 -7
  4. data/Dockerfile +9 -0
  5. data/docs/Gemfile.lock +183 -88
  6. data/docs/contributing.md +50 -16
  7. data/docs/example_presets.md +1 -1
  8. data/docs/global_configuration.md +55 -2
  9. data/docs/index.md +27 -21
  10. data/docs/installation.md +22 -7
  11. data/docs/presets.md +137 -55
  12. data/docs/releases.md +20 -1
  13. data/docs/usage.md +83 -39
  14. data/jekyll_picture_tag.gemspec +1 -1
  15. data/lib/jekyll_picture_tag.rb +28 -10
  16. data/lib/jekyll_picture_tag/cache.rb +3 -0
  17. data/lib/jekyll_picture_tag/cache/base.rb +59 -0
  18. data/lib/jekyll_picture_tag/cache/generated.rb +20 -0
  19. data/lib/jekyll_picture_tag/cache/source.rb +19 -0
  20. data/lib/jekyll_picture_tag/defaults/global.yml +2 -0
  21. data/lib/jekyll_picture_tag/defaults/presets.yml +2 -0
  22. data/lib/jekyll_picture_tag/generated_image.rb +85 -20
  23. data/lib/jekyll_picture_tag/img_uri.rb +1 -0
  24. data/lib/jekyll_picture_tag/instructions.rb +1 -0
  25. data/lib/jekyll_picture_tag/instructions/arg_splitter.rb +69 -0
  26. data/lib/jekyll_picture_tag/instructions/configuration.rb +47 -11
  27. data/lib/jekyll_picture_tag/instructions/preset.rb +35 -14
  28. data/lib/jekyll_picture_tag/instructions/set.rb +18 -8
  29. data/lib/jekyll_picture_tag/instructions/tag_parser.rb +59 -69
  30. data/lib/jekyll_picture_tag/output_formats/basic.rb +42 -11
  31. data/lib/jekyll_picture_tag/output_formats/img.rb +11 -0
  32. data/lib/jekyll_picture_tag/output_formats/picture.rb +22 -0
  33. data/lib/jekyll_picture_tag/router.rb +17 -0
  34. data/lib/jekyll_picture_tag/source_image.rb +60 -39
  35. data/lib/jekyll_picture_tag/srcsets/basic.rb +54 -19
  36. data/lib/jekyll_picture_tag/srcsets/pixel_ratio.rb +1 -3
  37. data/lib/jekyll_picture_tag/srcsets/width.rb +1 -1
  38. data/lib/jekyll_picture_tag/utils.rb +18 -0
  39. data/lib/jekyll_picture_tag/version.rb +1 -1
  40. data/readme.md +40 -16
  41. metadata +14 -8
@@ -1,7 +1,26 @@
1
1
  ---
2
2
  ---
3
3
  # Release History
4
-
4
+ * 1.11.0 July 27, 2020
5
+ * **Width and height attribute support!** Begone, page reflow.
6
+ * Cache image information between builds
7
+ * Change image naming format. This update will trigger all images to be regenerated, so you may
8
+ want to delete your generated images folder beforehand.
9
+ * 1.10.2 July 6, 2020
10
+ * Bugfix for fallback image files not actually getting generated
11
+ * 1.10.1 July 2, 2020
12
+ * Bugfix for erroneously regenerated images
13
+ * 1.10.0 May 11, 2020
14
+ * **Image Cropping support!** access the power of ImageMagick's `crop` function.
15
+ * Don't issue a warning when `default` preset is not found.
16
+ * Documentation improvements
17
+ * 1.9.0 Feb 2, 2020
18
+ * Add `fast_build` global setting
19
+ * Add `disabled` global setting
20
+ * Reduce unnecessary disk IO; sites with many source images should see build times improve when
21
+ no new images need to be generated.
22
+ * Add support for empty attributes; specifically so best-practice for decorative images (`alt=""`)
23
+ is possible.
5
24
  * 1.8.0 Nov 25, 2019
6
25
  * Add `data_sizes` setting for the `data_` family of output formats.
7
26
  * 1.7.1 Nov 14, 2019
@@ -1,65 +1,108 @@
1
1
  ---
2
2
  ---
3
+
3
4
  # How to use the Liquid Tag:
4
5
 
6
+ This section describes how to use JPT's liquid tag; what options it takes and what kind of information you can pass through it to influence the form of the final HTML-markup.
7
+
5
8
  ## Format:
6
9
 
7
10
  {% raw %}
8
- `{% picture [preset] (base image) [alternate images] [attributes] %}`
11
+ `{% picture [preset] (image) [crop] [alternate images & crops] [attributes] %}`
9
12
  {% endraw %}
10
13
 
11
14
  The only required argument is the base image. Line breaks and extra spaces are fine, and you can
12
15
  use liquid variables anywhere.
13
16
 
17
+ The `preset` determines the actual HTML code that gets written to your files;
18
+ it is basically a recipy that takes information that you provide in the
19
+ liquid tag and turns it into HTML markup. When the `preset` is omitted
20
+ default settings will be used, in the simplest case resulting in an `img`-tag
21
+ containing an srcset pointing to your newly generated image sizes. You are
22
+ free to override the `default` preset and define your own presets, giving
23
+ full flexibility in what JPT will write to your files. See [markup preset]({{
24
+ site.baseurl }}/presets#markup-presets) for more information on this.
25
+
14
26
  ## Examples:
15
27
 
16
28
  {% raw %}
17
29
  `{% picture example.jpg %}`
18
30
 
19
- `{% picture thumbnail example.jpg --alt Example Image %}`
31
+ `{% picture {{ page.example_liquid_picture_var }} %}`
32
+
33
+ `{% picture thumbnail example.jpg 1:1 --alt Example Image %}`
20
34
 
21
- `{% picture example.jpg --picture class="attribute-demo" %}`
35
+ `{% picture example.jpg 16:9 north --picture class="attribute-demo" %}`
22
36
 
23
37
  `{% picture blog_index {{ post.image }} --link {{ post.url }} %}`
24
38
 
25
39
  `{% picture "some example.jpg" mobile: other\ example.jpg %}`
26
40
 
27
41
  ```md
28
- {% picture
29
- hero
30
- example.jpg
31
- tablet: example_cropped.jpg
32
- mobile: example_cropped_more.jpg
33
- --alt Happy Puppy
34
- --picture class="hero"
42
+ {% picture
43
+ hero
44
+ example.jpg 16:9 east
45
+ tablet: example_cropped.jpg 3:2 east
46
+ mobile: example_cropped_more.jpg 1:1-50+0 east
47
+ --alt Happy Puppy
48
+ --picture class="hero"
35
49
  --link /
36
50
  %}
37
51
  ```
52
+
38
53
  {% endraw %}
39
54
 
40
55
  ## Argument reference
41
56
 
42
57
  Given in order:
43
58
 
44
- * **Preset**
59
+ - **Preset**
45
60
 
46
61
  Select a [markup preset]({{ site.baseurl }}/presets#markup-presets), or omit to use the `default` preset. Presets
47
62
  are collections of settings that determine nearly everything about JPT's output, from the image
48
- formats used to the exact format your markup will take.
63
+ formats used to the exact format your final HTML-markup will take.
49
64
 
50
- * **Base Image** (Required)
65
+ - **Base Image** (Required)
51
66
 
52
67
  Can be any raster image (as long as you have the required ImageMagick delegate). Relative to
53
68
  jekyll's root directory, or the `source` [setting]({{ site.baseurl }}/global_configuration) if you've configured it.
54
69
 
55
- For filenames with spaces, either use double quotes (`"my image.jpg"`) or a backslash (`my\
56
- image.jpg`).
70
+ For filenames with spaces, either use double quotes (`"my image.jpg"`) or a backslash (`my\ image.jpg`).
71
+
72
+ - **Crop**
73
+
74
+ **Check the [ installation guide ](installation) before using this feature.**
57
75
 
58
- * **Alternate images**
76
+ Crop an image to a given aspect ratio or size. This argument is given as a `geometry` and
77
+ (optionally) a `gravity`, which can appear in either order and are thin wrappers around
78
+ ImageMagick's [geometry](http://www.imagemagick.org/script/command-line-processing.php#geometry)
79
+ and [gravity](http://www.imagemagick.org/script/command-line-options.php#gravity) settings. The
80
+ values given here will override the preset settings (if present), can be given after every image,
81
+ and apply only to the preceding image.
59
82
 
60
- *Format:* `(media query preset): (filename) (...)`
83
+ Geometry can take many forms, but most likely you'll want to set an aspect ratio-- given in the
84
+ standard `width:height` ratio such as `3:2`. Gravity sets which portion of the image to keep, and
85
+ is given in compass directions (`north`, `southeast`, etc) or `center` (default). Cropping happens
86
+ before resizing; the preset `widths` setting is a post-crop value.
61
87
 
62
- *Example:* `tablet: img_cropped.jpg mobile: img_cropped_more.jpg`
88
+ If you'd like more fine-grained control, this can be offset by appending `+|-x` and (optionally)
89
+ `y` pixel values to the _geometry_ (not the gravity!). Example: `1:1+400 west` means "Crop to a
90
+ 1:1 aspect ratio, starting 400 pixels from the left side.", and `north 3:2+0+100` means "Crop to
91
+ 3:2, starting 100 pixels from the top." These can get a bit persnickety; there's nothing to stop
92
+ you from running off the side of the image. Pay attention.
93
+
94
+ For detailed documentation, see ImageMagick's
95
+ [crop](http://www.imagemagick.org/script/command-line-options.php#crop) tool.
96
+
97
+ _Note:_ If you do a lot of trial and error with these, it's a good idea to manually delete your
98
+ generated images folder more often as each change will build a new set of images without removing
99
+ the old ones.
100
+
101
+ - **Alternate images**
102
+
103
+ _Format:_ `(media query preset): (filename) (...)`
104
+
105
+ _Example:_ `tablet: img_cropped.jpg mobile: img_cropped_more.jpg`
63
106
 
64
107
  Optionally specify any number of alternate base images for given [screen
65
108
  sizes]({{ site.baseurl }}/presets/#media-presets) (specified in `_data/picture.yml`). This is called [art
@@ -70,44 +113,45 @@ Given in order:
70
113
  be provided to the browser in reverse order, and it will select the first one with an applicable
71
114
  media query.
72
115
 
73
- * **Attributes**
116
+ - **Attributes**
74
117
 
75
118
  Optionally specify any number of HTML attributes, or an href target. These will be added to any
76
119
  attributes you've set in a preset.
77
120
 
78
- * **`--link`**
121
+ - **`--link`**
122
+
123
+ _Format:_ `--link (some url)`
79
124
 
80
- *Format:* `--link (some url)`
125
+ _Examples_: `--link https://example.com`, `--link /blog/some_post/`
81
126
 
82
- *Examples*: `--link https://example.com`, `--link /blog/some_post/`
127
+ Wrap the image in an anchor tag, with the `href` attribute set to whatever value you give it.
128
+ This will override automatic source image linking, if you have enabled it.
83
129
 
84
- Wrap the image in an anchor tag, with the `href` attribute set to whatever value you give it.
85
- This will override automatic source image linking, if you have enabled it.
130
+ **Note**: If you get either mangled HTML or extra {::nomarkdown} tags when using this, read
131
+ [here]({{ site.baseurl }}/notes).
86
132
 
87
- **Note**: If you get either mangled HTML or extra {::nomarkdown} tags when using this, read
88
- [here]({{ site.baseurl }}/notes).
133
+ - **`--alt`**
89
134
 
90
- * **`--alt`**
91
-
92
- *Format:* `--alt (alt text)`
135
+ _Format:_ `--alt (alt text)`
93
136
 
94
- *Example:* `--alt Here is my alt text!`
137
+ _Example:_ `--alt Here is my alt text!`
95
138
 
96
139
  Convenience shortcut for `--img alt="..."`
97
-
98
- * **`--(element)`**
99
140
 
100
- *Format:* `--(picture|img|source|a|parent) (Standard HTML attributes)`
141
+ - **`--(element)`**
142
+
143
+ _Format:_ `--(picture|img|source|a|parent) (Standard HTML attributes)`
101
144
 
102
- *Example:* `--img class="awesome-fade-in" id="coolio" --a data-awesomeness="11"`
145
+ _Example:_ `--img class="awesome-fade-in" id="coolio" --a data-awesomeness="11"`
103
146
 
104
147
  Apply attributes to a given HTML element. Your options are:
105
148
 
106
- * `picture`
107
- * `img`
108
- * `source`
109
- * `a` (anchor tag)
110
- * `parent`
149
+ - `picture`
150
+ - `img`
151
+ - `source`
152
+ - `a` (anchor tag)
153
+ - `parent`
111
154
 
112
155
  `--parent` will be applied to the `<picture>` if present, otherwise the `<img>`; useful when
113
156
  using an `auto` output format.
157
+ **Note:** Attributes that are set in the liquid picture tag, but don't occur in the used `preset` will be ignored (e.g. adding `--picture class="cool-css"` with a preset that does not write a html `<picture>` tag).
@@ -40,7 +40,7 @@ Gem::Specification.new do |spec|
40
40
  spec.add_dependency 'addressable', '~> 2.6'
41
41
  spec.add_dependency 'mime-types', '~> 3'
42
42
  spec.add_dependency 'mini_magick', '~> 4'
43
- spec.add_dependency 'objective_elements', '~> 1.1.1'
43
+ spec.add_dependency 'objective_elements', '~> 1.1.2'
44
44
 
45
45
  spec.add_runtime_dependency 'jekyll', '< 5'
46
46
  end
@@ -9,6 +9,7 @@ require_relative 'jekyll_picture_tag/srcsets'
9
9
  require_relative 'jekyll_picture_tag/utils'
10
10
  require_relative 'jekyll_picture_tag/img_uri'
11
11
  require_relative 'jekyll_picture_tag/router'
12
+ require_relative 'jekyll_picture_tag/cache'
12
13
 
13
14
  # Title: Jekyll Picture Tag
14
15
  # Authors: Rob Wierzbowski : @robwierzbowski
@@ -18,9 +19,9 @@ require_relative 'jekyll_picture_tag/router'
18
19
  #
19
20
  # Description: Easy responsive images for Jekyll.
20
21
  #
21
- # Download: https://github.com/rbuchberger/jekyll_picture_tag
22
- # Documentation: https://github.com/rbuchberger/jekyll_picture_tag/readme.md
23
- # Issues: https://github.com/rbuchberger/jekyll_picture_tag/issues
22
+ # Download: https://rubygems.org/gems/jekyll_picture_tag
23
+ # Documentation: https://rbuchberger.github.io/jekyll_picture_tag/
24
+ # Issues: https://github.com/rbuchberger/jekyll_picture_tag/
24
25
  #
25
26
  # Syntax:
26
27
  # {% picture [preset] img.jpg [media_query: alt-img.jpg] [attributes] %}
@@ -39,30 +40,47 @@ require_relative 'jekyll_picture_tag/router'
39
40
  #
40
41
  # See the documentation for full configuration and usage instructions.
41
42
  module PictureTag
43
+ # The router module is important. If you're looking for the actual code which
44
+ # handles a `PictureTag.(some method)`, start there.
42
45
  extend Router
46
+
43
47
  ROOT_PATH = __dir__
44
48
 
45
49
  # This is the actual liquid tag, which provides the interface with Jekyll.
46
50
  class Picture < Liquid::Tag
51
+ # First jekyll initializes our class with a few arguments, of which we only
52
+ # care about the params (arguments passed to the liquid tag). Jekyll makes
53
+ # no attempt to parse them; they're given as a string.
47
54
  def initialize(tag_name, raw_params, tokens)
48
55
  @raw_params = raw_params
49
56
  super
50
57
  end
51
58
 
59
+ # Then jekyll calls the 'render' method and passes it a mostly undocumented
60
+ # context object, which appears to hold the entire site including its
61
+ # configuration and the parsed _data dir.
52
62
  def render(context)
53
- # Jekyll passes in a mostly undocumented context object, which appears to
54
- # hold the entire site, including configuration and the _data dir.
63
+ setup(context)
64
+
65
+ if PictureTag.disabled?
66
+ ''
67
+ else
68
+ PictureTag.output_class.new.to_s
69
+ end
70
+ end
71
+
72
+ private
73
+
74
+ def setup(context)
55
75
  PictureTag.context = context
56
76
 
57
- # The instruction set depends on both the context and the tag parameters:
77
+ # Now that we have both the tag parameters and the context object, we can
78
+ # build our instruction set.
58
79
  PictureTag.instructions = Instructions::Set.new(@raw_params)
59
80
 
60
81
  # We need to explicitly prevent jekyll from overwriting our generated
61
- # files:
82
+ # image files:
62
83
  Utils.keep_files
63
-
64
- # Return a string:
65
- PictureTag.output_class.new.to_s
66
84
  end
67
85
  end
68
86
  end
@@ -0,0 +1,3 @@
1
+ require_relative 'cache/base'
2
+ require_relative 'cache/source'
3
+ require_relative 'cache/generated'
@@ -0,0 +1,59 @@
1
+ require 'json'
2
+
3
+ module PictureTag
4
+ module Cache
5
+ # Basic image information cache functionality
6
+ module Base
7
+ def initialize(base_name)
8
+ @base_name = base_name
9
+ end
10
+
11
+ def [](key)
12
+ data[key]
13
+ end
14
+
15
+ def []=(key, value)
16
+ raise ArgumentError unless template.keys.include? key
17
+
18
+ data[key] = value
19
+ end
20
+
21
+ # Call after updating data.
22
+ def write
23
+ FileUtils.mkdir_p(File.join(base_directory, sub_directory))
24
+
25
+ File.open(filename, 'w+') do |f|
26
+ f.write JSON.generate(data)
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def data
33
+ @data ||= if File.exist?(filename)
34
+ JSON.parse(File.read(filename)).transform_keys(&:to_sym)
35
+ else
36
+ template
37
+ end
38
+ end
39
+
40
+ # /home/dave/my_blog/.jekyll-cache/jpt/(cache_dir)/assets/myimage.jpg.json
41
+ # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
42
+ def base_directory
43
+ File.join(PictureTag.site.cache_dir, 'jpt', cache_dir)
44
+ end
45
+
46
+ # /home/dave/my_blog/.jekyll-cache/jpt/(cache_dir)/assets/myimage.jpg.json
47
+ # ^^^^^^^^
48
+ def sub_directory
49
+ File.dirname(@base_name)
50
+ end
51
+
52
+ # /home/dave/my_blog/.jekyll-cache/jpt/somefolder/myimage.jpg.json
53
+ # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
54
+ def filename
55
+ File.join(base_directory, @base_name + '.json')
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,20 @@
1
+ module PictureTag
2
+ module Cache
3
+ # Caches generated image details, so we can skip expensive operations whenever
4
+ # possible.
5
+ # Stored width and height are values for the source image, after cropping.
6
+ class Generated
7
+ include Base
8
+
9
+ private
10
+
11
+ def cache_dir
12
+ 'generated'
13
+ end
14
+
15
+ def template
16
+ { width: nil, height: nil }
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,19 @@
1
+ module PictureTag
2
+ module Cache
3
+ # Caches source image details, so we can skip expensive operations whenever
4
+ # possible.
5
+ class Source
6
+ include Base
7
+
8
+ private
9
+
10
+ def template
11
+ { digest: nil, width: nil, height: nil }
12
+ end
13
+
14
+ def cache_dir
15
+ 'source'
16
+ end
17
+ end
18
+ end
19
+ end
@@ -7,3 +7,5 @@ picture:
7
7
  cdn_environments: ['production']
8
8
  nomarkdown: true
9
9
  ignore_missing_images: false
10
+ disabled: false
11
+ fast_build: false
@@ -7,3 +7,5 @@ noscript: false
7
7
  link_source: false
8
8
  quality: 75
9
9
  data_sizes: true
10
+ gravity: center
11
+ dimension_attributes: false
@@ -1,47 +1,104 @@
1
1
  require 'mini_magick'
2
2
 
3
3
  module PictureTag
4
- # Generated Image
5
- # Represents a generated source file.
4
+ # Represents a generated image file.
6
5
  class GeneratedImage
7
6
  attr_reader :width, :format
7
+
8
8
  include MiniMagick
9
9
 
10
- def initialize(source_file:, width:, format:)
10
+ def initialize(source_file:, width:, format:, crop: nil, gravity: '')
11
11
  @source = source_file
12
12
  @width = width
13
13
  @format = process_format format
14
+ @crop = crop
15
+ @gravity = gravity
16
+ end
14
17
 
15
- generate_image unless File.exist?(absolute_filename) || @source.missing
18
+ def exists?
19
+ File.exist?(absolute_filename)
16
20
  end
17
21
 
18
- def name
19
- "#{@source.base_name}-#{@width}-#{@source.digest}.#{@format}"
22
+ def generate
23
+ generate_image unless @source.missing || exists?
20
24
  end
21
25
 
26
+ # /home/dave/my_blog/_site/generated/somefolder/myimage-100-123abc.jpg
27
+ # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
22
28
  def absolute_filename
23
29
  @absolute_filename ||= File.join(PictureTag.dest_dir, name)
24
30
  end
25
31
 
32
+ # /home/dave/my_blog/_site/generated/somefolder/myimage-100-123abc.jpg
33
+ # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
34
+ def name
35
+ @name ||= "#{@source.base_name}-#{@width}-#{id}.#{@format}"
36
+ end
37
+
38
+ # https://example.com/assets/images/myimage-100-123abc.jpg
39
+ # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
26
40
  def uri
27
41
  ImgURI.new(name).to_s
28
42
  end
29
43
 
44
+ # Post crop
45
+ def source_width
46
+ update_cache unless cache[:width]
47
+
48
+ cache[:width]
49
+ end
50
+
51
+ # Post crop
52
+ def source_height
53
+ update_cache unless cache[:height]
54
+
55
+ cache[:height]
56
+ end
57
+
30
58
  private
31
59
 
60
+ # We exclude width and format from the cache name, since it isn't specific to them.
61
+ def cache
62
+ @cache ||= Cache::Generated.new("#{@source.base_name}-#{id}")
63
+ end
64
+
65
+ def update_cache
66
+ return if @source.missing
67
+
68
+ # Ensure it's generated:
69
+ image
70
+
71
+ cache[:width] = @source_dimensions[:width]
72
+ cache[:height] = @source_dimensions[:height]
73
+
74
+ cache.write
75
+ end
76
+
77
+ # Hash all inputs and truncate, so we know when they change without getting too long.
78
+ # /home/dave/my_blog/_site/generated/somefolder/myimage-100-1234abcde.jpg
79
+ # ^^^^^^^^^
80
+ def id
81
+ @id ||= Digest::MD5.hexdigest([@source.digest, @crop, @gravity, quality].join)[0..8]
82
+ end
83
+
84
+ # Post crop, before resizing and reformatting
32
85
  def image
33
- @image ||= Image.open(@source.name)
86
+ @image ||= open_image
34
87
  end
35
88
 
36
- def process_image
37
- image.combine_options do |i|
38
- i.resize "#{@width}x"
89
+ def open_image
90
+ image_base = Image.open(@source.name)
91
+ image_base.combine_options do |i|
39
92
  i.auto_orient
40
- i.strip
93
+ if @crop
94
+ i.gravity @gravity
95
+ i.crop @crop
96
+ end
41
97
  end
42
98
 
43
- image.format @format
44
- image.quality PictureTag.quality(@format)
99
+ @source_dimensions = { width: image_base.width, height: image_base.height }
100
+
101
+ image_base
45
102
  end
46
103
 
47
104
  def generate_image
@@ -50,20 +107,28 @@ module PictureTag
50
107
  write_image
51
108
  end
52
109
 
110
+ def quality
111
+ PictureTag.quality(@format)
112
+ end
113
+
114
+ def process_image
115
+ image.combine_options do |i|
116
+ i.resize "#{@width}x"
117
+ i.strip
118
+ end
119
+
120
+ image.format @format
121
+ image.quality quality
122
+ end
123
+
53
124
  def write_image
54
- check_dest_dir
125
+ FileUtils.mkdir_p(File.dirname(absolute_filename))
55
126
 
56
127
  image.write absolute_filename
57
128
 
58
129
  FileUtils.chmod(0o644, absolute_filename)
59
130
  end
60
131
 
61
- # Make sure destination directory exists
62
- def check_dest_dir
63
- dir = File.dirname absolute_filename
64
- FileUtils.mkdir_p(dir) unless Dir.exist?(dir)
65
- end
66
-
67
132
  def process_format(format)
68
133
  if format.casecmp('original').zero?
69
134
  @source.ext