ruby-vips 0.3.14 → 1.0.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 (97) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +22 -0
  3. data/CHANGELOG.md +4 -0
  4. data/Gemfile +15 -0
  5. data/Gemfile.lock +46 -31
  6. data/{LICENSE → LICENSE.txt} +1 -1
  7. data/README.md +101 -145
  8. data/Rakefile +45 -0
  9. data/TODO +8 -32
  10. data/VERSION +1 -0
  11. data/example/annotate.rb +17 -0
  12. data/example/daltonize8.rb +75 -0
  13. data/example/example1.rb +84 -0
  14. data/example/example2.rb +31 -0
  15. data/example/example3.rb +19 -0
  16. data/example/example4.rb +18 -0
  17. data/example/example5.rb +31 -0
  18. data/example/trim8.rb +41 -0
  19. data/example/watermark.rb +44 -0
  20. data/example/wobble.rb +36 -0
  21. data/lib/vips.rb +151 -14
  22. data/lib/vips/access.rb +14 -0
  23. data/lib/vips/align.rb +11 -0
  24. data/lib/vips/angle.rb +12 -0
  25. data/lib/vips/angle45.rb +16 -0
  26. data/lib/vips/argument.rb +163 -0
  27. data/lib/vips/bandformat.rb +20 -0
  28. data/lib/vips/call.rb +302 -0
  29. data/lib/vips/coding.rb +14 -0
  30. data/lib/vips/demandstyle.rb +35 -0
  31. data/lib/vips/direction.rb +11 -0
  32. data/lib/vips/error.rb +30 -0
  33. data/lib/vips/extend.rb +22 -0
  34. data/lib/vips/foreignflags.rb +20 -0
  35. data/lib/vips/image.rb +1382 -0
  36. data/lib/vips/interpolate.rb +37 -0
  37. data/lib/vips/interpretation.rb +28 -0
  38. data/lib/vips/methods.rb +1807 -0
  39. data/lib/vips/operation.rb +19 -0
  40. data/ruby-vips8.gemspec +112 -0
  41. data/spec/image_spec.rb +515 -0
  42. data/spec/samples/balloon.v +0 -0
  43. data/spec/samples/ghost.ppm +405 -0
  44. data/spec/samples/huge.jpg +0 -0
  45. data/spec/samples/icc.jpg +0 -0
  46. data/spec/samples/lcd.icc +0 -0
  47. data/spec/samples/lion.svg +154 -0
  48. data/spec/samples/sample.csv +7 -0
  49. data/spec/samples/sample.exr +0 -0
  50. data/spec/samples/wagon.jpg +0 -0
  51. data/spec/samples/wagon.v +0 -0
  52. data/spec/spec_helper.rb +49 -0
  53. data/spec/vips_spec.rb +74 -0
  54. metadata +110 -70
  55. data/ext/extconf.rb +0 -31
  56. data/ext/header.c +0 -457
  57. data/ext/header.h +0 -9
  58. data/ext/image.c +0 -629
  59. data/ext/image.h +0 -72
  60. data/ext/image_arithmetic.c +0 -936
  61. data/ext/image_arithmetic.h +0 -38
  62. data/ext/image_boolean.c +0 -301
  63. data/ext/image_boolean.h +0 -8
  64. data/ext/image_colour.c +0 -590
  65. data/ext/image_colour.h +0 -36
  66. data/ext/image_conversion.c +0 -884
  67. data/ext/image_conversion.h +0 -38
  68. data/ext/image_convolution.c +0 -368
  69. data/ext/image_convolution.h +0 -13
  70. data/ext/image_freq_filt.c +0 -740
  71. data/ext/image_freq_filt.h +0 -27
  72. data/ext/image_histograms_lut.c +0 -643
  73. data/ext/image_histograms_lut.h +0 -28
  74. data/ext/image_morphology.c +0 -327
  75. data/ext/image_morphology.h +0 -13
  76. data/ext/image_mosaicing.c +0 -554
  77. data/ext/image_mosaicing.h +0 -15
  78. data/ext/image_relational.c +0 -384
  79. data/ext/image_relational.h +0 -8
  80. data/ext/image_resample.c +0 -249
  81. data/ext/image_resample.h +0 -9
  82. data/ext/interpolator.c +0 -106
  83. data/ext/interpolator.h +0 -7
  84. data/ext/mask.c +0 -347
  85. data/ext/mask.h +0 -18
  86. data/ext/reader.c +0 -261
  87. data/ext/reader.h +0 -2
  88. data/ext/ruby_vips.c +0 -188
  89. data/ext/ruby_vips.h +0 -72
  90. data/ext/tags +0 -450
  91. data/ext/writer.c +0 -371
  92. data/ext/writer.h +0 -2
  93. data/lib/vips/reader.rb +0 -272
  94. data/lib/vips/version.rb +0 -3
  95. data/lib/vips/writer.rb +0 -342
  96. data/ruby-vips.gemspec +0 -100
  97. data/ruby.supp +0 -134
@@ -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-vips"
21
+ gem.homepage = "http://github.com/jcupitt/ruby-vips"
22
+ gem.license = "MIT"
23
+ gem.summary = %Q{Ruby extension for the vips image processing library.}
24
+ gem.description = %Q{ruby-vips is a ruby extension for vips. 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 CHANGED
@@ -1,38 +1,14 @@
1
- - add something to make a memory image, useful in some cases, eg. making very
2
- large image mosaics
1
+ - need something like ruby-vips occasional GC stuff, we can fill memory before
2
+ a GC is triggered
3
3
 
4
- - support vips_resize()
4
+ - mail about the getpoint unimplemented error
5
5
 
6
- - support vips_flatten(), see
6
+ http://sourceforge.net/p/ruby-gnome2/mailman/ruby-gnome2-devel-en/thread/CAGNS0RuZ5N6bha3M7B0%2BYf2M9-oni44idzZO17mtQiykS%2BmJKQ%40mail.gmail.com/#msg34790843
7
7
 
8
- https://github.com/jcupitt/ruby-vips/issues/45
8
+ - still missing a few enum docs
9
9
 
10
+ - add complex constants, eg.
10
11
 
11
- btw, there's a method called to_memory in JPEGWriter and PNGWriter, that works
12
- cool to retrieve the VIPS::Image as a memory buffer, will be cool if this
13
- method is moved up to Writer and then it handles the correct to_memory method
14
- using the image headers.
12
+ Complex(1, 2)
13
+ => (1+2i)
15
14
 
16
- add from_memory? or should the open method accept a blob in place of a path?
17
-
18
-
19
-
20
-
21
- TODO
22
- * Verify that all memory gets released when vips ops return errors. Namely,
23
- make sure that the allocated IMAGEs get released via ruby's free callbacks.
24
- * Allow for injecting ruby code into an image transformation pipeline (may be
25
- slow to call out to ruby with every read, but may be worthwhile for fun custom
26
- image processors).
27
- * Tap into VIPS callback system to allow progress updates, etc.
28
- * Allow for creating a ruby endpoint to the pipeline could be useful for
29
- streaming.
30
- * Image#to_a
31
- * look into other.h, audit all libvips methods and make sure they are all
32
- implemented
33
- * JRuby support
34
- * Optional extensions to core Ruby classes, allowing operations such as
35
- [1, 2, 3] & im . This could be optionally enabled by requiring e.g.
36
- vips/core_ext
37
- * Put groups of image operations into modules, breaking docs into themes and
38
- possibly allowing for selective loading of image ops.
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'vips'
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-vips
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 'vips'
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]
@@ -0,0 +1,84 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'vips'
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 'vips'
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 'vips'
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 'vips'
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 'vips'
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-vips ... 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 'vips'
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 'vips'
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]