# coding: utf-8 require 'imagetools/version' require 'fileutils' require 'optparse' require 'yaml' module Imagetools class Config FILENAME_SEARCH = 's (\d+)-(\d+)-(\d+) (\d+)\.(\d+)\.(\d+)' FILENAME_REPLACE = 's_\1\2\3_\4\5\6' RESIZE_WIDTH = 1280 def self.create_from_yaml(yaml) config = Config.new config.filename_search1 = config_value(yaml, "filename", "search1", false) config.filename_replace1 = config_value(yaml, "filename", "replace1", false) config.filename_search2 = config_value(yaml, "filename", "search2", false) config.filename_replace2 = config_value(yaml, "filename", "replace2", false) config.filename_search3 = config_value(yaml, "filename", "search3", false) config.filename_replace3 = config_value(yaml, "filename", "replace3", false) config.resize_width = config_value(yaml, "resize", "width", false) config.init_default config end def self.config_value(yaml, section, key, require) return nil unless yaml return nil unless yaml[section] value = yaml[section][key] if require && (value.nil? || value.empty?) raise RuntimeError, "#{section}:#{key}: is empty" end value end def initialize end def init_default @filename_search1 ||= FILENAME_SEARCH @filename_replace1 ||= FILENAME_REPLACE @resize_width ||= RESIZE_WIDTH end attr_accessor :filename_search1, :filename_replace1, :filename_search2, :filename_replace2, :filename_search3, :filename_replace3 attr_accessor :resize_width def filename_patterns [ [@filename_search1, @filename_replace1], [@filename_search2, @filename_replace2], [@filename_search3, @filename_replace3], ] end end class Imagefilter OTHER_JPG_SEARCH = /\.(large|huge|jpg_large|JPG)$/i OTHER_JPG_REPLACE = '.jpg' CONVERT_CMD = "convert" DWEBP_CMD = "dwebp" RESIZE_CMD = "mogrify -background white -resize %dx\\> " ROTATE_CMD = "exiftran -ai " COMPRESS_CMD = "jpegoptim --strip-all --max=90 " EXTERNAL_CMDS = [CONVERT_CMD, RESIZE_CMD, ROTATE_CMD, COMPRESS_CMD, DWEBP_CMD] WEBP_SEARCH = /(.+)\.webp/i WEBP_REPLACE = '\1.png' PNG_SEARCH = /(.+)\.png/i PNG_REPLACE = '\1.jpg' JPG_SEARCH = /(.+)\.jpe?g/i HEIC_SEARCH = /(.+)\.heic/i HEIC_REPLACE = '\1.jpg' EXCLUDE_PAT = /^_/ # 先頭が"_"の場合は除外 def self.run(argv) STDOUT.sync = true opts = {} opt = OptionParser.new(argv) opt.banner = "Usage: #{opt.program_name} [-h|--help] " opt.version = VERSION opt.separator('') opt.separator('Parameters:') param =< #{topath}" # FileUtils.mv(filepath, topath, :force => true) unless @opts[:n] # aaa.JPG => aaa.jpgを成功させるためにFIleUtils.mv(same fileエラーがでる)ではなくmvを使う cmd = "mv \"#{filepath}\" \"#{topath}\"" system(cmd) return topath end def webp2png(filepath) fromname = File.basename(filepath) toname = self.class.replace_webp2png(fromname) return filepath if fromname == toname dir = File.dirname(filepath) topath = File.join(dir, toname) puts "convert: #{filepath} => #{topath}" # dwebp ~/Desktop/1.webp -o ~/Desktop/1.jpg cmd = "#{DWEBP_CMD} \"#{filepath}\" -o \"#{topath}\"" if system(cmd) FileUtils.rm(filepath) end return topath end def png2jpg(filepath) fromname = File.basename(filepath) toname = self.class.replace_png2jpg(fromname) return filepath if fromname == toname dir = File.dirname(filepath) topath = File.join(dir, toname) puts "convert: #{filepath} => #{topath}" # convert test.png -background "#ffff00" -flatten test.jpg cmd = "#{CONVERT_CMD} \"#{filepath}\" -background \"#ffffff\" -flatten \"#{topath}\"" if system(cmd) FileUtils.rm(filepath) end return topath end def heic2jpg(filepath) fromname = File.basename(filepath) toname = self.class.replace_heic2jpg(fromname) # puts "heic2jpg #{fromname}=>#{toname}" return filepath if fromname == toname dir = File.dirname(filepath) topath = File.join(dir, toname) puts "convert: #{filepath} => #{topath}" # convert ~/Desktop/test.heic -o ~/Desktop/test.jpg cmd = "#{CONVERT_CMD} \"#{filepath}\" \"#{topath}\"" if system(cmd) FileUtils.rm(filepath) end return topath end def resize_jpg(filepath) fromname = File.basename(filepath) unless fromname =~ JPG_SEARCH return filepath end puts "resize: #{filepath}" resize_cmd = sprintf(RESIZE_CMD, @config.resize_width) cmd = "#{resize_cmd} \"#{filepath}\"" system(cmd) return filepath end def rotate_jpg(filepath) fromname = File.basename(filepath) unless fromname =~ JPG_SEARCH return filepath end puts "rotate: #{filepath}" cmd = "#{ROTATE_CMD} \"#{filepath}\"" system(cmd) return filepath end def compress_jpg(filepath) fromname = File.basename(filepath) unless fromname =~ JPG_SEARCH return filepath end puts "compress: #{filepath}" cmd = "#{COMPRESS_CMD} \"#{filepath}\"" system(cmd) return filepath end end end