Class: Jekyll::Images::Thumbnail

Inherits:
Object
  • Object
show all
Defined in:
lib/jekyll/images/thumbnail.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(site:, filename:, image:, **args) ⇒ Thumbnail

Returns a new instance of Thumbnail.



10
11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/jekyll/images/thumbnail.rb', line 10

def initialize(site:, filename:, image:, **args)
  if args.slice(:width, :height).values.none?
    raise ArgumentError, "#{filename} thumbnail needs width or height"
  end

  @site = site
  @filename = filename
  @image = image
  @width = args[:width] || proportional_width(args[:height])
  @height = args[:height] || proportional_height(args[:width])
  @crop = args[:crop]&.to_sym || :attention
  @auto_rotate = args[:auto_rotate].nil? ? true : args[:auto_rotate]
end

Instance Attribute Details

#auto_rotateObject (readonly)

Returns the value of attribute auto_rotate.



8
9
10
# File 'lib/jekyll/images/thumbnail.rb', line 8

def auto_rotate
  @auto_rotate
end

#cropObject (readonly)

Returns the value of attribute crop.



8
9
10
# File 'lib/jekyll/images/thumbnail.rb', line 8

def crop
  @crop
end

#filenameObject (readonly)

Returns the value of attribute filename.



8
9
10
# File 'lib/jekyll/images/thumbnail.rb', line 8

def filename
  @filename
end

#heightObject (readonly)

Returns the value of attribute height.



8
9
10
# File 'lib/jekyll/images/thumbnail.rb', line 8

def height
  @height
end

#imageObject (readonly)

Returns the value of attribute image.



8
9
10
# File 'lib/jekyll/images/thumbnail.rb', line 8

def image
  @image
end

#siteObject (readonly)

Returns the value of attribute site.



8
9
10
# File 'lib/jekyll/images/thumbnail.rb', line 8

def site
  @site
end

#widthObject (readonly)

Returns the value of attribute width.



8
9
10
# File 'lib/jekyll/images/thumbnail.rb', line 8

def width
  @width
end

Instance Method Details

#destObject

Generates a destination from filename only if we’re downsizing



45
46
47
48
49
50
51
# File 'lib/jekyll/images/thumbnail.rb', line 45

def dest
  @dest ||= if thumbnail?
              filename.gsub(/#{extname}\z/, "_#{width}x#{height}#{extname}")
            else
              filename.gsub(/#{extname}\z/, "_optimized#{extname}")
            end
end

#extnameObject



61
62
63
# File 'lib/jekyll/images/thumbnail.rb', line 61

def extname
  @extname ||= File.extname filename
end

#interlaced?Boolean

Returns:

  • (Boolean)


110
111
112
# File 'lib/jekyll/images/thumbnail.rb', line 110

def interlaced?
  site.config.dig('images', 'interlaced')
end

#optimizeObject

Run optimizations



92
93
94
95
96
97
98
99
100
# File 'lib/jekyll/images/thumbnail.rb', line 92

def optimize
  before, after = Runner.run(dest, interlaced?)

  return unless before

  pct = ((after.to_f / before) * -100 + 100).round(2)

  Jekyll.logger.info "Reduced #{dest} from #{before} to #{after} bytes (%#{pct})"
end

#proportional_height(width) ⇒ Object

Finds a height that’s proportional to the width



35
36
37
# File 'lib/jekyll/images/thumbnail.rb', line 35

def proportional_height(width)
  @proportional_height ||= (image.height * (width / image.width.to_f)).round
end

#proportional_width(height) ⇒ Object

Find a width that’s proportional to height



40
41
42
# File 'lib/jekyll/images/thumbnail.rb', line 40

def proportional_width(height)
  @proportional_width ||= (image.width * (height / image.height.to_f)).round
end

#relative_pathObject



102
103
104
# File 'lib/jekyll/images/thumbnail.rb', line 102

def relative_path
  @relative_path ||= dest.sub(site.source, '').sub(%r{\A/}, '')
end

#static_fileObject



106
107
108
# File 'lib/jekyll/images/thumbnail.rb', line 106

def static_file
  @static_file ||= Jekyll::StaticFile.new(site, site.source, File.dirname(relative_path), File.basename(relative_path))
end

#thumbnailObject

XXX: We don’t memoize because we don’t need the thumbnail in memory after it has been written.



26
27
28
29
30
31
32
# File 'lib/jekyll/images/thumbnail.rb', line 26

def thumbnail
  Vips::Image.thumbnail filename,
                        width,
                        height: height,
                        auto_rotate: auto_rotate,
                        crop: crop
end

#thumbnail?Boolean

Returns:

  • (Boolean)


57
58
59
# File 'lib/jekyll/images/thumbnail.rb', line 57

def thumbnail?
  image.width > width
end

#urlObject



53
54
55
# File 'lib/jekyll/images/thumbnail.rb', line 53

def url
  static_file.url
end

#writeObject

Save the file into destination if needed and add to files to copy



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/jekyll/images/thumbnail.rb', line 72

def write
  return unless write?

  if thumbnail?
    Jekyll.logger.info "Thumbnailing #{filename} => #{dest}"
    thumbnail.write_to_file(dest)
  else
    Jekyll.logger.info "Copying #{filename} => #{dest}"
    FileUtils.cp(filename, dest)
  end

  # Add it to the static files so Jekyll copies them.  Once they
  # are written they're copied when the site is loaded.
  site.static_files << static_file

  # The file was updated, so it exists and is newer than source
  !write?
end

#write?Boolean

Only write when the source is newer than the thumbnail

Returns:

  • (Boolean)


66
67
68
# File 'lib/jekyll/images/thumbnail.rb', line 66

def write?
  !File.exist?(dest) || File.mtime(filename) > File.mtime(dest)
end