ruby-vips8 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
+