ndav-magick-image 0.0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: bf489f7ae5981b5e552d896e8ce0f0696784d914572af0678790464f409f9b16
4
+ data.tar.gz: '09e621d161ed19c832229e535a9f9ff3a6864b1f05756ab91c0c2e5a1e3e800b'
5
+ SHA512:
6
+ metadata.gz: 955db5a60c525d1be3a242c424428a93a71cdec036724684f14c1876741bb56f3de86d0e3be75ced7980f44038573332a7a508b0918df524017f3b3e17c4e666
7
+ data.tar.gz: 85d97b041b9153ff193b5348fee2b55257458f76450019307b2a4ff529b726c68d388fb3f1944328aaba12deaf09422d4b6d525c41c5658364b6c7146b30faea
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ Gemfile.lock
2
+ pkg/
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) Kitaiti Makoto
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,112 @@
1
+ NDAV::Magick::Image
2
+ ===================
3
+
4
+ [NDAV][] bridge for [RMagick][]'s `Magick::Image`.
5
+
6
+ SYNOPSIS
7
+ --------
8
+
9
+ ```ruby
10
+ require "rmagick"
11
+ require "ndav/magick/image"
12
+
13
+ # to_xxx API
14
+ image_list = Magick::ImageList.new("path/to/image")
15
+ image = image_list[0] # => Magick::Image
16
+ ndav = image.to_ndav # => NDAV
17
+ image = ndav.to_magick_image # => Magick::Image
18
+
19
+ # Now it's a MemoryView producer
20
+ memory_view = Fiddle::MemoryView.new(image) # => Fiddle::MemoryView
21
+
22
+ # from_xxx API
23
+ ndav = NDAV.from_magick_image(image) # => NDAV
24
+ image = Magick::Image.from_ndav(ndav) # => Magick::Image
25
+
26
+ # cast-like conversion API
27
+ include NDAV::Converter
28
+ ndav = NDAV(image) # => NDAV
29
+ image = MagickImage(ndav) # => Magick::Image
30
+ ```
31
+
32
+ *Note* that this bridge currently copies data during conversion between `NDAV` and `Magick::Image`.
33
+
34
+ *Note* that this bridge is the early implementation. Breaking changes are expected in the near future.
35
+
36
+ INSTALLATION
37
+ ------------
38
+
39
+ % gem install ndav-magick-image
40
+
41
+ Or,
42
+
43
+ % bundle add ndav-magick-image
44
+
45
+ CONVERSION RULES
46
+ ----------------
47
+
48
+ These are conversion rules between `Magick::Image` and `NDAV`.
49
+
50
+ ### shape ###
51
+
52
+ The shape is `[height, width, channels]`. Channels vary based on the image attributes.
53
+
54
+ | channels | gray? | alpha? | pixel value |
55
+ |----------|----------|--------|----------------------|
56
+ | `1` | `true` | `false`| `[intensity]` |
57
+ | `2` | `true` | `true` | `[intensity, alpha]` |
58
+ | `3` | `false` | `false`| `[R, G, B]` |
59
+ | `4` | `false` | `true` | `[R, G, B, alpha]` |
60
+
61
+ ### format and item size ###
62
+
63
+ Currently, this bridge supports only 8-bit depth expression of pixels, which means all channels including grayscale intencity, RGB and alpha are 0-255 values. Therefore, the MemoryView format is always `"C"` and the item size is 1-byte. Currently, HDR images are converted to standard dynamic-range images.
64
+
65
+ Other formats such as float might be supported in the future.
66
+
67
+ EXAMPLE
68
+ -------
69
+
70
+ Using `NDAV`, we can convert between `Magick::Image` and `Numo::NArray`. Let's inject noise to an image. That's quite easy if you use [Numo::NArray][].
71
+
72
+ ```ruby
73
+ require "rmagick"
74
+ require "ndav/magick/image"
75
+ require "numo/narray/alt"
76
+ require "ndav/numo/narray"
77
+
78
+ include ::NDAV::Converter
79
+
80
+ image_list = Magick::ImageList.new("path/to/image")
81
+ image = image_list[0]
82
+ numo = NumoNArray(image)
83
+ abort "Use RGB image" unless numo.shape[2] == 3
84
+
85
+ noise = Numo::Int8.new(numo.shape).rand(Numo::Int8::MIN, Numo::Int8::MAX)
86
+ noised = Numo::Int16.cast(numo)
87
+ noised.inplace + noise
88
+ noised.inplace.clip(Numo::UInt8::MIN, Numo::UInt8::MAX)
89
+
90
+ noised_image = MagickImage(Numo::UInt8.cast(noised))
91
+ noised_image.write "noised.png"
92
+ ```
93
+
94
+ | Before | After |
95
+ |--------|-------|
96
+ | [![Original image](https://i.gyazo.com/905f541f15c0d57db5fc7ea3f6edaf07.png)](https://gyazo.com/905f541f15c0d57db5fc7ea3f6edaf07) | [![Noized image](https://i.gyazo.com/7ad51507e7a2d2c8c39c15ce71a5175a.png)](https://gyazo.com/7ad51507e7a2d2c8c39c15ce71a5175a) |
97
+
98
+ TODO
99
+ ----
100
+
101
+ * Support HDRI
102
+ * Support zero-copy
103
+ * Support float value pixels
104
+
105
+ LICENSE
106
+ -------
107
+
108
+ MIT License. See LICENSE.txt file.
109
+
110
+ [NDAV]: https://kitaitimakoto.gitlab.io/ndav/
111
+ [RMagick]: https://rmagick.github.io/
112
+ [Numo::NArray]: https://ruby-numo.github.io/numo-narray/
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require "rake/testtask"
2
+ require "rubygems/tasks"
3
+
4
+ task default: :test
5
+
6
+ Gem::Tasks.new
7
+ Rake::TestTask.new
@@ -0,0 +1,74 @@
1
+ require "ndav"
2
+ require "rmagick"
3
+
4
+ class NDAV
5
+ module Magick
6
+ module Image
7
+ CHANNELS_TO_MAP = {
8
+ nil => "I",
9
+ 1 => "I",
10
+ 2 => "IA",
11
+ 3 => "RGB",
12
+ 4 => "RGBA"
13
+ }
14
+
15
+ module FromNDAV
16
+ # TODO: Support more formats
17
+ def from_ndav(ndav)
18
+ raise %|Currently, supports only format "C", but is "#{ndav.format}"| unless ndav.format == "C"
19
+ raise "Currently, supports only row-major contiguous NDAV" unless ndav.row_major_contiguous?
20
+ raise "ndim must be 2 or 3 but is #{ndav.ndim}" unless [2, 3].include? ndav.ndim
21
+
22
+ height, width, channels = ndav.shape
23
+ map = CHANNELS_TO_MAP[channels]
24
+ raise "Unsupported channels: #{channels}" unless map
25
+
26
+ image = ::Magick::Image.new(width, height)
27
+ image.import_pixels 0, 0, width, height, map, ndav.to_s
28
+ image
29
+ end
30
+ end
31
+
32
+ module MemoryViewable
33
+ private
34
+
35
+ # TODO: Support HDRI
36
+ def ndav_descriptor(**)
37
+ map =
38
+ case [gray?, alpha?]
39
+ when [true, true] then "IA"
40
+ when [true, false] then "I"
41
+ when [false, true] then "RGBA"
42
+ else "RGB"
43
+ end
44
+ shape = [rows, columns, map.length]
45
+ format = "C"
46
+ item_size = ::NDAV::ITEM_SIZES[format]
47
+
48
+ {
49
+ data: export_pixels_to_str(0, 0, columns, rows, map, ::Magick::CharPixel),
50
+ shape:,
51
+ strides: ::NDAV.default_strides(shape:, item_size:),
52
+ format:,
53
+ byte_size: shape.reduce(item_size, :*),
54
+ readonly?: true
55
+ }
56
+ end
57
+ end
58
+
59
+ module Converter
60
+ def MagickImage(array, *, **)
61
+ if array.kind_of? ::Magick::Image
62
+ array
63
+ elsif array.respond_to? :to_ndav
64
+ array.to_ndav(*, **).to_magick_image
65
+ else
66
+ ::NDAV.new(array, *, **).to_magick_image
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+
73
+ register ::Magick::Image, Magick::Image, name: :magick_image
74
+ end
@@ -0,0 +1,20 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "ndav-magick-image"
3
+ s.version = "0.0.1"
4
+ s.authors = ["Kitaiti Makoto"]
5
+ s.summary = "N-Dimensional Array View for RMagick"
6
+ s.licenses = ["MIT"]
7
+ s.homepage = "https://gitlab.com/KitaitiMakoto/ndav-magick-image"
8
+
9
+ s.files = Dir.chdir(__dir__) {`git ls-files -z`.split("\x0")}
10
+
11
+ s.add_runtime_dependency "ndav"
12
+ s.add_runtime_dependency "rmagick"
13
+
14
+ s.add_development_dependency "rake"
15
+ s.add_development_dependency "test-unit"
16
+ s.add_development_dependency "test-unit-notify"
17
+ s.add_development_dependency "terminal-notifier" if RUBY_PLATFORM.match? /darwin/
18
+ s.add_development_dependency "rubygems-tasks"
19
+ s.add_development_dependency "fiddle"
20
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,5 @@
1
+ require "ndav/magick/image"
2
+ require "test/unit"
3
+ require "test/unit/notify"
4
+ require "fiddle"
5
+ require "tmpdir"
@@ -0,0 +1,30 @@
1
+ require_relative "helper"
2
+
3
+ class TestConverter < Test::Unit::TestCase
4
+ def setup
5
+ @width = 3
6
+ @height = 2
7
+ end
8
+
9
+ def test_ndav_from_magick_image
10
+ image = ::Magick::Image.new(@width, @height)
11
+ draw = ::Magick::Draw.new
12
+ draw.fill "#00FF00"
13
+ draw.rectangle 0, 1, 3, 2
14
+ draw.draw image
15
+ image.alpha ::Magick::OffAlphaChannel
16
+
17
+ assert_instance_of ::NDAV, ::NDAV::Converter::NDAV(image)
18
+ end
19
+
20
+ def test_magick_image_from_ndav
21
+ array = [
22
+ [[255, 255, 255] * @width] * (@height / 2),
23
+ [[ 0, 255, 0] * @width] * (@height / 2)
24
+ ]
25
+ ptr = Fiddle::Pointer[array.flatten.pack("C*")]
26
+ ndav = ::NDAV.new(ptr, shape: [@height, @width, 3])
27
+
28
+ assert_instance_of ::Magick::Image, ::NDAV::Converter::MagickImage(ndav)
29
+ end
30
+ end
@@ -0,0 +1,72 @@
1
+ require_relative "helper"
2
+
3
+ class TestFromNDAV < Test::Unit::TestCase
4
+ def setup
5
+ @width = 3
6
+ @height = 2
7
+ end
8
+
9
+ def test_basic
10
+ array = [
11
+ [[255, 255, 255] * @width] * (@height / 2),
12
+ [[ 0, 255, 0] * @width] * (@height / 2)
13
+ ]
14
+ ptr = Fiddle::Pointer[array.flatten.pack("C*")]
15
+ ndav = ::NDAV.new(ptr, shape: [@height, @width, 3])
16
+ image = ::Magick::Image.from_ndav(ndav)
17
+
18
+ assert_equal @width, image.columns
19
+ assert_equal @height, image.rows
20
+ assert_false image.gray?
21
+ assert_false image.alpha?
22
+ assert_equal array.flatten, image.export_pixels_to_str.unpack("C*")
23
+ end
24
+
25
+ def test_alpha
26
+ array = [
27
+ [[255, 255, 255, 128] * @width] * (@height / 2),
28
+ [[ 0, 255, 0, 128] * @width] * (@height / 2)
29
+ ]
30
+ ptr = Fiddle::Pointer[array.flatten.pack("C*")]
31
+ ndav = ::NDAV.new(ptr, shape: [@height, @width, 4])
32
+ image = ::Magick::Image.from_ndav(ndav)
33
+
34
+ assert_equal @width, image.columns
35
+ assert_equal @height, image.rows
36
+ assert_false image.gray?
37
+ assert_true image.alpha?
38
+ assert_equal array.flatten, image.export_pixels_to_str(0, 0, @width, @height, "RGBA").unpack("C*")
39
+ end
40
+
41
+ def test_grayscale
42
+ array = [
43
+ [[255] * @width] * (@height / 2),
44
+ [[128] * @width] * (@height / 2)
45
+ ]
46
+ ptr = Fiddle::Pointer[array.flatten.pack("C*")]
47
+ ndav = ::NDAV.new(ptr, shape: [@height, @width, 1])
48
+ image = ::Magick::Image.from_ndav(ndav)
49
+
50
+ assert_equal @width, image.columns
51
+ assert_equal @height, image.rows
52
+ assert_true image.gray?
53
+ assert_false image.alpha?
54
+ assert_equal array.flatten, image.export_pixels_to_str(0, 0, @width, @height, "R").unpack("C*")
55
+ end
56
+
57
+ def test_gray_alpha
58
+ array = [
59
+ [[255, 128] * @width] * (@height / 2),
60
+ [[128, 128] * @width] * (@height / 2)
61
+ ]
62
+ ptr = Fiddle::Pointer[array.flatten.pack("C*")]
63
+ ndav = ::NDAV.new(ptr, shape: [@height, @width, 2])
64
+ image = ::Magick::Image.from_ndav(ndav)
65
+
66
+ assert_equal @width, image.columns
67
+ assert_equal @height, image.rows
68
+ assert_true image.gray?
69
+ assert_true image.alpha?
70
+ assert_equal array.flatten, image.export_pixels_to_str(0, 0, @width, @height, "RA").unpack("C*")
71
+ end
72
+ end
@@ -0,0 +1,31 @@
1
+ require_relative "helper"
2
+
3
+ class TestMagickImage < Test::Unit::TestCase
4
+ def setup
5
+ @width = 3
6
+ @height = 2
7
+ @color = "#00FF00"
8
+ end
9
+
10
+ def test_identical
11
+ image = Magick::Image.new(@width, @height)
12
+ draw = Magick::Draw.new
13
+ draw.fill @color
14
+ draw.rectangle 0, 1, 3, 2
15
+ draw.draw image
16
+ image.alpha Magick::OffAlphaChannel
17
+ converted = image.to_ndav.to_magick_image
18
+
19
+ assert_equal image, converted
20
+
21
+ Dir.mktmpdir do |dir|
22
+ dir = File.realpath(dir)
23
+ orig_path = File.join(dir, "orig.png")
24
+ converted_path = File.join(dir, "converted.png")
25
+
26
+ image.write orig_path
27
+ converted.write converted_path
28
+ assert_equal File.read(orig_path), File.read(converted_path)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,82 @@
1
+ require_relative "helper"
2
+
3
+ class TestMemoryViewable < Test::Unit::TestCase
4
+ def setup
5
+ @width = 3
6
+ @height = 2
7
+ @image = ::Magick::Image.new(@width, @height)
8
+
9
+ draw = Magick::Draw.new
10
+ draw.fill "#00FF00"
11
+ draw.rectangle 0, 1, 3, 2
12
+ draw.draw @image
13
+
14
+ @image.alpha Magick::OffAlphaChannel
15
+ end
16
+
17
+ def test_basic
18
+ Fiddle::MemoryView.export @image do |view|
19
+ assert_equal 3, view.ndim
20
+ assert_equal [@height, @width, 3], view.shape
21
+ assert_equal 1, view.item_size
22
+ assert_equal "C", view.format
23
+ assert_equal @width * @height * 3, view.byte_size
24
+ assert_equal [
25
+ [[255, 255, 255] * @width] * (@height / 2),
26
+ [[ 0, 255, 0] * @width] * (@height / 2)
27
+ ].flatten,
28
+ view.to_s.unpack("C*")
29
+ end
30
+ end
31
+
32
+ def test_alpha
33
+ @image.alpha Magick::OnAlphaChannel
34
+
35
+ Fiddle::MemoryView.export @image do |view|
36
+ assert_equal 3, view.ndim
37
+ assert_equal [@height, @width, 4], view.shape
38
+ assert_equal 1, view.item_size
39
+ assert_equal "C", view.format
40
+ assert_equal @width * @height * 4, view.byte_size
41
+ end
42
+ end
43
+
44
+ def test_grayscale
45
+ image = @image.quantize(256, Magick::GRAYColorspace)
46
+
47
+ Fiddle::MemoryView.export image do |view|
48
+ assert_equal 3, view.ndim
49
+ assert_equal [@height, @width, 1], view.shape
50
+ assert_equal 1, view.item_size
51
+ assert_equal "C", view.format
52
+ assert_equal @width * @height * 1, view.byte_size
53
+ assert_equal [
54
+ [[255] * @width] * (@height / 2),
55
+ [[182] * @width] * (@height / 2)
56
+ ].flatten,
57
+ view.to_s.unpack("C*")
58
+ end
59
+ end
60
+
61
+ def test_gray_alpha
62
+ image = @image.quantize(256, Magick::GRAYColorspace)
63
+ image.alpha Magick::OnAlphaChannel
64
+
65
+ Fiddle::MemoryView.export image do |view|
66
+ assert_equal 3, view.ndim
67
+ assert_equal [@height, @width, 2], view.shape
68
+ assert_equal 1, view.item_size
69
+ assert_equal "C", view.format
70
+ assert_equal @width * @height * 2, view.byte_size
71
+ assert_equal [
72
+ [[255, 255] * @width] * (@height / 2),
73
+ [[182, 255] * @width] * (@height / 2)
74
+ ].flatten,
75
+ view.to_s.unpack("C*")
76
+ end
77
+ end
78
+
79
+ def test_writable
80
+ pend
81
+ end
82
+ end
metadata ADDED
@@ -0,0 +1,161 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ndav-magick-image
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Kitaiti Makoto
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: ndav
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '0'
26
+ - !ruby/object:Gem::Dependency
27
+ name: rmagick
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ - !ruby/object:Gem::Dependency
41
+ name: rake
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ type: :development
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ - !ruby/object:Gem::Dependency
55
+ name: test-unit
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ type: :development
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ - !ruby/object:Gem::Dependency
69
+ name: test-unit-notify
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ type: :development
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ - !ruby/object:Gem::Dependency
83
+ name: terminal-notifier
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ type: :development
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ - !ruby/object:Gem::Dependency
97
+ name: rubygems-tasks
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ type: :development
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: fiddle
112
+ requirement: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ type: :development
118
+ prerelease: false
119
+ version_requirements: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ executables: []
125
+ extensions: []
126
+ extra_rdoc_files: []
127
+ files:
128
+ - ".gitignore"
129
+ - Gemfile
130
+ - LICENSE.txt
131
+ - README.md
132
+ - Rakefile
133
+ - lib/ndav/magick/image.rb
134
+ - ndav-magick-image.gemspec
135
+ - test/helper.rb
136
+ - test/test_converter.rb
137
+ - test/test_from_ndav.rb
138
+ - test/test_magick_image.rb
139
+ - test/test_memory_viewable.rb
140
+ homepage: https://gitlab.com/KitaitiMakoto/ndav-magick-image
141
+ licenses:
142
+ - MIT
143
+ metadata: {}
144
+ rdoc_options: []
145
+ require_paths:
146
+ - lib
147
+ required_ruby_version: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ required_rubygems_version: !ruby/object:Gem::Requirement
153
+ requirements:
154
+ - - ">="
155
+ - !ruby/object:Gem::Version
156
+ version: '0'
157
+ requirements: []
158
+ rubygems_version: 4.0.20
159
+ specification_version: 4
160
+ summary: N-Dimensional Array View for RMagick
161
+ test_files: []