ruby-vips8 0.1.0
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 +7 -0
- data/.rspec +1 -0
- data/.yardopts +10 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +15 -0
- data/Gemfile.lock +84 -0
- data/LICENSE.txt +20 -0
- data/README.md +170 -0
- data/Rakefile +45 -0
- data/TODO +11 -0
- data/VERSION +1 -0
- data/example/annotate.rb +17 -0
- data/example/daltonize8.rb +75 -0
- data/example/example1.rb +84 -0
- data/example/example2.rb +31 -0
- data/example/example3.rb +19 -0
- data/example/example4.rb +18 -0
- data/example/example5.rb +31 -0
- data/example/trim8.rb +41 -0
- data/example/watermark.rb +44 -0
- data/example/wobble.rb +36 -0
- data/lib/vips8.rb +153 -0
- data/lib/vips8/access.rb +14 -0
- data/lib/vips8/align.rb +11 -0
- data/lib/vips8/angle.rb +12 -0
- data/lib/vips8/angle45.rb +16 -0
- data/lib/vips8/argument.rb +163 -0
- data/lib/vips8/bandformat.rb +20 -0
- data/lib/vips8/call.rb +302 -0
- data/lib/vips8/coding.rb +14 -0
- data/lib/vips8/demandstyle.rb +35 -0
- data/lib/vips8/direction.rb +11 -0
- data/lib/vips8/error.rb +30 -0
- data/lib/vips8/extend.rb +22 -0
- data/lib/vips8/foreignflags.rb +20 -0
- data/lib/vips8/image.rb +1383 -0
- data/lib/vips8/interpolate.rb +37 -0
- data/lib/vips8/interpretation.rb +28 -0
- data/lib/vips8/methods.rb +1807 -0
- data/lib/vips8/operation.rb +19 -0
- data/ruby-vips8.gemspec +112 -0
- data/spec/image_spec.rb +515 -0
- data/spec/samples/balloon.v +0 -0
- data/spec/samples/ghost.ppm +405 -0
- data/spec/samples/huge.jpg +0 -0
- data/spec/samples/icc.jpg +0 -0
- data/spec/samples/lcd.icc +0 -0
- data/spec/samples/lion.svg +154 -0
- data/spec/samples/sample.csv +7 -0
- data/spec/samples/sample.exr +0 -0
- data/spec/samples/wagon.jpg +0 -0
- data/spec/samples/wagon.v +0 -0
- data/spec/spec_helper.rb +49 -0
- data/spec/vips_spec.rb +74 -0
- metadata +198 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a53c0bc2ee35537831ff8ac3de36af784fcd063b
|
4
|
+
data.tar.gz: d9e83f55493934fbe42b2f004884ebdf5b6e8632
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0507b95ff7aa019f3b5b8de8227cde46e990730778c20740a74ccf1e4efb4a5b52142b2974affc48e560583976d5b755463f61906cc1d11ed2a0a6317a0daae3
|
7
|
+
data.tar.gz: a29eb8203ee77fbb096e5e18b06db20ef22608e4400e8eaa3ad5d819fa54a4c6b81468f35b34fcfc1af67c90d40a9322c4edbee471cd119e88473f4bde5a28a0
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.yardopts
ADDED
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
source 'http://rubygems.org'
|
2
|
+
|
3
|
+
# runtime deps
|
4
|
+
gem "gobject-introspection", "~> 3.0"
|
5
|
+
|
6
|
+
# Add dependencies to develop your gem here.
|
7
|
+
# Include everything needed to run rake, tests, features, etc.
|
8
|
+
group :development do
|
9
|
+
gem "rspec", "~> 3.3"
|
10
|
+
gem "yard", "~> 0.8"
|
11
|
+
gem "redcarpet", "~> 3.3"
|
12
|
+
gem "github-markup", "~> 1.4"
|
13
|
+
gem "bundler", "~> 1.0"
|
14
|
+
gem "jeweler", "~> 2.0"
|
15
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
addressable (2.4.0)
|
5
|
+
builder (3.2.2)
|
6
|
+
descendants_tracker (0.0.4)
|
7
|
+
thread_safe (~> 0.3, >= 0.3.1)
|
8
|
+
diff-lcs (1.2.5)
|
9
|
+
faraday (0.9.2)
|
10
|
+
multipart-post (>= 1.2, < 3)
|
11
|
+
git (1.2.9.1)
|
12
|
+
github-markup (1.4.0)
|
13
|
+
github_api (0.13.1)
|
14
|
+
addressable (~> 2.4.0)
|
15
|
+
descendants_tracker (~> 0.0.4)
|
16
|
+
faraday (~> 0.8, < 0.10)
|
17
|
+
hashie (>= 3.4)
|
18
|
+
multi_json (>= 1.7.5, < 2.0)
|
19
|
+
oauth2
|
20
|
+
glib2 (3.0.7)
|
21
|
+
pkg-config
|
22
|
+
gobject-introspection (3.0.7)
|
23
|
+
glib2 (= 3.0.7)
|
24
|
+
hashie (3.4.3)
|
25
|
+
highline (1.7.8)
|
26
|
+
jeweler (2.0.1)
|
27
|
+
builder
|
28
|
+
bundler (>= 1.0)
|
29
|
+
git (>= 1.2.5)
|
30
|
+
github_api
|
31
|
+
highline (>= 1.6.15)
|
32
|
+
nokogiri (>= 1.5.10)
|
33
|
+
rake
|
34
|
+
rdoc
|
35
|
+
json (1.8.3)
|
36
|
+
jwt (1.5.2)
|
37
|
+
mini_portile2 (2.0.0)
|
38
|
+
multi_json (1.11.2)
|
39
|
+
multi_xml (0.5.5)
|
40
|
+
multipart-post (2.0.0)
|
41
|
+
nokogiri (1.6.7.2)
|
42
|
+
mini_portile2 (~> 2.0.0.rc2)
|
43
|
+
oauth2 (1.0.0)
|
44
|
+
faraday (>= 0.8, < 0.10)
|
45
|
+
jwt (~> 1.0)
|
46
|
+
multi_json (~> 1.3)
|
47
|
+
multi_xml (~> 0.5)
|
48
|
+
rack (~> 1.2)
|
49
|
+
pkg-config (1.1.7)
|
50
|
+
rack (1.6.4)
|
51
|
+
rake (10.5.0)
|
52
|
+
rdoc (4.2.1)
|
53
|
+
json (~> 1.4)
|
54
|
+
redcarpet (3.3.4)
|
55
|
+
rspec (3.4.0)
|
56
|
+
rspec-core (~> 3.4.0)
|
57
|
+
rspec-expectations (~> 3.4.0)
|
58
|
+
rspec-mocks (~> 3.4.0)
|
59
|
+
rspec-core (3.4.1)
|
60
|
+
rspec-support (~> 3.4.0)
|
61
|
+
rspec-expectations (3.4.0)
|
62
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
63
|
+
rspec-support (~> 3.4.0)
|
64
|
+
rspec-mocks (3.4.1)
|
65
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
66
|
+
rspec-support (~> 3.4.0)
|
67
|
+
rspec-support (3.4.1)
|
68
|
+
thread_safe (0.3.5)
|
69
|
+
yard (0.8.7.6)
|
70
|
+
|
71
|
+
PLATFORMS
|
72
|
+
ruby
|
73
|
+
|
74
|
+
DEPENDENCIES
|
75
|
+
bundler (~> 1.0)
|
76
|
+
github-markup (~> 1.4)
|
77
|
+
gobject-introspection (~> 3.0)
|
78
|
+
jeweler (~> 2.0)
|
79
|
+
redcarpet (~> 3.3)
|
80
|
+
rspec (~> 3.3)
|
81
|
+
yard (~> 0.8)
|
82
|
+
|
83
|
+
BUNDLED WITH
|
84
|
+
1.10.6
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2014 John Cupitt
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,170 @@
|
|
1
|
+
# ruby-vips8
|
2
|
+
|
3
|
+
This gem provides a Ruby binding for the [vips image processing
|
4
|
+
library](http://www.vips.ecs.soton.ac.uk). It wraps version 8 of the API.
|
5
|
+
The older vips7-based [ruby-vips](https://github.com/jcupitt/ruby-vips)
|
6
|
+
gem is still being maintained.
|
7
|
+
|
8
|
+
`ruby-vips8` is fast and it can work without needing the
|
9
|
+
entire image to be loaded into memory.
|
10
|
+
`ruby-vips8` allows you to set up pipelines that don't get executed until you
|
11
|
+
output the image to disk or to a string. This means you can create,
|
12
|
+
manipulate, and pass around Image objects without incurring any memory or CPU
|
13
|
+
costs. The image is not actually processed until you write the image to memory
|
14
|
+
or to disk.
|
15
|
+
|
16
|
+
For example, the benchmark at
|
17
|
+
[vips-benchmarks](https://github.com/stanislaw/vips-benchmarks) loads a large
|
18
|
+
image, crops, shrinks, sharpens and saves again, and repeats 10 times.
|
19
|
+
|
20
|
+
```text
|
21
|
+
real time in seconds, fastest of three runs
|
22
|
+
benchmark tiff jpeg
|
23
|
+
ruby-vips.rb 2.77 2.98
|
24
|
+
ruby-vips8.rb 2.97 3.29
|
25
|
+
image-magick 8.18 9.71
|
26
|
+
rmagick.rb 9.22 10.06
|
27
|
+
image_sci.rb 9.39 7.20
|
28
|
+
|
29
|
+
peak memory use in bytes
|
30
|
+
benchmark peak RSS
|
31
|
+
ruby-vips.rb 107340
|
32
|
+
ruby-vips8.rb 117604
|
33
|
+
image_sci.rb 146536
|
34
|
+
rmagick.rb 3352020
|
35
|
+
```
|
36
|
+
|
37
|
+
See also [benchmarks at the official libvips
|
38
|
+
website](http://www.vips.ecs.soton.ac.uk/index.php?title=Speed_and_Memory_Use).
|
39
|
+
There's a handy blog post explaining [how libvips opens
|
40
|
+
files](http://libvips.blogspot.co.uk/2012/06/how-libvips-opens-file.html)
|
41
|
+
which gives some more background.
|
42
|
+
|
43
|
+
## Requirements
|
44
|
+
|
45
|
+
* OS X or Linux
|
46
|
+
* libvips 8.2 and later
|
47
|
+
|
48
|
+
## Installation prerequisites
|
49
|
+
|
50
|
+
### OS X
|
51
|
+
|
52
|
+
Install [homebrew](http://mxcl.github.com/homebrew) and enter:
|
53
|
+
|
54
|
+
```bash
|
55
|
+
$ brew install homebrew/science/vips
|
56
|
+
```
|
57
|
+
|
58
|
+
To verify that your vips install is working, try:
|
59
|
+
|
60
|
+
```bash
|
61
|
+
$ vips --version
|
62
|
+
vips-8.2.1
|
63
|
+
```
|
64
|
+
|
65
|
+
Make sure you have `Vips-8.0.typelib` on your `GI_TYPELIB_PATH`. Enter
|
66
|
+
something like:
|
67
|
+
|
68
|
+
```bash
|
69
|
+
$ export GI_TYPELIB_PATH=/usr/local/lib/girepository-1.0
|
70
|
+
```
|
71
|
+
|
72
|
+
### Other platforms
|
73
|
+
|
74
|
+
You need to install libvips from source since 8.2 has not been packaged yet
|
75
|
+
(Jan 2016).
|
76
|
+
|
77
|
+
Download a tarball from the
|
78
|
+
[libvips website](http://www.vips.ecs.soton.ac.uk/supported/current), or build
|
79
|
+
from [the git repository](https://github.com/jcupitt/libvips) and see the
|
80
|
+
README.
|
81
|
+
|
82
|
+
## Installing the gem.
|
83
|
+
|
84
|
+
```bash
|
85
|
+
$ gem install ruby-vips8
|
86
|
+
```
|
87
|
+
|
88
|
+
or include it in Gemfile:
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
gem 'ruby-vips8'
|
92
|
+
```
|
93
|
+
|
94
|
+
And take a look in `examples/`. There is full yard documentation, take a look
|
95
|
+
there too.
|
96
|
+
|
97
|
+
# Example
|
98
|
+
|
99
|
+
```ruby
|
100
|
+
require 'vips8'
|
101
|
+
|
102
|
+
im = Vips::Image.new_from_file filename
|
103
|
+
|
104
|
+
# put im at position (100, 100) in a 3000 x 3000 pixel image,
|
105
|
+
# make the other pixels in the image by mirroring im up / down /
|
106
|
+
# left / right, see
|
107
|
+
# http://www.vips.ecs.soton.ac.uk/supported/current/doc/html/libvips/libvips-conversion.html#vips-embed
|
108
|
+
im = im.embed 100, 100, 3000, 3000, :extend => :mirror
|
109
|
+
im.write_to_file output_filename
|
110
|
+
|
111
|
+
# multiply the green (middle) band by 2, leave the other two alone
|
112
|
+
im *= [1, 2, 1]
|
113
|
+
|
114
|
+
# make an image from an array constant, convolve with it
|
115
|
+
mask = Vips::Image.new_from_array [
|
116
|
+
[-1, -1, -1],
|
117
|
+
[-1, 16, -1],
|
118
|
+
[-1, -1, -1]], 8
|
119
|
+
im = im.conv mask
|
120
|
+
```
|
121
|
+
|
122
|
+
# What's wrong with ruby-vips?
|
123
|
+
|
124
|
+
There's an existing Ruby binding for vips
|
125
|
+
[here](https://github.com/jcupitt/ruby-vips). It was written by a Ruby
|
126
|
+
expert, it works well, it includes a test-suite, and has pretty full
|
127
|
+
documentation. Why do another?
|
128
|
+
|
129
|
+
ruby-vips is based on the old vips7 API. There's now vips8, which adds several
|
130
|
+
very useful new features:
|
131
|
+
|
132
|
+
* [GObject](https://developer.gnome.org/gobject/stable/)-based API with full
|
133
|
+
introspection. You can discover the vips8 API at runtime. This means that if
|
134
|
+
libvips gets a new operator, any binding that goes via vips8 will
|
135
|
+
get the new thing immediately. With vips7, whenever libvips was changed, all
|
136
|
+
the bindings needed to be changed too.
|
137
|
+
|
138
|
+
* No C required. Thanks to
|
139
|
+
[gobject-introspection](https://wiki.gnome.org/Projects/GObjectIntrospection)
|
140
|
+
you can write the binding in Ruby itself, there's no need for any C. This
|
141
|
+
makes it a lot smaller and more portable.
|
142
|
+
|
143
|
+
* vips7 probably won't get new features. vips7 doesn't really exist any more:
|
144
|
+
the API is still there, but now just a thin compatibility layer over vips8.
|
145
|
+
New features may well not get added to the vips7 API.
|
146
|
+
|
147
|
+
There are some more minor pluses as well:
|
148
|
+
|
149
|
+
* Named and optional arguments. vips8 lets you have optional and required
|
150
|
+
arguments, both input and output, and optional arguments can have default
|
151
|
+
values.
|
152
|
+
|
153
|
+
* Operation cache. vips8 keeps track of the last 1,000 or so operations and
|
154
|
+
will automatically reuse results when it can. This can give a huge speedup
|
155
|
+
in some cases.
|
156
|
+
|
157
|
+
* vips8 is much simpler and more regular. For example,
|
158
|
+
ruby-vips had to work hard to offer a nice loader system, but that's all
|
159
|
+
built into vips8. It can do things like load and save formatted images to
|
160
|
+
and from memory buffers as well, which just wasn't possible before.
|
161
|
+
|
162
|
+
This binding adds some extra useful features over the old `ruby-vips` binding.
|
163
|
+
|
164
|
+
* Full set of arithmetic operator overloads.
|
165
|
+
|
166
|
+
* Automatic constant expansion. You can write things like
|
167
|
+
`image.bandjoin(255)` and the 255 will be automatically expanded to an image
|
168
|
+
and attached as an extra band. You can mix int, float, scalar, vector and
|
169
|
+
image constants freely.
|
170
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
|
6
|
+
begin
|
7
|
+
Bundler.setup(:default, :development)
|
8
|
+
rescue Bundler::BundlerError => e
|
9
|
+
$stderr.puts e.message
|
10
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
11
|
+
exit e.status_code
|
12
|
+
end
|
13
|
+
|
14
|
+
require 'rake'
|
15
|
+
|
16
|
+
require 'jeweler'
|
17
|
+
|
18
|
+
Jeweler::Tasks.new do |gem|
|
19
|
+
# gem is a Gem::Specification... see http://guides.rubygems.org/specification-reference/ for more options
|
20
|
+
gem.name = "ruby-vips8"
|
21
|
+
gem.homepage = "http://github.com/jcupitt/ruby-vips8"
|
22
|
+
gem.license = "MIT"
|
23
|
+
gem.summary = %Q{Ruby extension for the vips8 image processing library.}
|
24
|
+
gem.description = %Q{ruby-vips8 is a ruby extension for vips8. It is extremely fast and it can process huge images without requiring the entire image to be loaded into memory.}
|
25
|
+
gem.email = "jcupitt@gmail.com"
|
26
|
+
gem.authors = ["John Cupitt"]
|
27
|
+
# dependencies defined in Gemfile
|
28
|
+
end
|
29
|
+
Jeweler::RubygemsDotOrgTasks.new
|
30
|
+
|
31
|
+
require 'rspec/core'
|
32
|
+
require 'rspec/core/rake_task'
|
33
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
34
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
35
|
+
end
|
36
|
+
|
37
|
+
task :default => :spec
|
38
|
+
|
39
|
+
require "github/markup"
|
40
|
+
require "redcarpet"
|
41
|
+
require "yard"
|
42
|
+
require "yard/rake/yardoc_task"
|
43
|
+
|
44
|
+
YARD::Rake::YardocTask.new do |yard|
|
45
|
+
end
|
data/TODO
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
- mail about the getpoint unimplemented error
|
2
|
+
|
3
|
+
http://sourceforge.net/p/ruby-gnome2/mailman/ruby-gnome2-devel-en/thread/CAGNS0RuZ5N6bha3M7B0%2BYf2M9-oni44idzZO17mtQiykS%2BmJKQ%40mail.gmail.com/#msg34790843
|
4
|
+
|
5
|
+
- still missing a few enum docs
|
6
|
+
|
7
|
+
- add complex constants, eg.
|
8
|
+
|
9
|
+
Complex(1, 2)
|
10
|
+
=> (1+2i)
|
11
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/example/annotate.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
require 'vips8'
|
4
|
+
|
5
|
+
im = Vips::Image.new_from_file ARGV[0], :access => :sequential
|
6
|
+
|
7
|
+
left_text = Vips::Image.text "left corner", :dpi => 300
|
8
|
+
left = left_text.embed 50, 50, im.width, 150
|
9
|
+
|
10
|
+
right_text = Vips::Image.text "right corner", :dpi => 300
|
11
|
+
right = right_text.embed im.width - right_text.width - 50, 50, im.width, 150
|
12
|
+
|
13
|
+
footer = (left | right).ifthenelse(0, [255, 0, 0], :blend => true)
|
14
|
+
|
15
|
+
im = im.insert footer, 0, im.height, :expand => true
|
16
|
+
|
17
|
+
im.write_to_file ARGV[1]
|
@@ -0,0 +1,75 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
# daltonize an image with ruby-vips8
|
4
|
+
# based on
|
5
|
+
# http://scien.stanford.edu/pages/labsite/2005/psych221/projects/05/ofidaner/colorblindness_project.htm
|
6
|
+
# see
|
7
|
+
# http://libvips.blogspot.co.uk/2013/05/daltonize-in-ruby-vips-carrierwave-and.html
|
8
|
+
# for a discussion of this code
|
9
|
+
|
10
|
+
require 'vips8'
|
11
|
+
|
12
|
+
#Vips.set_debug true
|
13
|
+
|
14
|
+
# matrices to convert D65 XYZ to and from bradford cone space
|
15
|
+
xyz_to_brad = [
|
16
|
+
[0.8951, 0.2664, -0.1614],
|
17
|
+
[-0.7502, 1.7135, 0.0367],
|
18
|
+
[0.0389, -0.0685, 1.0296]
|
19
|
+
]
|
20
|
+
brad_to_xyz = [
|
21
|
+
[0.987, -0.147, 0.16],
|
22
|
+
[0.432, 0.5184, 0.0493],
|
23
|
+
[-0.0085, 0.04, 0.968]
|
24
|
+
]
|
25
|
+
|
26
|
+
im = Vips::Image.new_from_file ARGV[0]
|
27
|
+
|
28
|
+
# remove any alpha channel before processing
|
29
|
+
alpha = nil
|
30
|
+
if im.bands == 4
|
31
|
+
alpha = im[3]
|
32
|
+
im = im.extract_band 0, :n => 3
|
33
|
+
end
|
34
|
+
|
35
|
+
begin
|
36
|
+
# import to XYZ with lcms
|
37
|
+
# if there's no profile there, we'll fall back to the thing below
|
38
|
+
xyz = im.icc_import :embedded => true, :pcs => :xyz
|
39
|
+
rescue Vips::Error
|
40
|
+
# nope .. use the built-in converter instead
|
41
|
+
xyz = im.colourspace :xyz
|
42
|
+
end
|
43
|
+
|
44
|
+
brad = xyz.recomb xyz_to_brad
|
45
|
+
|
46
|
+
# through the Deuteranope matrix
|
47
|
+
# we need rows to sum to 1 in Bradford space --- the matrix in the original
|
48
|
+
# Python code sums to 1.742
|
49
|
+
deut = brad.recomb [
|
50
|
+
[1, 0, 0],
|
51
|
+
[0.7, 0, 0.3],
|
52
|
+
[0, 0, 1]
|
53
|
+
]
|
54
|
+
|
55
|
+
xyz = deut.recomb brad_to_xyz
|
56
|
+
|
57
|
+
# .. and back to sRGB
|
58
|
+
rgb = xyz.colourspace :srgb
|
59
|
+
|
60
|
+
# so this is the colour error
|
61
|
+
err = im - rgb
|
62
|
+
|
63
|
+
# add the error back to other channels to make a compensated image
|
64
|
+
im = im + err.recomb([
|
65
|
+
[0, 0, 0],
|
66
|
+
[0.7, 1, 0],
|
67
|
+
[0.7, 0, 1]
|
68
|
+
])
|
69
|
+
|
70
|
+
# reattach any alpha we saved above
|
71
|
+
if alpha
|
72
|
+
im = im.bandjoin(alpha)
|
73
|
+
end
|
74
|
+
|
75
|
+
im.write_to_file ARGV[1]
|