imogen 0.3.0 → 0.3.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '09124ca98f369b44498c5605caa4f45dd5d8225b3416fb2bc4d90e7224a0fda2'
4
- data.tar.gz: e7e7b386740002d47365e5e1f1838c9328184982bcd90ca081405bf7f615bc6d
3
+ metadata.gz: cbcea943f658496d2794d4def050cc0ec3bac40ce2912586ab62e1152656fe50
4
+ data.tar.gz: 1b69768da2f5229e1cf18025030d05eee77f81e8c185f40f60ede9bc287bc346
5
5
  SHA512:
6
- metadata.gz: fddb3b745f8cca9c19e13e58f8d70f520e02a7319f4a46a4191497e47f70f1c5216ce500fe8e95a93b64207a83f1aaa15a889b67a0da507396143fef5aafef4f
7
- data.tar.gz: 67be3ab83b6823be1b662896085cc896a42c104bd99ea17d0f861dc1f1c1aa538e951fbc6f2aa2f2e13cbcc318d9defc2174bd8abae72d286b24b01261efb82f
6
+ metadata.gz: 6dcee0b0c7e0eb873f37487d07aac005e2cf3f6cd532c7e1094b2a3d360d2f51642bcd48378f32b14270fc7af1b722ada6f12e5c7bcfd5c96b236cc1f60c7b83
7
+ data.tar.gz: '094cbbd705e9d2bc7a88245e254c6de70788a4d6f5f23c814ce1d52bf6ec55c186d84948fb12233605490034eff119aa10bcf458219d4d8bf44d4e16e760e852'
data/lib/imogen/iiif.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module Imogen
2
2
  module Iiif
3
- class BadRequest < Exception; end
3
+ class BadRequest < StandardError; end
4
4
  class Transform
5
5
  def initialize(src)
6
6
  @width = 0
data/lib/imogen.rb CHANGED
@@ -1,6 +1,16 @@
1
1
  # encoding: UTF-8
2
2
  require 'vips'
3
+ require 'ffi'
4
+
3
5
  module Imogen
6
+ extend FFI::Library
7
+
8
+ # Note: library_name function comes from `require 'vips'`
9
+ ffi_lib library_name("vips", 42)
10
+
11
+ attach_function :vips_cache_get_max_mem, [], :int
12
+ attach_function :vips_cache_set_max_mem, [:int], :void
13
+ attach_function :vips_tracked_get_mem, [], :int
4
14
 
5
15
  def self.from(src_path)
6
16
  yield Vips::Image.matload(src_path)
@@ -26,10 +36,36 @@ module Imogen
26
36
  raise "format from path not implemented"
27
37
  end
28
38
 
29
- def self.image(src_path, flags=0)
39
+ # @param [String] src_path The local file path to the image.
40
+ # @param [Hash] opts The options to use when opening an image.
41
+ # @option opts [Boolean] :nocache When true, will clear the Vips cache before opening the image.
42
+ def self.image(src_path, opts = {})
43
+ # TODO: Change to `new_from_file(src_path, {nocache: nocache})`, or something similar,
44
+ # when these two GitHub issues are addressed:
45
+ # 1) https://github.com/libvips/ruby-vips/issues/360
46
+ # 2) https://github.com/libvips/libvips/pull/3370
47
+ clear_vips_cache_mem if opts[:nocache] == true
30
48
  Vips::Image.new_from_file(src_path)
31
49
  end
32
- def self.with_image(src_path, flags = 0, &block)
33
- block.yield(image(src_path, flags))
50
+
51
+ # @param [String] src_path The local file path to the image.
52
+ # @param [Hash] opts The options to use when opening an image.
53
+ # @option opts [Boolean] :nocache When true, will clear the Vips cache before opening the image.
54
+ def self.with_image(src_path, opts = {}, &block)
55
+ block.yield(image(src_path, opts))
56
+ end
57
+
58
+ # TODO: The clear_vips_cache_mem method can be removed once these two tickets are addressed:
59
+ # 1) https://github.com/libvips/ruby-vips/issues/360
60
+ # 2) https://github.com/libvips/libvips/pull/3370
61
+ def self.clear_vips_cache_mem
62
+ # store original max because we'll restore it later
63
+ original_max_value = vips_cache_get_max_mem
64
+
65
+ # Drop max mem to 0, which also internally triggers a trim operation that clears out old cache entries
66
+ vips_cache_set_max_mem(0)
67
+
68
+ # Restore original value to support future caching operations
69
+ vips_cache_set_max_mem(original_max_value)
34
70
  end
35
71
  end
@@ -0,0 +1,25 @@
1
+ require 'imogen'
2
+ require 'tmpdir'
3
+
4
+ describe Imogen, vips: true do
5
+ describe ".with_image" do
6
+ it 'should call clear_vips_cache_mem when nocache option is provided' do
7
+ expect(Vips::Image).to receive(:new_from_file)
8
+ expect(Imogen).to receive(:clear_vips_cache_mem)
9
+ Imogen.with_image(fixture('sample.jpg').path, nocache: true) do |img|
10
+ # don't need to do anything with the image for this test
11
+ end
12
+ end
13
+
14
+ it 'should not call clear_vips_cache_mem when nocache option is not provided, or is false' do
15
+ expect(Vips::Image).to receive(:new_from_file).twice
16
+ expect(Imogen).not_to receive(:clear_vips_cache_mem)
17
+ Imogen.with_image(fixture('sample.jpg').path, nocache: false) do |img|
18
+ # don't need to do anything with the image for this test
19
+ end
20
+ Imogen.with_image(fixture('sample.jpg').path) do |img|
21
+ # don't need to do anything with the image for this test
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,62 @@
1
+ require 'imogen'
2
+ require 'tmpdir'
3
+
4
+ describe 'Transparent image conversion', vips: true do
5
+ let(:output_file) { Dir.tmpdir + '/test-imogen-convert.jpg' }
6
+ let(:vips_image_double) do
7
+ dbl = double(Vips::Image)
8
+ allow(dbl).to receive(:height).and_return(1080)
9
+ allow(dbl).to receive(:width).and_return(1920)
10
+ dbl
11
+ end
12
+
13
+ describe 'Imogen::Iiif.convert' do
14
+ it "should convert transparent pixels to white pixels when converting to a raster type that does not support transparency" do
15
+ Imogen.with_image(fixture('sample-with-transparency.png').path) do |img|
16
+ expect(img.getpoint(0, 0)).to eq([255, 255, 255, 0.0])
17
+ Imogen::Iiif.convert(img, output_file, 'jpg', region: 'full', size: 'full', quality: 'color', rotation: '0')
18
+ end
19
+
20
+ Imogen.with_image(output_file) do |img|
21
+ expect(img.getpoint(0, 0)).to eq([255, 255, 255])
22
+ end
23
+ ensure
24
+ File.delete(output_file) if File.exist?(output_file)
25
+ end
26
+
27
+ it "should pass the expected background parameter when calling write_to_file" do
28
+ expect(Imogen).to receive(:with_image).and_yield(vips_image_double)
29
+ expect(vips_image_double).to receive(:write_to_file).with(String, {background: [255, 255, 255]})
30
+ Imogen.with_image(fixture('sample.jpg').path) do |img|
31
+ Imogen::Iiif.convert(img, output_file, 'jpg', region: 'full', size: 'full', quality: 'color', rotation: '0')
32
+ end
33
+ end
34
+ end
35
+
36
+ describe 'Imogen::AutoCrop.convert' do
37
+ # Note: The test below is reliable because the input image is square, but it might fail if the
38
+ # fixture image is ever changed, since a non-square image may have an unpredictable
39
+ # auto-detected, featured, square region. This is fine though, since in this case we're only
40
+ # testing transparent pixel conversion and not testing cropping behavior.
41
+ it "should convert transparent pixels to white pixels when converting to a raster type that does not support transparency" do
42
+ Imogen.with_image(fixture('sample-with-transparency.png').path) do |img|
43
+ expect(img.getpoint(0, 0)).to eq([255, 255, 255, 0.0])
44
+ Imogen::AutoCrop.convert(img, output_file, 500)
45
+ end
46
+
47
+ Imogen.with_image(output_file) do |img|
48
+ expect(img.getpoint(0, 0)).to eq([255, 255, 255])
49
+ end
50
+ ensure
51
+ File.delete(output_file) if File.exist?(output_file)
52
+ end
53
+
54
+ it "should pass the expected background parameter when calling write_to_file" do
55
+ allow(Imogen::Iiif::Region::Featured).to receive(:convert).and_yield(vips_image_double)
56
+ expect(vips_image_double).to receive(:write_to_file).with(String, {background: [255, 255, 255]})
57
+ Imogen.with_image(fixture('sample.jpg').path) do |img|
58
+ Imogen::AutoCrop.convert(img, output_file, 500)
59
+ end
60
+ end
61
+ end
62
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: imogen
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Armintor
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2022-12-09 00:00:00.000000000 Z
12
+ date: 2023-09-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ruby-vips
@@ -45,14 +45,14 @@ dependencies:
45
45
  requirements:
46
46
  - - "~>"
47
47
  - !ruby/object:Gem::Version
48
- version: '3.9'
48
+ version: '3.12'
49
49
  type: :development
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
53
  - - "~>"
54
54
  - !ruby/object:Gem::Version
55
- version: '3.9'
55
+ version: '3.12'
56
56
  description:
57
57
  email: armintor@gmail.com
58
58
  executables: []
@@ -69,9 +69,12 @@ files:
69
69
  - lib/imogen/iiif/tiles.rb
70
70
  - lib/imogen/zoomable.rb
71
71
  - lib/imogencv.bundle
72
+ - spec/fixtures/files/sample-with-transparency.png
72
73
  - spec/fixtures/files/sample.jpg
73
74
  - spec/integration/imogen_autocrop_spec.rb
74
75
  - spec/integration/imogen_iiif_spec.rb
76
+ - spec/integration/imogen_spec.rb
77
+ - spec/integration/transparent_image_conversion_spec.rb
75
78
  - spec/spec_helper.rb
76
79
  - spec/unit/imogen_iiif_quality_spec.rb
77
80
  - spec/unit/imogen_iiif_region_spec.rb
@@ -96,7 +99,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
96
99
  - !ruby/object:Gem::Version
97
100
  version: '0'
98
101
  requirements: []
99
- rubygems_version: 3.1.6
102
+ rubygems_version: 3.2.32
100
103
  signing_key:
101
104
  specification_version: 4
102
105
  summary: IIIF image derivative generation helpers for Vips