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.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +1 -0
  3. data/.yardopts +10 -0
  4. data/CHANGELOG.md +5 -0
  5. data/Gemfile +15 -0
  6. data/Gemfile.lock +84 -0
  7. data/LICENSE.txt +20 -0
  8. data/README.md +170 -0
  9. data/Rakefile +45 -0
  10. data/TODO +11 -0
  11. data/VERSION +1 -0
  12. data/example/annotate.rb +17 -0
  13. data/example/daltonize8.rb +75 -0
  14. data/example/example1.rb +84 -0
  15. data/example/example2.rb +31 -0
  16. data/example/example3.rb +19 -0
  17. data/example/example4.rb +18 -0
  18. data/example/example5.rb +31 -0
  19. data/example/trim8.rb +41 -0
  20. data/example/watermark.rb +44 -0
  21. data/example/wobble.rb +36 -0
  22. data/lib/vips8.rb +153 -0
  23. data/lib/vips8/access.rb +14 -0
  24. data/lib/vips8/align.rb +11 -0
  25. data/lib/vips8/angle.rb +12 -0
  26. data/lib/vips8/angle45.rb +16 -0
  27. data/lib/vips8/argument.rb +163 -0
  28. data/lib/vips8/bandformat.rb +20 -0
  29. data/lib/vips8/call.rb +302 -0
  30. data/lib/vips8/coding.rb +14 -0
  31. data/lib/vips8/demandstyle.rb +35 -0
  32. data/lib/vips8/direction.rb +11 -0
  33. data/lib/vips8/error.rb +30 -0
  34. data/lib/vips8/extend.rb +22 -0
  35. data/lib/vips8/foreignflags.rb +20 -0
  36. data/lib/vips8/image.rb +1383 -0
  37. data/lib/vips8/interpolate.rb +37 -0
  38. data/lib/vips8/interpretation.rb +28 -0
  39. data/lib/vips8/methods.rb +1807 -0
  40. data/lib/vips8/operation.rb +19 -0
  41. data/ruby-vips8.gemspec +112 -0
  42. data/spec/image_spec.rb +515 -0
  43. data/spec/samples/balloon.v +0 -0
  44. data/spec/samples/ghost.ppm +405 -0
  45. data/spec/samples/huge.jpg +0 -0
  46. data/spec/samples/icc.jpg +0 -0
  47. data/spec/samples/lcd.icc +0 -0
  48. data/spec/samples/lion.svg +154 -0
  49. data/spec/samples/sample.csv +7 -0
  50. data/spec/samples/sample.exr +0 -0
  51. data/spec/samples/wagon.jpg +0 -0
  52. data/spec/samples/wagon.v +0 -0
  53. data/spec/spec_helper.rb +49 -0
  54. data/spec/vips_spec.rb +74 -0
  55. metadata +198 -0
@@ -0,0 +1,84 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'vips8'
4
+ $vips_debug = true
5
+
6
+ puts ""
7
+ puts "starting up:"
8
+
9
+ # this makes vips keep a list of all active objects which we can print out
10
+ Vips::leak_set true
11
+
12
+ # disable the operation cache
13
+ Vips::cache_set_max 0
14
+
15
+ puts ""
16
+ puts "creating object:"
17
+ x = Vips::Image.new
18
+ Vips::Object::print_all
19
+
20
+ puts ""
21
+ puts "freeing object:"
22
+ x = nil
23
+ GC.start
24
+ Vips::Object::print_all
25
+
26
+ puts ""
27
+ puts "creating operation:"
28
+ op = Vips::Operation.new "black"
29
+ Vips::Object::print_all
30
+ op.set_property "width", 200
31
+ op.set_property "height", 300
32
+
33
+ puts ""
34
+ puts "after operation init:"
35
+ GC.start
36
+ Vips::Object::print_all
37
+
38
+ puts ""
39
+ puts "operation lookup:"
40
+ op2 = Vips::cache_operation_lookup op
41
+ if op2
42
+ puts "cache hit"
43
+ op = op2
44
+ op2 = nil
45
+ else
46
+ puts "cache miss ... building"
47
+ if not op.build
48
+ puts "*** build error"
49
+ end
50
+ Vips::cache_operation_add op
51
+ end
52
+
53
+ puts ""
54
+ puts "after build:"
55
+ GC.start
56
+ Vips::Object::print_all
57
+
58
+ puts ""
59
+ puts "fetching output:"
60
+ im = op.get_property "out"
61
+ GC.start
62
+ Vips::Object::print_all
63
+
64
+ puts ""
65
+ puts "fetching output again:"
66
+ im2 = op.get_property "out"
67
+ GC.start
68
+ Vips::Object::print_all
69
+
70
+ puts ""
71
+ puts "freeing operation:"
72
+ op.unref_outputs
73
+ op = nil
74
+ op2 = nil
75
+ GC.start
76
+ Vips::Object::print_all
77
+
78
+ puts ""
79
+ puts "shutting down:"
80
+ im = nil
81
+ im2 = nil
82
+ GC.start
83
+ Vips::shutdown
84
+ GC.start
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'vips8'
4
+
5
+ puts ""
6
+ puts "starting up:"
7
+
8
+ # this makes vips keep a list of all active objects which we can print out
9
+ Vips::leak_set true
10
+
11
+ # disable the operation cache
12
+ Vips::cache_set_max 0
13
+
14
+ n = 100
15
+
16
+ n.times do |i|
17
+ puts ""
18
+ puts "call #{i} ..."
19
+ out = Vips::call "black", 200, 300
20
+ if out.width != 200 or out.height != 300
21
+ puts "bad image result from black"
22
+ end
23
+ end
24
+
25
+ puts ""
26
+ puts "after #{n} calls:"
27
+ GC.start
28
+ Vips::Object::print_all
29
+
30
+ puts ""
31
+ puts "shutting down:"
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'vips8'
4
+
5
+ # this makes vips keep a list of all active objects
6
+ # Vips::leak_set true
7
+
8
+ # disable the operation cache
9
+ # Vips::cache_set_max 0
10
+
11
+ # turn on debug logging
12
+ #Vips.set_debug true
13
+
14
+ 10000.times do |i|
15
+ puts "loop #{i} ..."
16
+ im = Vips::Image.new_from_file ARGV[0]
17
+ im = im.embed 100, 100, 3000, 3000, :extend => :mirror
18
+ im.write_to_file "x.v"
19
+ end
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'vips8'
4
+
5
+ # this makes vips keep a list of all active objects
6
+ Vips::leak_set true
7
+
8
+ # disable the operation cache
9
+ #Vips::cache_set_max 0
10
+
11
+ # turn on debug logging
12
+ #Vips.set_debug true
13
+
14
+ ARGV.each do |filename|
15
+ im = Vips::Image.new_from_file filename
16
+ profile = im.get_value "icc-profile-data"
17
+ puts "profile has #{profile.length} bytes"
18
+ end
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'vips8'
4
+
5
+ # this makes vips keep a list of all active objects
6
+ # Vips::leak_set true
7
+
8
+ # disable the operation cache
9
+ # Vips::cache_set_max 0
10
+
11
+ # turn on debug logging
12
+ #Vips.set_debug true
13
+
14
+ if ARGV.length < 2
15
+ raise "usage: #{$PROGRAM_NAME}: input-file output-file"
16
+ end
17
+
18
+ im = Vips::Image.new_from_file ARGV[0], :access => :sequential
19
+
20
+ im *= [1, 2, 1]
21
+
22
+ # we want to be able to specify a scale for the convolution mask, so we have to
23
+ # make it ourselves
24
+ # if you are OK with scale=1, you can just pass the array directly to .conv()
25
+ mask = Vips::Image.new_from_array [
26
+ [-1, -1, -1],
27
+ [-1, 16, -1],
28
+ [-1, -1, -1]], 8
29
+ im = im.conv mask
30
+
31
+ im.write_to_file ARGV[1]
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/ruby
2
+
3
+ # An equivalent of ImageMagick's -trim in ruby-vips8 ... automatically remove
4
+ # "boring" image edges.
5
+
6
+ # We use .project to sum the rows and columns of a 0/255 mask image, the first
7
+ # non-zero row or column is the object edge. We make the mask image with an
8
+ # amount-different-from-background image plus a threshold.
9
+
10
+ require 'vips8'
11
+
12
+ im = Vips::Image.new_from_file ARGV[0]
13
+
14
+ # find the value of the pixel at (0, 0) ... we will search for all pixels
15
+ # significantly different from this
16
+ background = im.getpoint(0, 0)
17
+
18
+ # we need to smooth the image, subtract the background from every pixel, take
19
+ # the absolute value of the difference, then threshold
20
+ mask = (im.median - background).abs > 10
21
+
22
+ # sum mask rows and columns, then search for the first non-zero sum in each
23
+ # direction
24
+ columns, rows = mask.project
25
+
26
+ first_column, first_row = columns.profile
27
+ left = first_row.min
28
+
29
+ first_column, first_row = columns.fliphor.profile
30
+ right = columns.width - first_row.min
31
+
32
+ first_column, first_row = rows.profile
33
+ top = first_column.min
34
+
35
+ first_column, first_row = rows.flipver.profile
36
+ bottom = rows.height - first_column.min
37
+
38
+ # and now crop the original image
39
+ im = im.crop left, top, right - left, bottom - top
40
+
41
+ im.write_to_file ARGV[1]
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'vips8'
4
+
5
+ im = Vips::Image.new_from_file ARGV[0], :access => :sequential
6
+
7
+ text = Vips::Image.text ARGV[2], :width => 500, :dpi => 300
8
+ text = (text * 0.3).cast(:uchar)
9
+ text = text.embed 100, 100, text.width + 200, text.width + 200
10
+ text = text.replicate 1 + im.width / text.width, 1 + im.height / text.height
11
+ text = text.crop 0, 0, im.width, im.height
12
+
13
+ # we want to blend into the visible part of the image and leave any alpha
14
+ # channels untouched ... we need to split im into two parts
15
+
16
+ # guess how many bands from the start of im contain visible colour information
17
+ if im.bands >= 4 and im.interpretation == :cmyk
18
+ # cmyk image
19
+ n_visible_bands = 4
20
+ text_colour = [0, 255, 0, 0]
21
+ elsif im.bands >= 3
22
+ # rgb image
23
+ n_visible_bands = 3
24
+ text_colour = [255, 0, 0]
25
+ else
26
+ # mono image
27
+ n_visible_bands = 1
28
+ text_colour = 255
29
+ end
30
+
31
+ # split into image and alpha
32
+ if im.bands - n_visible_bands > 0
33
+ alpha = im.extract_band n_visible_bands, :n => im.bands - n_visible_bands
34
+ im = im.extract_band 0, :n => n_visible_bands
35
+ else
36
+ alpha = nil
37
+ end
38
+
39
+ marked = text.ifthenelse text_colour, im, :blend => true
40
+
41
+ # reattach alpha
42
+ marked = marked.bandjoin alpha if alpha
43
+
44
+ marked.write_to_file ARGV[1]
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'vips8'
4
+
5
+ image = Vips::Image.new_from_file ARGV[0]
6
+
7
+ module Vips
8
+ class Image
9
+ def wobble
10
+ # this makes an image where pixel (0, 0) (at the top-left) has
11
+ # value [0, 0], and pixel (image.width, image.height) at the
12
+ # bottom-right has value [image.width, image.height]
13
+ index = Vips::Image.xyz width, height
14
+
15
+ # make a version with (0, 0) at the centre, negative values up
16
+ # and left, positive down and right
17
+ centre = index - [width / 2, height / 2]
18
+
19
+ # to polar space, so each pixel is now distance and angle in degrees
20
+ polar = centre.polar
21
+
22
+ # scale sin(distance) by 1/distance to make a wavey pattern
23
+ d = ((polar[0] * 3).sin * 10000) / (polar[0] + 1)
24
+
25
+ # and back to rectangular coordinates again to make a set of
26
+ # vectors we can apply to the original index image
27
+ index += d.bandjoin(polar[1]).rect
28
+
29
+ # finally, use our modified index image to distort!
30
+ mapim index
31
+ end
32
+ end
33
+ end
34
+
35
+ image = image.wobble
36
+ image.write_to_file ARGV[1]
@@ -0,0 +1,153 @@
1
+ # This module provides a set of overrides for the vips image processing library
2
+ # used via the gobject-introspection gem.
3
+ #
4
+ # Author:: John Cupitt (mailto:jcupitt@gmail.com)
5
+ # License:: MIT
6
+
7
+ # @private
8
+ def log str
9
+ if $vips_debug
10
+ puts str
11
+ end
12
+ end
13
+
14
+ # copied from ruby-gnome2/gstreamer/lib/gst.rb without much understanding
15
+
16
+ require 'pathname'
17
+ require 'gobject-introspection'
18
+
19
+ # pick up a local girepository/lib in preference to the system one
20
+ base_dir = Pathname.new(__FILE__).dirname.dirname.expand_path
21
+ vendor_dir = base_dir + "vendor" + "local"
22
+ vendor_bin_dir = vendor_dir + "bin"
23
+ GLib.prepend_dll_path(vendor_bin_dir)
24
+ vendor_girepository_dir = vendor_dir + "lib" + "girepository-1.0"
25
+ GObjectIntrospection.prepend_typelib_path(vendor_girepository_dir)
26
+
27
+ module Vips
28
+ # @private
29
+ LOG_DOMAIN = "VIPS"
30
+ GLib::Log.set_log_domain(LOG_DOMAIN)
31
+
32
+ # about as crude as you could get
33
+ $vips_debug = false
34
+
35
+ # Turn debug logging on and off.
36
+ #
37
+ # @param dbg [Boolean] Set true to print debug log messages
38
+ def self.set_debug dbg
39
+ $vips_debug = dbg
40
+ end
41
+
42
+ class << self
43
+ # @private
44
+ def const_missing(name)
45
+ log "Vips::const_missing: #{name}"
46
+
47
+ init()
48
+ if const_defined?(name)
49
+ const_get(name)
50
+ else
51
+ super
52
+ end
53
+ end
54
+
55
+ # @private
56
+ def method_missing(name, *args, &block)
57
+ log "Vips::method_missing: #{name}, #{args}, #{block}"
58
+
59
+ init()
60
+ if respond_to?(name)
61
+ __send__(name, *args, &block)
62
+ else
63
+ super
64
+ end
65
+ end
66
+
67
+ # @private
68
+ def init(*argv)
69
+ log "Vips::init: #{argv}"
70
+
71
+ class << self
72
+ remove_method(:init)
73
+ remove_method(:const_missing)
74
+ remove_method(:method_missing)
75
+ end
76
+
77
+ loader = Loader.new(self, argv)
78
+ begin
79
+ loader.load("Vips")
80
+ rescue
81
+ puts "Unable to load Vips"
82
+ puts " Check that the vips library has been installed and is"
83
+ puts " on your library path."
84
+ puts " Check that the typelib `Vips-8.0.typelib` has been "
85
+ puts " installed, and that it is on your GI_TYPELIB_PATH."
86
+ raise
87
+ end
88
+
89
+ require 'vips8/error'
90
+ require 'vips8/argument'
91
+ require 'vips8/operation'
92
+ require 'vips8/call'
93
+ require 'vips8/image'
94
+ end
95
+ end
96
+
97
+ # @private
98
+ class Loader < GObjectIntrospection::Loader
99
+ def initialize(base_module, init_arguments)
100
+ log "Vips::Loader.initialize: #{base_module}, #{init_arguments}"
101
+
102
+ super(base_module)
103
+ @init_arguments = init_arguments
104
+ end
105
+
106
+ private
107
+ def pre_load(repository, namespace)
108
+ log "Vips::Loader.pre_load: #{repository}, #{namespace}"
109
+
110
+ call_init_function(repository, namespace)
111
+ define_value_modules
112
+ end
113
+
114
+ def call_init_function(repository, namespace)
115
+ log "Vips::Loader.call_init_function: #{repository}, #{namespace}"
116
+
117
+ # call Vips::init
118
+ init = repository.find(namespace, "init")
119
+ succeeded, argv, error = init.invoke(:arguments => [$PROGRAM_NAME])
120
+
121
+ # TODO get the vips error buffer
122
+ raise error unless succeeded
123
+ end
124
+
125
+ def define_value_modules
126
+ @value_functions_module = Module.new
127
+ @value_methods_module = Module.new
128
+ @base_module.const_set("ValueFunctions", @value_functions_module)
129
+ @base_module.const_set("ValueMethods", @value_methods_module)
130
+ end
131
+
132
+ def post_load(repository, namespace)
133
+ log "Vips::Loader.post_load:"
134
+ end
135
+
136
+ end
137
+ end
138
+
139
+ at_exit {
140
+ Vips::shutdown if Vips.respond_to? :shutdown
141
+ }
142
+
143
+ # this makes vips keep a list of all active objects which we can print out
144
+ Vips::leak_set true if $vips_debug
145
+
146
+ # @private
147
+ def showall
148
+ if $vips_debug
149
+ GC.start
150
+ Vips::Object::print_all
151
+ end
152
+ end
153
+