dzt 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9ebec393c326ec86c8abdb6f4ccc73c4c74398b8
4
+ data.tar.gz: 647bcbe70edcb2a8718a757cd12f2cbda0eac921
5
+ SHA512:
6
+ metadata.gz: 8735da367c32b01f25ad064685ff460eeaaf874410a99c238932ec3e5a2264df35a6eff169f3057ec3bb1cfd7650a6929084faa68d3391bd111602c998ac6b9d
7
+ data.tar.gz: 65cdf93cb7fb7bd6a8926f9410456fbb38def9193ffb7832a7eeb1167fd61281dadf1873f0122b27c60c9cc2db121fc55ae99674f6e76e49cf090f44ec9254c3
@@ -0,0 +1,3 @@
1
+ ### 0.1.0 (3/16/2014)
2
+
3
+ * Initial public release - [@dblock](https://github.com/dblock).
@@ -0,0 +1,10 @@
1
+ Contributing
2
+ ============
3
+
4
+ You're encouraged to contribute to this gem.
5
+
6
+ * Fork this project.
7
+ * Make changes, write tests.
8
+ * Updated [CHANGELOG](CHANGELOG.md).
9
+ * Make a pull request, bonus points for topic branches.
10
+
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2014 Daniel Doubrovkine.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,39 @@
1
+ DZT
2
+ ===
3
+
4
+ [![Build Status](https://travis-ci.org/dblock/dzt.png)](https://travis-ci.org/dblock/dzt)
5
+
6
+ Slice deep-zoom tiled images to be used with [OpenSeaDragon](http://openseadragon.github.io/) or [ARTiledImageView](https://github.com/dblock/ARTiledImageView).
7
+
8
+ ![](screenshots/goya.gif)
9
+
10
+ ## Usage
11
+
12
+ ```
13
+ gem install dzt
14
+ ```
15
+
16
+ #### Get Help
17
+
18
+ ```
19
+ dzt help
20
+ ```
21
+
22
+ #### Tile an Image
23
+
24
+ ```
25
+ dzt slice image.jpg --output tiles
26
+ ```
27
+
28
+ Creates a *tiles* folder with deep-zoom tiles.
29
+
30
+
31
+ ## Contributing
32
+
33
+ See [CONTRIBUTING](CONTRIBUTING.md).
34
+
35
+ ## Copyright and License
36
+
37
+ Copyright (c) 2014, Daniel Doubrovkine, [Artsy](http://artsy.github.io). Some tiling code inspired from [deep_zoom_slicer](https://github.com/meso-unimpressed/deep_zoom_slicer).
38
+
39
+ This project is licensed under the [MIT License](LICENSE.md).
data/bin/dzt ADDED
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env ruby
2
+ require 'gli'
3
+ require 'dzt'
4
+
5
+ include GLI::App
6
+
7
+ program_desc 'Tile images into deep-zoom tiles'
8
+
9
+ default_command :slice
10
+
11
+ desc "Slice an image"
12
+ command :slice do |c|
13
+ c.flag [:o, :output], desc: 'Output folder', default_value: File.join(Dir.pwd, "tiles")
14
+ c.action do |global_options, options, args|
15
+ if args.length < 1
16
+ raise 'You must specify an image file to slice.'
17
+ end
18
+ tiler = DZT::Tiler.new(
19
+ source: args[0],
20
+ destination: options[:output]
21
+ )
22
+ tiler.slice! do |path|
23
+ puts path
24
+ end
25
+ end
26
+ end
27
+
28
+ exit run(ARGV)
@@ -0,0 +1,3 @@
1
+ require 'RMagick'
2
+ require 'dzt/version'
3
+ require 'dzt/tiler'
@@ -0,0 +1,126 @@
1
+ # Deep Zoom module for generating Deep Zoom (DZI) tiles from a source image
2
+ module DZT
3
+ class Tiler
4
+ # Defaults
5
+ DEFAULT_TILE_SIZE = 512
6
+ DEFAULT_TILE_OVERLAP = 0
7
+ DEFAULT_QUALITY = 75
8
+ DEFAULT_TILE_FORMAT = "jpg"
9
+
10
+ # Generates the DZI-formatted tiles and sets necessary metadata on this object.
11
+ #
12
+ # @param source Magick::Image, or filename of image to be used for tiling
13
+ # @param quality Image compression quality (default: 75)
14
+ # @param format Format for output tiles (default: "jpg")
15
+ # @param size Size, in pixels, for tile squares (default: 512)
16
+ # @param overlap Size, in pixels, of the overlap between tiles (default: 2)
17
+ # @param overwrite If true, overwrites existing tiles (default: false)
18
+ # @param destination: Full directory in which to output tiles.
19
+ #
20
+ def initialize(options)
21
+ @tile_source = options[:source]
22
+ raise "Missing options[:source]." unless @tile_source
23
+ @tile_source = Magick::Image.read(@tile_source)[0] if @tile_source.is_a?(String)
24
+ @tile_size = options[:size] || DEFAULT_TILE_SIZE
25
+ @tile_overlap = options[:overlap] || DEFAULT_TILE_OVERLAP
26
+ @tile_format = options[:format] || DEFAULT_TILE_FORMAT
27
+ @max_tiled_height = @tile_source.rows
28
+ @max_tiled_width = @tile_source.columns
29
+ @tile_quality = options[:quality] || DEFAULT_QUALITY
30
+ @overwrite = options[:overwrite] || false
31
+ @destination = options[:destination] || File.join(Dir.pwd, "tiles")
32
+ end
33
+
34
+ ##
35
+ # Generates the DZI-formatted tiles and sets necessary metadata on this object.
36
+ # Uses a default tile size of 512 pixels, with a default overlap of 2 pixel.
37
+ ##
38
+ def slice!(&block)
39
+ if ! @overwrite && File.directory?(@destination) && ! Dir["@{@destination}/*"].empty?
40
+ raise "Output directory #{@destination} already exists!"
41
+ @overwrite ? Rails.logger.warn(msg) : raise(msg)
42
+ end
43
+
44
+ image = @tile_source.dup
45
+ orig_width, orig_height = image.columns, image.rows
46
+
47
+ # iterate over all levels (= zoom stages)
48
+ max_level(orig_width, orig_height).downto(0) do |level|
49
+ width, height = image.columns, image.rows
50
+
51
+ current_level_dir = File.join(@destination, level.to_s)
52
+ FileUtils.mkdir_p(current_level_dir)
53
+
54
+ if block_given?
55
+ yield current_level_dir
56
+ end
57
+
58
+ # iterate over columns
59
+ x, col_count = 0, 0
60
+ while x < width
61
+ # iterate over rows
62
+ y, row_count = 0, 0
63
+ while y < height
64
+ dest_path = File.join(current_level_dir, "#{col_count}_#{row_count}.#{@tile_format}")
65
+ tile_width, tile_height = tile_dimensions(x, y, @tile_size, @tile_overlap)
66
+
67
+ save_cropped_image(image, dest_path, x, y, tile_width, tile_height, @tile_quality)
68
+
69
+ y += (tile_height - (2 * @tile_overlap))
70
+ row_count += 1
71
+ end
72
+ x += (tile_width - (2 * @tile_overlap))
73
+ col_count += 1
74
+ end
75
+
76
+ image.resize!(0.5)
77
+ end
78
+
79
+ image.destroy!
80
+ end
81
+
82
+ protected
83
+
84
+ # Determines width and height for tiles, dependent of tile position.
85
+ # Center tiles have overlapping on each side.
86
+ # Borders have no overlapping on the border side and overlapping on all other sides.
87
+ # Corners have only overlapping on the right and lower border.
88
+ def tile_dimensions(x, y, tile_size, overlap)
89
+ overlapping_tile_size = tile_size + (2 * overlap)
90
+ border_tile_size = tile_size + overlap
91
+
92
+ tile_width = (x > 0) ? overlapping_tile_size : border_tile_size
93
+ tile_height = (y > 0) ? overlapping_tile_size : border_tile_size
94
+
95
+ return tile_width, tile_height
96
+ end
97
+
98
+ # Calculates how often an image with given dimension can
99
+ # be divided by two until 1x1 px are reached.
100
+ def max_level(width, height)
101
+ return (Math.log([width, height].max) / Math.log(2)).ceil
102
+ end
103
+
104
+ # Crops part of src image and writes it to dest path.
105
+ #
106
+ # Params: src: may be an Magick::Image object or a path to an image.
107
+ # dest: path where cropped image should be stored.
108
+ # x, y: offset from upper left corner of source image.
109
+ # width, height: width and height of cropped image.
110
+ # quality: compression level 0-100 (or 0.0-1.0), lower number means higher compression.
111
+ def save_cropped_image(src, dest, x, y, width, height, quality = 75)
112
+ if src.is_a? Magick::Image
113
+ img = src
114
+ else
115
+ img = Magick::Image::read(src).first
116
+ end
117
+
118
+ quality = quality * 100 if quality < 1
119
+
120
+ # The crop method retains the offset information in the cropped image.
121
+ # To reset the offset data, adding true as the last argument to crop.
122
+ cropped = img.crop(x, y, width, height, true)
123
+ cropped.write(dest) { @quality = quality }
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,3 @@
1
+ module DZT
2
+ VERSION = '0.1.0'
3
+ end
metadata ADDED
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dzt
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Daniel Doubrovkine
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-03-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: gli
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rmagick
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description:
42
+ email: dblock@dblock.org
43
+ executables:
44
+ - dzt
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - bin/dzt
49
+ - lib/dzt/tiler.rb
50
+ - lib/dzt/version.rb
51
+ - lib/dzt.rb
52
+ - CHANGELOG.md
53
+ - CONTRIBUTING.md
54
+ - LICENSE.md
55
+ - README.md
56
+ homepage: http://github.com/dblock/dzt
57
+ licenses:
58
+ - MIT
59
+ metadata: {}
60
+ post_install_message:
61
+ rdoc_options: []
62
+ require_paths:
63
+ - lib
64
+ required_ruby_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ required_rubygems_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - '>='
72
+ - !ruby/object:Gem::Version
73
+ version: 1.3.6
74
+ requirements: []
75
+ rubyforge_project:
76
+ rubygems_version: 2.0.14
77
+ signing_key:
78
+ specification_version: 4
79
+ summary: Tile images for deep-zoom.
80
+ test_files: []