19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
# File 'lib/rawfeed/build/image_minifier.rb', line 19
def self.minify_images
begin
require "mini_magick"
rescue LoadError
end
begin
system("identify -version > /dev/null 2>&1")
unless $?.success?
raise "ImageMagick not found"
end
rescue => e
puts "[!] Error: ImageMagick is not installed or not found in PATH".red
puts "".red
if RUBY_PLATFORM.include?("linux")
if File.exist?("/etc/arch-release")
puts " Arch Linux: sudo pacman -S imagemagick".yellow
else
puts " Ubuntu/Debian: sudo apt-get install imagemagick".yellow
end
elsif RUBY_PLATFORM.include?("darwin")
puts " macOS: brew install imagemagick".yellow
elsif RUBY_PLATFORM.include?("mingw") || RUBY_PLATFORM.include?("mswin")
puts " Windows: https://imagemagick.org/script/download.php".yellow
else
puts " See: https://imagemagick.org/script/download.php".yellow
end
exit 1
end
puts "Minifying images...".yellow
image_files = Dir.glob("#{BUILD_DIR}/assets/images/**/*.{jpg,jpeg,png}", File::FNM_CASEFOLD)
if image_files.empty?
puts "No images found."
return
end
puts "Found #{image_files.length} images\n".cyan
total_before = 0
total_after = 0
successful = 0
failed = 0
image_files.each do |file|
begin
before_size = File.size(file)
total_before += before_size
dir = File.dirname(file)
basename = File.basename(file, File.extname(file))
converter = system("magick --version > /dev/null 2>&1") ? "magick convert" : "convert"
temp_jpeg = "#{file}.temp.jpg"
cmd_jpeg = "#{converter} #{shell_escape(file)} -quality #{QUALITY_JPEG} -strip #{shell_escape(temp_jpeg)} 2>/dev/null"
system(cmd_jpeg)
if File.exist?(temp_jpeg) && File.size(temp_jpeg) > 0
FileUtils.mv(temp_jpeg, file)
jpeg_size = File.size(file)
total_after += jpeg_size
successful += 1
webp_path = File.join(dir, "#{basename}.webp")
cmd_webp = "#{converter} #{shell_escape(file)} -quality #{QUALITY_WEBP} #{shell_escape(webp_path)} 2>/dev/null"
system(cmd_webp)
avif_path = File.join(dir, "#{basename}.avif")
cmd_avif = "#{converter} #{shell_escape(file)} -quality #{QUALITY_AVIF} #{shell_escape(avif_path)} 2>/dev/null"
system(cmd_avif)
human_before = format_bytes(before_size)
human_after = format_bytes(jpeg_size)
puts " #{green_checkmark} #{file} #{neutral("(#{human_before} → #{human_after})")}"
else
failed += 1
FileUtils.rm(temp_jpeg) if File.exist?(temp_jpeg)
puts " #{red_x} #{file} #{red("(Failed to convert)")}"
end
rescue => e
failed += 1
puts " #{red_x} #{file} #{red("(#{e.message}")}\n"
end
end
if successful > 0
saved = total_before - total_after
human_before = format_bytes(total_before)
human_after = format_bytes(total_after)
human_saved = format_bytes(saved)
puts ""
puts "Images optimized: #{human_before} → #{human_after} (saved #{human_saved})".bold.green
puts " Successful: #{successful}, Failed: #{failed}".cyan if failed > 0
puts ""
elsif failed > 0
puts ""
puts "No images were processed (#{failed} failed)".red
puts ""
end
end
|