imagetools 1.3.1 → 1.5.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b165e7e85d7d0854577ab7a1f452ff4b3df9d87ea82890dcdda5f0550f969046
4
- data.tar.gz: e38ddf3c06d47997399fada92f2130460cfadb5558bb0f460b555e07684cb3cb
3
+ metadata.gz: f1abcb0bf228739f0993edc336151eec2bdbdbc2bfc8a46d6c1b5ce47e5d5836
4
+ data.tar.gz: c03694b434386645be24daeb97ee5b12ae03588401afc1b3d207ddd44e9dd3ba
5
5
  SHA512:
6
- metadata.gz: f16f40fdcb563715da0064a6c5a2ef9bd61ff2469f70d7e25760156b081ef950b8c5ea3608bcf773e96ba59b91314216ff7b995bfd94b6c784b10d3a2d61c9a0
7
- data.tar.gz: bea91193b72e52fda2954c19939dbf92ae479bec2a3029c6d4156f2d19714b01e343301ce8f205a1c27d9ece7a95b538f700379dc37cedc48c9b353fba1fda26
6
+ metadata.gz: 15ac47a208ab77856ea2382ea5792ff67f02382f7402a111c439ea6b36290d5bcba24e77e51c5fd03eac7f42aa0ccab2da499054f10ba9fed2fe10892e8a5604
7
+ data.tar.gz: 6aae7f1b2acdf083467c39db9fd69f35e44326853cac81670077fd235246f75b06ae49637fcd50cf3013eacb53e751a750cd5a1e222fa754a842620a734a21cf
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.7.5
1
+ 3.0.2
data/Gemfile.lock CHANGED
@@ -1,15 +1,15 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- imagetools (1.3.1)
5
- rmagick (= 3.2.0)
4
+ imagetools (1.5.1)
5
+ rmagick
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
- minitest (5.14.4)
10
+ minitest (5.15.0)
11
11
  rake (13.0.6)
12
- rmagick (3.2.0)
12
+ rmagick (4.2.4)
13
13
 
14
14
  PLATFORMS
15
15
  ruby
@@ -21,4 +21,4 @@ DEPENDENCIES
21
21
  rake (~> 13.0)
22
22
 
23
23
  BUNDLED WITH
24
- 2.1.4
24
+ 2.3.8
data/exe/imageblog ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'imagetools/imageblog'
4
+
5
+ Imagetools::Imageblog.run(ARGV)
data/imagetools.gemspec CHANGED
@@ -29,7 +29,7 @@ Gem::Specification.new do |spec|
29
29
  spec.bindir = "exe"
30
30
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
31
31
  spec.require_paths = ["lib"]
32
- spec.add_dependency "rmagick", "3.2.0"
32
+ spec.add_dependency "rmagick"
33
33
  spec.add_development_dependency "bundler", "~> 2.0"
34
34
  spec.add_development_dependency "rake", "~> 13.0"
35
35
  spec.add_development_dependency "minitest", "~> 5.0"
@@ -0,0 +1,148 @@
1
+ # coding: utf-8
2
+ # imagehugo: hugo用の画像処理。リネームとサムネイル&アイキャッチ画像の生成。
3
+
4
+ require 'imagetools/version'
5
+ require 'imagetools/imagefilter'
6
+ require 'rmagick'
7
+ require 'optparse'
8
+ require 'fileutils'
9
+
10
+ module Imagetools
11
+ class ImageItem
12
+ attr_accessor :srcfile, :dstfile, :outfile
13
+ def to_s
14
+ "#{srcfile}=>#{dstfile}=>#{outfile}"
15
+ end
16
+ end
17
+
18
+ class Imageblog
19
+ def self.run(argv)
20
+ STDOUT.sync = true
21
+ opts = {}
22
+ opt = OptionParser.new(argv)
23
+ opt.version = VERSION
24
+ opt.banner = "Usage: #{opt.program_name} [-h|--help] <dir> or <image1 image2 image3 ...>"
25
+ opt.separator('')
26
+ opt.separator("Examples:")
27
+ opt.separator(" #{opt.program_name} ~/tmp # concat two recent IMG_*jpg images.")
28
+ opt.separator(" #{opt.program_name} image1.jpg image2.jpg image3.jpg # concat specified images.")
29
+ opt.separator('')
30
+ opt.separator("Options:")
31
+ opt.on_head('-h', '--help', 'Show this message') do |v|
32
+ puts opt.help
33
+ exit
34
+ end
35
+ opt.on('-v', '--verbose', 'Verbose message') {|v| opts[:v] = v}
36
+ opt.on('--dry-run', 'Message only') {|v| opts[:dry_run] = v}
37
+ opt.on('-o OUTDIR', '--output=OUTDIR', 'Output dir') {|v| opts[:o] = v}
38
+ opt.on('-n NUM', '--number=NUM', 'Process image number') {|v| opts[:n] = v.to_i}
39
+ opt.on('-b BASENAME', '--base=BASENAME', 'Output file basename') {|v| opts[:b] = v}
40
+ opt.parse!(argv)
41
+ opts[:b] ||= Time.now.strftime("%Y%m%d")
42
+ dir, image_files = get_image_files(opts, argv)
43
+ if image_files.size == 0
44
+ puts opt.help
45
+ exit
46
+ end
47
+ command = Imageblog.new(opts)
48
+ command.run(dir, image_files)
49
+ end
50
+
51
+ def self.get_image_files(opts, argv)
52
+ image_files = []
53
+ # ディレクトリが処理対象かどうかを決める
54
+ dir = nil
55
+ if argv.size == 1
56
+ # 引き数が1個の場合は最初の引き数
57
+ path = File.expand_path(argv[0])
58
+ if FileTest.directory?(path)
59
+ dir = path
60
+ end
61
+ elsif argv.size == 0
62
+ # 引き数がない場合カレントディレクトリ
63
+ dir = File.expand_path('.')
64
+ end
65
+ if dir
66
+ concat_number = opts[:n] || 2
67
+ # ディレクトリが指定されていた場合、指定ディレクトリ内のIMG_ファイルの最新n個を対象とする
68
+ # 最新の基準は(ファイル名基準)
69
+ match_files = Dir.glob("#{dir}/*.{jpg,jpeg,png}", File::FNM_CASEFOLD).sort
70
+ # match_files.sort {|a, b|
71
+ # File.mtime(a) <=> File.mtime(b)
72
+ # }
73
+ # 後ろからn個を取得(小さい方の数とする)
74
+ count = [match_files.size, concat_number].min
75
+ image_files = match_files[-count..-1]
76
+ else
77
+ # それ以外は指定された引き数を全て対象とする
78
+ argv.each do |arg|
79
+ arg = File.expand_path(arg)
80
+ dir = File.dirname(arg)
81
+ if FileTest.file?(arg) && (arg =~ /\.jpe?g$/i || arg =~ /\.png/i)
82
+ image_files << arg
83
+ end
84
+ end
85
+ end
86
+ return dir, image_files
87
+ end
88
+
89
+ def initialize(opts)
90
+ @opts = opts
91
+ end
92
+
93
+
94
+ def run(dir, image_files)
95
+ outdir = dir
96
+ if @opts[:o]
97
+ outdir = @opts[:o]
98
+ end
99
+ rename_images(image_files, outdir)
100
+ # concat_images(image_files, output_path)
101
+ end
102
+
103
+ private
104
+ def rename_images(image_files, outdir)
105
+ # サムネイルはhoge_0.jpg
106
+ # アイキャッチはhoge_1.jpg hoge_2.jpg以降が通常の画像
107
+ items = []
108
+ thumbnal_item = nil # hoge_0.jpgとする
109
+ image_files.each_with_index do |image_file, index|
110
+ item = ImageItem.new
111
+ item.srcfile = image_file
112
+
113
+ src_basename = File.basename(image_file)
114
+ extname = File.extname(src_basename)
115
+ dst_basename = @opts[:b]
116
+
117
+ item.dstfile = File.join(outdir, "#{dst_basename}_#{index + 1}#{extname}")
118
+ if index == 0
119
+ thumbnal_item = ImageItem.new
120
+ thumbnal_item.srcfile = image_file
121
+ thumbnal_item.dstfile = File.join(outdir, "#{dst_basename}_0#{extname}")
122
+ end
123
+ items << item
124
+ end
125
+ items.each do |item|
126
+ FileUtils.cp(item.srcfile, item.dstfile)
127
+ end
128
+ FileUtils.cp(thumbnal_item.srcfile, thumbnal_item.dstfile)
129
+
130
+ #フィルタ実行
131
+ config = Config.new
132
+ config.init_default
133
+ opts = {}
134
+ filter = Imagefilter.new(opts, config)
135
+ items.each do |item|
136
+ item.outfile = filter.run(item.dstfile)
137
+ end
138
+
139
+
140
+ # サムネイル
141
+ config.resize_width = 400
142
+ filter = Imagefilter.new(opts, config)
143
+ thumbnal_item.outfile = filter.run(thumbnal_item.dstfile)
144
+
145
+ end
146
+ end
147
+ end
148
+
@@ -26,7 +26,7 @@ module Imagetools
26
26
  opt.on('-v', '--verbose', 'Verbose message') {|v| opts[:v] = v}
27
27
  opt.on('--dry-run', 'Message only') {|v| opts[:dry_run] = v}
28
28
  opt.on('-o OUTNAME', '--output=OUTNAME', 'Output file') {|v| opts[:o] = v}
29
- opt.on('-n NUM', '--number=NUM', 'Cancat image Number') {|v| opts[:n] = v.to_i}
29
+ opt.on('-n NUM', '--number=NUM', 'Concat image number') {|v| opts[:n] = v.to_i}
30
30
  opt.parse!(argv)
31
31
  image_files = get_image_files(opts, argv)
32
32
  if image_files.size < 2
@@ -89,14 +89,20 @@ module Imagetools
89
89
  def concat_images(image_files, output_file)
90
90
  puts image_files.join("+") + "=#{output_file}"
91
91
 
92
+ # 結果の画像リスト
92
93
  result_image_list = Magick::ImageList.new
94
+
93
95
  image_files.each do |image_file|
94
- #background_colorとflatten_imagesを組み合わせて背景色を指定
96
+ # 個別画像の背景色を白に変換
97
+ # 一気に行く方法がないので、ImageListを作成しbackground_colorとflatten_imagesを組み合わる。
95
98
  image_list = Magick::ImageList.new(image_file) {self.background_color = 'white'}
96
99
  image = image_list.flatten_images
100
+
101
+ # 結果の画像リストに追加
97
102
  result_image_list << image
98
103
  end
99
-
104
+
105
+ #append(false)で横方向に結合
100
106
  result = result_image_list.append(false)
101
107
 
102
108
  width = result.columns
@@ -9,20 +9,45 @@ module Imagetools
9
9
  class Config
10
10
  FILENAME_SEARCH = 's (\d+)-(\d+)-(\d+) (\d+)\.(\d+)\.(\d+)'
11
11
  FILENAME_REPLACE = 's_\1\2\3_\4\5\6'
12
+ RESIZE_WIDTH = 1280
13
+
14
+ def self.create_from_yaml(yaml)
15
+ config = Config.new
16
+ config.filename_search1 = config_value(yaml, "filename", "search1", false)
17
+ config.filename_replace1 = config_value(yaml, "filename", "replace1", false)
18
+ config.filename_search2 = config_value(yaml, "filename", "search2", false)
19
+ config.filename_replace2 = config_value(yaml, "filename", "replace2", false)
20
+ config.filename_search3 = config_value(yaml, "filename", "search3", false)
21
+ config.filename_replace3 = config_value(yaml, "filename", "replace3", false)
22
+ config.resize_width = config_value(yaml, "resize", "width", false)
23
+ config.init_default
24
+ config
25
+ end
26
+
27
+
28
+ def self.config_value(yaml, section, key, require)
29
+ return nil unless yaml
30
+ return nil unless yaml[section]
31
+ value = yaml[section][key]
32
+ if require && (value.nil? || value.empty?)
33
+ raise RuntimeError, "#{section}:#{key}: is empty"
34
+ end
35
+ value
36
+ end
12
37
 
13
- def initialize(yaml)
14
- @yaml = yaml
15
- @filename_search1 = config_value("filename", "search1", false) || FILENAME_SEARCH
16
- @filename_replace1 = config_value("filename", "replace1", false) || FILENAME_REPLACE
17
- @filename_search2 = config_value("filename", "search2", false)
18
- @filename_replace2 = config_value("filename", "replace2", false)
19
- @filename_search3 = config_value("filename", "search3", false)
20
- @filename_replace3 = config_value("filename", "replace3", false)
38
+ def initialize
21
39
  end
22
40
 
23
- attr_reader :filename_search1, :filename_replace1,
24
- :filename_search2, :filename_replace2,
25
- :filename_search3, :filename_replace3
41
+ def init_default
42
+ @filename_search1 ||= FILENAME_SEARCH
43
+ @filename_replace1 ||= FILENAME_REPLACE
44
+ @resize_width ||= RESIZE_WIDTH
45
+ end
46
+
47
+ attr_accessor :filename_search1, :filename_replace1,
48
+ :filename_search2, :filename_replace2,
49
+ :filename_search3, :filename_replace3
50
+ attr_accessor :resize_width
26
51
 
27
52
  def filename_patterns
28
53
  [
@@ -31,16 +56,6 @@ module Imagetools
31
56
  [@filename_search3, @filename_replace3],
32
57
  ]
33
58
  end
34
-
35
- private
36
- def config_value(section, key, require)
37
- return nil unless @yaml
38
- value = @yaml[section][key]
39
- if require && (value.nil? || value.empty?)
40
- raise RuntimeError, "#{section}:#{key}: is empty"
41
- end
42
- value
43
- end
44
59
  end
45
60
 
46
61
  class Imagefilter
@@ -49,8 +64,7 @@ module Imagetools
49
64
 
50
65
  CONVERT_CMD = "convert"
51
66
  DWEBP_CMD = "dwebp"
52
- # RESIZE_CMD = "mogrify -resize 1280x\\> "
53
- RESIZE_CMD = "mogrify -background white -resize 1280x\\> "
67
+ RESIZE_CMD = "mogrify -background white -resize %dx\\> "
54
68
  ROTATE_CMD = "exiftran -ai "
55
69
  COMPRESS_CMD = "jpegoptim --strip-all --max=90 "
56
70
  EXTERNAL_CMDS = [RESIZE_CMD, ROTATE_CMD, COMPRESS_CMD]
@@ -61,6 +75,9 @@ module Imagetools
61
75
  PNG_SEARCH = /(.+)\.png/i
62
76
  PNG_REPLACE = '\1.jpg'
63
77
  JPG_SEARCH = /(.+)\.jpe?g/i
78
+ HEIC_SEARCH = /(.+)\.heic/i
79
+ HEIC_REPLACE = '\1.jpg'
80
+
64
81
  EXCLUDE_PAT = /^_/ # 先頭が"_"の場合は除外
65
82
 
66
83
  def self.run(argv)
@@ -96,7 +113,7 @@ EOM
96
113
  if FileTest.file?(config_file)
97
114
  yaml = YAML.load_file(config_file)
98
115
  end
99
- config = Config.new(yaml)
116
+ config = Config.create_from_yaml(yaml)
100
117
  if opts[:t]
101
118
  ret = selftest
102
119
  exit(ret)
@@ -142,6 +159,10 @@ EOM
142
159
  filename.sub(PNG_SEARCH, PNG_REPLACE)
143
160
  end
144
161
 
162
+ def self.replace_heic2jpg(filename)
163
+ filename.sub(HEIC_SEARCH, HEIC_REPLACE)
164
+ end
165
+
145
166
  def self.match_exclude_image?(filename)
146
167
  filename =~ EXCLUDE_PAT
147
168
  end
@@ -172,10 +193,10 @@ EOM
172
193
  if exclude_image?(filepath)
173
194
  return
174
195
  end
175
-
176
196
  filepath = rename_image(filepath)
177
197
  filepath = webp2png(filepath)
178
198
  filepath = png2jpg(filepath)
199
+ filepath = heic2jpg(filepath)
179
200
  filepath = resize_jpg(filepath)
180
201
  filepath = rotate_jpg(filepath)
181
202
  filepath = compress_jpg(filepath)
@@ -239,13 +260,31 @@ EOM
239
260
  return topath
240
261
  end
241
262
 
263
+ def heic2jpg(filepath)
264
+ fromname = File.basename(filepath)
265
+ toname = self.class.replace_heic2jpg(fromname)
266
+ # puts "heic2jpg #{fromname}=>#{toname}"
267
+ return filepath if fromname == toname
268
+
269
+ dir = File.dirname(filepath)
270
+ topath = File.join(dir, toname)
271
+ puts "convert: #{filepath} => #{topath}"
272
+ # convert ~/Desktop/test.heic -o ~/Desktop/test.jpg
273
+ cmd = "#{CONVERT_CMD} \"#{filepath}\" \"#{topath}\""
274
+ if system(cmd)
275
+ FileUtils.rm(filepath)
276
+ end
277
+ return topath
278
+ end
279
+
242
280
  def resize_jpg(filepath)
243
281
  fromname = File.basename(filepath)
244
282
  unless fromname =~ JPG_SEARCH
245
283
  return filepath
246
284
  end
247
285
  puts "resize: #{filepath}"
248
- cmd = "#{RESIZE_CMD} \"#{filepath}\""
286
+ resize_cmd = sprintf(RESIZE_CMD, @config.resize_width)
287
+ cmd = "#{resize_cmd} \"#{filepath}\""
249
288
  system(cmd)
250
289
  return filepath
251
290
  end
@@ -1,3 +1,3 @@
1
1
  module Imagetools
2
- VERSION = "1.3.1"
2
+ VERSION = "1.5.1"
3
3
  end
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
data/test_imageblog.sh ADDED
@@ -0,0 +1,2 @@
1
+ #!/bin/sh
2
+ bundle exec ruby exe/imageblog "$@"
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: imagetools
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.1
4
+ version: 1.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - src
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-12-10 00:00:00.000000000 Z
11
+ date: 2022-03-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rmagick
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 3.2.0
19
+ version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 3.2.0
26
+ version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -72,6 +72,7 @@ email:
72
72
  executables:
73
73
  - iconcreator
74
74
  - iconextractor
75
+ - imageblog
75
76
  - imageburst
76
77
  - imageconcat
77
78
  - imagefilter
@@ -102,6 +103,7 @@ files:
102
103
  - build.sh
103
104
  - exe/iconcreator
104
105
  - exe/iconextractor
106
+ - exe/imageblog
105
107
  - exe/imageburst
106
108
  - exe/imageconcat
107
109
  - exe/imagefilter
@@ -113,6 +115,7 @@ files:
113
115
  - lib/imagetools.rb
114
116
  - lib/imagetools/iconcreator.rb
115
117
  - lib/imagetools/iconextractor.rb
118
+ - lib/imagetools/imageblog.rb
116
119
  - lib/imagetools/imageburst.rb
117
120
  - lib/imagetools/imageconcat.rb
118
121
  - lib/imagetools/imagefilter.rb
@@ -142,12 +145,19 @@ files:
142
145
  - sample/demo/demo/Base.lproj/Main.storyboard
143
146
  - sample/demo/demo/Info.plist
144
147
  - sample/demo/demo/ViewController.swift
148
+ - sample/hugo_dst/1200x400.png
149
+ - sample/hugo_dst/1200x800.png
150
+ - sample/hugo_dst/600x200.png
151
+ - sample/hugo_src/0000.png
152
+ - sample/hugo_src/0001.png
153
+ - sample/hugo_src/0002.png
145
154
  - sample/icon.png
146
155
  - sample/icon.sketch
147
156
  - sample_iconcreator.sh
148
157
  - test.sh
149
158
  - test_iconcreator.sh
150
159
  - test_iconextractor.sh
160
+ - test_imageblog.sh
151
161
  - test_imageburst.sh
152
162
  - test_imageconcat.sh
153
163
  - test_imagefilter.sh
@@ -156,7 +166,7 @@ homepage: ''
156
166
  licenses:
157
167
  - MIT
158
168
  metadata: {}
159
- post_install_message:
169
+ post_install_message:
160
170
  rdoc_options: []
161
171
  require_paths:
162
172
  - lib
@@ -171,8 +181,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
171
181
  - !ruby/object:Gem::Version
172
182
  version: '0'
173
183
  requirements: []
174
- rubygems_version: 3.1.6
175
- signing_key:
184
+ rubygems_version: 3.2.22
185
+ signing_key:
176
186
  specification_version: 4
177
187
  summary: Image Tools.
178
188
  test_files: []