washi 0.1.0 → 0.1.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
  SHA1:
3
- metadata.gz: 9681b843b1c430cdffe28ceb433d4d10916d9dc8
4
- data.tar.gz: f429efcb2ae6dc415414f15088cf2d17cf3517f5
3
+ metadata.gz: a438f0fc570d286f3aa0e810ef7a09f36effcd67
4
+ data.tar.gz: 7e1a88bcbbbd0ba9e9c9f8076a287a33773559ff
5
5
  SHA512:
6
- metadata.gz: 6c10cbe413d45e8759c53bd6cd84cc9a82a491fdb10dc16a1d15c0f2dd3bf751f6393948d1fce89f3471a66e516c567da36f8b65f2569603ed85ba469229de27
7
- data.tar.gz: 7b224ba0620234943b6cffbfd62ea554b7ea0cea474f164239aa2950b012f1f8b21838e02c28ef9a4dddecbeee637e1b2c25e094e06cb7a60488ac6dcd394658
6
+ metadata.gz: a34e96479d6b6b75898d0bc968da6cefea0cb48a864bf023a28f8ed2632bdd13d9f67a7ff2c47876eb7b293df735e37dbd78af477582b062b4d1b2cb1d12096e
7
+ data.tar.gz: 69474be1aacde8a0111404c0744338aa8ab17a3df86aa87c2171e515c8990ba2e245d412efa572e3668a298077732053a9a85ab855a311105b3413470b8026f3
@@ -1,10 +1 @@
1
- module Washi
2
- class Tiler
3
- def self.call(input_path, output_path, options={})
4
- unless tile_size = options[:tile_size]
5
- fail "Need pass :tile_size"
6
- end
7
- `vips dzsave #{input_path} #{output_path} --tile-size #{tile_size} --overlap 0 --vips-progress --vips-leak`
8
- end
9
- end
10
- end
1
+ require 'washi/tiler'
@@ -0,0 +1,15 @@
1
+ module Washil
2
+ @@config = Class.new {
3
+ attr_accessor :overlap, :binapath, :options
4
+
5
+ def initialize
6
+ @overlap = 0
7
+ @binapath = 'vips dzsave'
8
+ @options = %w|--vips-progress --vips-leak|
9
+ end
10
+ }.new
11
+
12
+ def self.config
13
+ @@config
14
+ end
15
+ end
@@ -0,0 +1,28 @@
1
+ module DZT
2
+ class FileStorage
3
+ #
4
+ # @param destination: Full directory in which to output tiles, defaults to 'tiles' in the current dir.
5
+ #
6
+ def initialize(options = {})
7
+ @store_path = options[:destination] || File.join(Dir.pwd, 'tiles')
8
+ end
9
+
10
+ def exists?
11
+ File.directory?(@store_path) && !Dir['@{@store_path}/*'].empty?
12
+ end
13
+
14
+ def storage_location(level)
15
+ File.join(@store_path, level.to_s)
16
+ end
17
+
18
+ def mkdir(path)
19
+ FileUtils.mkdir_p(path)
20
+ end
21
+
22
+ def write(file, dest, options = {})
23
+ quality = options[:quality]
24
+ file.quality quality
25
+ file.write(dest)
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,61 @@
1
+ module DZT
2
+ class S3Storage
3
+ DEFAULT_ACL = 'public-read'
4
+ DEFAULT_KEY = ''
5
+ #
6
+ # @param s3_acl: ACL to use for storing, defaults to 'public-read'.
7
+ # @param s3_bucket: Bucket to store tiles.
8
+ # @param s3_key: Key to prefix stored files.
9
+ # @param aws_id: AWS Id.
10
+ # @param aws_secret: AWS Secret.
11
+ #
12
+ def initialize(options = {})
13
+ @s3_acl = options[:s3_acl] || DEFAULT_ACL
14
+ @s3_bucket = options[:s3_bucket]
15
+ @s3_key = options[:s3_key] || DEFAULT_KEY
16
+ @s3_id = options[:aws_id]
17
+ @s3_secret = options[:aws_secret]
18
+ end
19
+
20
+ def s3
21
+ @s3 ||= begin
22
+ require_fog!
23
+ Fog::Storage.new(
24
+ provider: 'AWS',
25
+ aws_access_key_id: @s3_id,
26
+ aws_secret_access_key: @s3_secret
27
+ )
28
+ end
29
+ end
30
+
31
+ # Currently does not supporting checking S3 fo overwritten files
32
+ def exists?
33
+ false
34
+ end
35
+
36
+ def storage_location(level)
37
+ "#{@s3_key}/#{level}"
38
+ end
39
+
40
+ # no-op
41
+ def mkdir(_path)
42
+ end
43
+
44
+ def write(file, dest, options = {})
45
+ quality = options[:quality]
46
+ s3.put_object(@s3_bucket, dest, file.to_blob { @quality = quality if quality },
47
+ 'Content-Type' => file.mime_type,
48
+ 'x-amz-acl' => @s3_acl
49
+ )
50
+ end
51
+
52
+ private
53
+
54
+ def require_fog!
55
+ require 'fog'
56
+ rescue LoadError => e
57
+ STDERR.puts 'Fog is required for storing data in S3, run `gem install fog`.'
58
+ raise e
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,99 @@
1
+ require 'mini_magick'
2
+
3
+ module MiniDzt
4
+ class Tiler
5
+ # Defaults
6
+ DEFAULT_TILE_SIZE = 512
7
+ DEFAULT_TILE_OVERLAP = 0
8
+ DEFAULT_QUALITY = 75
9
+ DEFAULT_TILE_FORMAT = 'jpg'
10
+ DEFAULT_OVERWRITE_FLAG = false
11
+
12
+ # Generates the DZI-formatted tiles and sets necessary metadata on this object.
13
+ #
14
+ # @param [Hash] options
15
+ # @option source Magick::Image, or filename of image to be used for tiling
16
+ # @option quality Image compression quality (default: 75)
17
+ # @option format Format for output tiles (default: "jpg")
18
+ # @option size Size, in pixels, for tile squares (default: 512)
19
+ # @option overlap Size, in pixels, of the overlap between tiles (default: 2)
20
+ # @option overwrite Whether or not to overwrite if the destination exists (default: false)
21
+ def initialize(options)
22
+ fail 'Missing options[:source].' unless options[:source]
23
+
24
+ @tile_source = MiniMagick::Image.open(options[:source])
25
+ @tile_size = options[:size] || DEFAULT_TILE_SIZE
26
+ @tile_overlap = options[:overlap] || DEFAULT_TILE_OVERLAP
27
+ @tile_format = options[:format] || DEFAULT_TILE_FORMAT
28
+ @tile_quality = options[:quality] || DEFAULT_QUALITY
29
+ @overwrite = options[:overwrite] || DEFAULT_OVERWRITE_FLAG
30
+
31
+ @max_tiled_height = @tile_source.height
32
+ @max_tiled_width = @tile_source.width
33
+ end
34
+
35
+ def slice!(output_dir)
36
+ @tmp_working_dir = Pathname(@tile_source.path).dirname + "mini_dzt_#{SecureRandom.hex}"
37
+ FileUtils.mkdir_p @tmp_working_dir
38
+
39
+ orig_width = @tile_source.width
40
+ orig_height = @tile_source.height
41
+
42
+ max_level(orig_width, orig_height).downto(0) do |level|
43
+ puts "Level #{level}..."
44
+ current_level_storage_dir = "#{@tmp_working_dir}/#{level}"
45
+ FileUtils.mkdir_p current_level_storage_dir
46
+
47
+ width = @tile_source.width
48
+ height = @tile_source.height
49
+
50
+ manuscripts = get_manuscripts(width, height, current_level_storage_dir)
51
+
52
+ manuscripts.each do |dest_path, geometry_arg|
53
+ crope_image(@tile_source, dest_path, geometry_arg, @tile_quality)
54
+ end
55
+
56
+ @tile_source.resize("50%")
57
+ end
58
+ FileUtils.mv @tmp_working_dir, output_dir
59
+ end
60
+
61
+ private
62
+ def tile_counts(length)
63
+ return 1 if length <= @tile_size
64
+ (length / @tile_size.to_f).ceil
65
+ end
66
+
67
+ def get_manuscripts(width, height, current_level_storage_dir)
68
+ manuscripts = []
69
+
70
+ overlapping_tile_size = @tile_size + @tile_overlap
71
+ col_counts = tile_counts(width)
72
+ row_counts = tile_counts(height)
73
+ x, y = [0, 0]
74
+
75
+ row_counts.times do |row_count|
76
+ col_counts.times do |col_count|
77
+ manuscripts << [
78
+ File.join(current_level_storage_dir, "#{col_count}_#{row_count}.#{@tile_format}"),
79
+ "#{overlapping_tile_size}x#{overlapping_tile_size}+#{x}+#{y}"
80
+ ]
81
+ x += @tile_size
82
+ end
83
+ x = 0
84
+ y += @tile_size
85
+ end
86
+ manuscripts
87
+ end
88
+
89
+ def max_level(width, height)
90
+ (Math.log([width, height].max) / Math.log(2)).ceil
91
+ end
92
+
93
+ def crope_image(image, dest_path, geometry_arg, quality = 75)
94
+ puts geometry_arg
95
+ cmd = "convert -crop #{geometry_arg} #{image.path} #{dest_path}"
96
+ system(cmd)
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,12 @@
1
+ require 'washi/config'
2
+
3
+ module Washi
4
+ class Tiler
5
+ def self.call(input_path, output_path, options={})
6
+ unless tile_size = options[:tile_size]
7
+ fail "Need pass :tile_size"
8
+ end
9
+ `#{Washil.config.binapath} #{input_path} #{output_path} --tile-size #{tile_size} --overlap #{Washil.config.overlap} #{Washil.config.options.join(" ")}`
10
+ end
11
+ end
12
+ end
@@ -1,3 +1,3 @@
1
1
  module Washi
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: washi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - gogotanaka
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-04-24 00:00:00.000000000 Z
11
+ date: 2016-04-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -71,6 +71,11 @@ files:
71
71
  - bin/setup
72
72
  - exe/washi
73
73
  - lib/washi.rb
74
+ - lib/washi/config.rb
75
+ - lib/washi/mini_dzt/file_storage.rb
76
+ - lib/washi/mini_dzt/s3_storage.rb
77
+ - lib/washi/mini_dzt/tiler.rb
78
+ - lib/washi/tiler.rb
74
79
  - lib/washi/version.rb
75
80
  - test/fixtures/img1.jpg
76
81
  - test/fixtures/img2.jpg