image_voodoo 0.8.8 → 0.9.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +4 -0
- data/.rubocop.yml +165 -0
- data/.travis.yml +16 -1
- data/Gemfile +5 -0
- data/Jars.lock +3 -0
- data/Rakefile +14 -4
- data/bin/image_voodoo +73 -84
- data/image_voodoo.gemspec +14 -7
- data/lib/image_science.rb +3 -1
- data/lib/image_voodoo/awt/core_ext/buffered_image.rb +15 -0
- data/lib/image_voodoo/awt/core_ext/graphics2d.rb +15 -0
- data/lib/image_voodoo/awt/shapes.rb +41 -3
- data/lib/image_voodoo/awt.rb +162 -152
- data/lib/image_voodoo/gae.rb +12 -6
- data/lib/image_voodoo/metadata.rb +138 -90
- data/lib/image_voodoo/needs_head.rb +3 -0
- data/lib/image_voodoo/version.rb +3 -1
- data/lib/image_voodoo.rb +47 -96
- data/samples/bench.rb +30 -36
- data/samples/file_greyscale.rb +2 -0
- data/samples/file_thumbnail.rb +2 -0
- data/samples/file_view.rb +4 -1
- data/samples/{in-memory.rb → in_memory.rb} +2 -0
- data/samples/lossy.rb +2 -0
- data/test/test_image_science.rb +34 -74
- data/test/test_image_voodoo.rb +84 -0
- data/test/test_metadata.rb +31 -16
- data/test/test_shapes.rb +23 -0
- data/tools/gen.rb +34 -27
- metadata +87 -10
- data/vendor/metadata-extractor-2.7.0.jar +0 -0
- data/vendor/xmpcore-5.1.2.jar +0 -0
@@ -0,0 +1,84 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test/unit/testcase'
|
4
|
+
require 'test/unit' if $PROGRAM_NAME == __FILE__
|
5
|
+
require 'image_voodoo'
|
6
|
+
|
7
|
+
# Depends on a small portion of awt/shapes working properly
|
8
|
+
class TestImageVoodoo < Test::Unit::TestCase
|
9
|
+
# 04
|
10
|
+
# b8
|
11
|
+
def make_square
|
12
|
+
image = ImageVoodoo.new_image 20, 20, "test.gif"
|
13
|
+
image.square(*upper_left, 10, '000000')
|
14
|
+
image.square(10, 0, 10, '444444')
|
15
|
+
image.square(0, 10, 10, '888888')
|
16
|
+
image.square(*lower_right, 10, 'bb0000')
|
17
|
+
end
|
18
|
+
|
19
|
+
def assert_color(color, red, green, blue, alpha=nil)
|
20
|
+
assert_equal(red, color.red)
|
21
|
+
assert_equal(green, color.green)
|
22
|
+
assert_equal(blue, color.blue)
|
23
|
+
assert_equal(alpha, color.alpha) if alpha
|
24
|
+
end
|
25
|
+
|
26
|
+
def lower_right
|
27
|
+
[10, 10]
|
28
|
+
end
|
29
|
+
|
30
|
+
def upper_left
|
31
|
+
[0, 0]
|
32
|
+
end
|
33
|
+
|
34
|
+
# TODO: Don't fully know how to predict pixel values for adjust_brightness.
|
35
|
+
|
36
|
+
def test_alpha
|
37
|
+
image = make_square.alpha('000000')
|
38
|
+
assert_equal(0xff, image.color_at(*upper_left).alpha)
|
39
|
+
end
|
40
|
+
|
41
|
+
# 04 -> 40
|
42
|
+
# 8b b8
|
43
|
+
def test_flip_horizontally
|
44
|
+
image = make_square.flip_horizontally
|
45
|
+
assert_color(image.color_at(*upper_left), 0x44, 0x44, 0x44)
|
46
|
+
end
|
47
|
+
|
48
|
+
# 04 -> 8b
|
49
|
+
# 8b 04
|
50
|
+
def test_flip_vertically
|
51
|
+
image = make_square.flip_vertically
|
52
|
+
assert_color(image.color_at(*upper_left), 0x88, 0x88, 0x88)
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_greyscale
|
56
|
+
image = make_square.greyscale
|
57
|
+
assert_color(image.color_at(*lower_right), 0x5d, 0x5d, 0x5d)
|
58
|
+
end
|
59
|
+
|
60
|
+
# 04 -0-> 04 -90-> 80 -180-> 4b -270-> b8
|
61
|
+
# 8b 8b b4 08 40
|
62
|
+
def test_rotate
|
63
|
+
image = make_square
|
64
|
+
assert_color(image.color_at(*upper_left), 0x00, 0x00, 0x00)
|
65
|
+
image = image.rotate(90)
|
66
|
+
assert_color(image.color_at(*upper_left), 0x88, 0x88, 0x88)
|
67
|
+
image = image.rotate(180)
|
68
|
+
assert_color(image.color_at(*upper_left), 0x44, 0x44, 0x44)
|
69
|
+
image = image.rotate(270)
|
70
|
+
assert_color(image.color_at(*upper_left), 0xbb, 0x00, 0x00)
|
71
|
+
end
|
72
|
+
|
73
|
+
# 04 -(-90)-> 4b -(-180)-> 80 -(-270)-> b8
|
74
|
+
# 8b 08 b4 40
|
75
|
+
def test_rotate_negative
|
76
|
+
image = make_square
|
77
|
+
image = image.rotate(-90)
|
78
|
+
assert_color(image.color_at(*upper_left), 0x44, 0x44, 0x44)
|
79
|
+
image = image.rotate(-180)
|
80
|
+
assert_color(image.color_at(*upper_left), 0x88, 0x88, 0x88)
|
81
|
+
image = image.rotate(-270)
|
82
|
+
assert_color(image.color_at(*upper_left), 0xbb, 0x00, 0x00)
|
83
|
+
end
|
84
|
+
end
|
data/test/test_metadata.rb
CHANGED
@@ -1,49 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'test/unit/testcase'
|
2
|
-
require 'test/unit' if $
|
4
|
+
require 'test/unit' if $PROGRAM_NAME == __FILE__
|
3
5
|
require 'image_voodoo'
|
4
6
|
|
5
7
|
IMAGE_DIR = File.join File.dirname(__FILE__), '..', '..', 'metadata-extractor-images'
|
6
8
|
|
7
9
|
# FIXME: If we end up running on travis or other tool this should be ignored
|
8
10
|
# subdir to this project and probably clone repo into that subdir
|
9
|
-
|
10
|
-
puts
|
11
|
+
if !File.exist? IMAGE_DIR
|
12
|
+
puts 'To run this test you must clone:'
|
13
|
+
puts 'https://github.com/drewnoakes/metadata-extractor-images.git'
|
14
|
+
puts 'into a sibling directory to image_voodoo'
|
11
15
|
else
|
12
16
|
class TestImageVoodooMetadata < Test::Unit::TestCase
|
13
17
|
def setup
|
14
|
-
@path = File.join IMAGE_DIR,
|
15
|
-
@path_gps = File.join IMAGE_DIR,
|
16
|
-
@path_no_exif = File.join File.dirname(__FILE__),
|
18
|
+
@path = File.join IMAGE_DIR, 'jpg', 'Apple iPhone 4S.jpg'
|
19
|
+
@path_gps = File.join IMAGE_DIR, 'jpg', 'Apple iPhone 4.jpg'
|
20
|
+
@path_no_exif = File.join File.dirname(__FILE__), 'pix.png'
|
21
|
+
end
|
22
|
+
|
23
|
+
def assert_orientation(expected, metadata)
|
24
|
+
assert_equal expected, metadata[:IFD0][:Orientation]
|
17
25
|
end
|
26
|
+
|
18
27
|
def test_metadata_from_file
|
19
28
|
ImageVoodoo.with_image @path do |img|
|
20
|
-
|
21
|
-
|
22
|
-
assert_equal 6,
|
23
|
-
assert_equal 3264,
|
24
|
-
assert_equal 2448,
|
25
|
-
assert_equal
|
26
|
-
assert_equal
|
29
|
+
metadata = img.metadata
|
30
|
+
assert_orientation 6, metadata
|
31
|
+
assert_equal 6, metadata.orientation
|
32
|
+
assert_equal 3264, metadata.width
|
33
|
+
assert_equal 2448, metadata.height
|
34
|
+
assert_equal 'Apple', metadata.make
|
35
|
+
assert_equal 'iPhone 4S', metadata.model
|
27
36
|
end
|
28
37
|
end
|
29
38
|
|
30
39
|
def test_metadata_from_inputstream
|
31
40
|
ImageVoodoo.with_bytes File.read(@path) do |img|
|
32
|
-
|
41
|
+
assert_orientation 6, img.metadata
|
33
42
|
end
|
34
43
|
end
|
35
44
|
|
36
45
|
def test_metadata_no_ifd0
|
37
46
|
ImageVoodoo.with_image @path_no_exif do |img|
|
38
47
|
assert !img.metadata[:IFD0].exists?
|
39
|
-
|
48
|
+
assert_orientation nil, img.metadata
|
40
49
|
end
|
41
50
|
end
|
42
51
|
|
43
52
|
def test_metadata_gps
|
44
53
|
ImageVoodoo.with_image @path_gps do |img|
|
45
54
|
assert img.metadata[:Gps].exists?
|
46
|
-
assert_equal(
|
55
|
+
assert_equal('N', img.metadata[:Gps]['Latitude Ref'])
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_metadata_to_s
|
60
|
+
ImageVoodoo.with_image @path do |img|
|
61
|
+
assert img.metadata.to_s =~ /Make = Apple/
|
47
62
|
end
|
48
63
|
end
|
49
64
|
end
|
data/test/test_shapes.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test/unit/testcase'
|
4
|
+
require 'test/unit' if $PROGRAM_NAME == __FILE__
|
5
|
+
require 'image_voodoo'
|
6
|
+
|
7
|
+
class TestShapes < Test::Unit::TestCase
|
8
|
+
def test_new_image
|
9
|
+
image = ImageVoodoo.new_image 10, 20, "test.gif"
|
10
|
+
assert_equal 10, image.width
|
11
|
+
assert_equal 20, image.height
|
12
|
+
assert_equal "gif", image.format
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_square
|
16
|
+
image = ImageVoodoo.new_image 10, 10, "test.gif"
|
17
|
+
image.square 0, 0, 10, 'ff9900'
|
18
|
+
color = image.color_at(0, 0)
|
19
|
+
assert_equal(0xff, color.red)
|
20
|
+
assert_equal(0x99, color.green)
|
21
|
+
assert_equal(0x00, color.blue)
|
22
|
+
end
|
23
|
+
end
|
data/tools/gen.rb
CHANGED
@@ -1,23 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Used to generate part of metadata.rb. Unfortunately, I am unable to fill
|
2
4
|
# in appropriate access methods so I generate with get_string and then manually
|
3
5
|
# update. In future versions I will just run this twice with old and new src
|
4
6
|
# and manually splice in new data (or fixes).
|
5
|
-
#
|
7
|
+
#
|
6
8
|
# % find ../metadata-extractor/Source/ -name '*Directory.java' | xargs grep TAG_ | grep 'public static final' | ruby tools/gen.rb
|
7
9
|
|
10
|
+
# FIXME: I made style tweaks and removed redundant data manually in generated
|
11
|
+
# source. I should update this tool to do all that.
|
12
|
+
# FIXME: I should add a generated comment in metadata generated file.
|
13
|
+
|
8
14
|
def normalize_directory_name(path)
|
9
|
-
path.
|
15
|
+
path.tr('/', '.')
|
10
16
|
end
|
11
17
|
|
12
18
|
def normalize_tag_name(capname)
|
13
|
-
name = capname.split('_').map
|
19
|
+
name = capname.split('_').map(&:capitalize).join(' ')
|
14
20
|
[name, "TAG_#{capname}"]
|
15
21
|
end
|
16
22
|
|
17
23
|
# 'ExifSubIFDDirectory' => 'Exif Sub IFD0'
|
18
24
|
def humanize_directory_name(s)
|
19
25
|
s = s.gsub('Directory', '')
|
20
|
-
s.split(/([A-Z]+[a-z]+)/).map {|a| a ==
|
26
|
+
s.split(/([A-Z]+[a-z]+)/).map { |a| a == '' ? nil : a }.compact.join(' ')
|
21
27
|
end
|
22
28
|
|
23
29
|
io = $stdin
|
@@ -25,37 +31,38 @@ directories = {}
|
|
25
31
|
|
26
32
|
io.readlines.each do |line|
|
27
33
|
# .../IptcDirectory.java: public static final int TAG_BY_LINE = 80;
|
28
|
-
if %r{Source/[/]?(?<
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
34
|
+
next if %r{Source/[/]?(?<dir_name>.*).java:.*TAG_(?<tag_name>[\S]+)} !~ line
|
35
|
+
|
36
|
+
directory_name = normalize_directory_name dir_name
|
37
|
+
directories[directory_name] ||= []
|
38
|
+
directories[directory_name] << normalize_tag_name(tag_name)
|
33
39
|
end
|
34
40
|
|
35
41
|
directories.each do |directory, tag_names|
|
36
42
|
class_name = directory.split('.')[-1]
|
37
|
-
puts "
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
43
|
+
puts <<"EOS"
|
44
|
+
# GENERATED
|
45
|
+
class #{class_name} < Directory
|
46
|
+
java_import #{directory}
|
47
|
+
|
48
|
+
def self.directory_class
|
49
|
+
#{directory}
|
50
|
+
end"
|
51
|
+
|
52
|
+
TAGS = {
|
53
|
+
EOS
|
45
54
|
tag_names.each do |name, original_name|
|
46
|
-
puts "
|
55
|
+
puts "'#{name}' => ['#{original_name}', :get_string],"
|
47
56
|
end
|
48
|
-
puts
|
49
|
-
|
50
|
-
|
57
|
+
puts <<EOS
|
58
|
+
}.freeze
|
59
|
+
end
|
60
|
+
EOS
|
51
61
|
end
|
52
62
|
|
53
|
-
puts
|
54
|
-
puts "DIRECTORY_MAP = {"
|
63
|
+
puts 'DIRECTORY_MAP = {'
|
55
64
|
directories.each do |directory, _|
|
56
65
|
class_name = directory.split('.')[-1]
|
57
|
-
puts "
|
66
|
+
puts "'#{humanize_directory_name(class_name)}' => #{class_name},"
|
58
67
|
end
|
59
|
-
puts
|
60
|
-
|
61
|
-
|
68
|
+
puts '}.freeze'
|
metadata
CHANGED
@@ -1,15 +1,85 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: image_voodoo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thomas E. Enebo, Charles Nutter, Nick Sieger
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
12
|
-
dependencies:
|
11
|
+
date: 2021-10-12 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - ">="
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: '0'
|
19
|
+
name: jar-dependencies
|
20
|
+
prerelease: false
|
21
|
+
type: :development
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
name: rake
|
34
|
+
prerelease: false
|
35
|
+
type: :development
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
name: rubocop
|
48
|
+
prerelease: false
|
49
|
+
type: :development
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
name: ruby-maven
|
62
|
+
prerelease: false
|
63
|
+
type: :development
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
name: test-unit
|
76
|
+
prerelease: false
|
77
|
+
type: :development
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
13
83
|
description: Image manipulation in JRuby with ImageScience compatible API
|
14
84
|
email: tom.enebo@gmail.com
|
15
85
|
executables:
|
@@ -20,8 +90,11 @@ files:
|
|
20
90
|
- ".gitignore"
|
21
91
|
- ".hgignore"
|
22
92
|
- ".hgtags"
|
93
|
+
- ".rubocop.yml"
|
23
94
|
- ".travis.yml"
|
95
|
+
- Gemfile
|
24
96
|
- History.txt
|
97
|
+
- Jars.lock
|
25
98
|
- LICENSE-2.0.txt
|
26
99
|
- LICENSE.txt
|
27
100
|
- Manifest.txt
|
@@ -33,25 +106,28 @@ files:
|
|
33
106
|
- lib/image_science.rb
|
34
107
|
- lib/image_voodoo.rb
|
35
108
|
- lib/image_voodoo/awt.rb
|
109
|
+
- lib/image_voodoo/awt/core_ext/buffered_image.rb
|
110
|
+
- lib/image_voodoo/awt/core_ext/graphics2d.rb
|
36
111
|
- lib/image_voodoo/awt/shapes.rb
|
37
112
|
- lib/image_voodoo/gae.rb
|
38
113
|
- lib/image_voodoo/metadata.rb
|
114
|
+
- lib/image_voodoo/needs_head.rb
|
39
115
|
- lib/image_voodoo/version.rb
|
40
116
|
- samples/bench.rb
|
41
117
|
- samples/checkerboard.jpg
|
42
118
|
- samples/file_greyscale.rb
|
43
119
|
- samples/file_thumbnail.rb
|
44
120
|
- samples/file_view.rb
|
45
|
-
- samples/
|
121
|
+
- samples/in_memory.rb
|
46
122
|
- samples/lossy.rb
|
47
123
|
- test/pix.png
|
48
124
|
- test/pix_cmyk.jpg
|
49
125
|
- test/test_image_science.rb
|
126
|
+
- test/test_image_voodoo.rb
|
50
127
|
- test/test_metadata.rb
|
128
|
+
- test/test_shapes.rb
|
51
129
|
- tools/gen.rb
|
52
130
|
- vendor/CMYKDemo.jar
|
53
|
-
- vendor/metadata-extractor-2.7.0.jar
|
54
|
-
- vendor/xmpcore-5.1.2.jar
|
55
131
|
homepage: http://github.com/jruby/image_voodoo
|
56
132
|
licenses: []
|
57
133
|
metadata: {}
|
@@ -70,9 +146,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
70
146
|
- - ">="
|
71
147
|
- !ruby/object:Gem::Version
|
72
148
|
version: '0'
|
73
|
-
requirements:
|
74
|
-
|
75
|
-
rubygems_version: 2.
|
149
|
+
requirements:
|
150
|
+
- jar com.drewnoakes, metadata-extractor, 2.11.0
|
151
|
+
rubygems_version: 3.2.14
|
76
152
|
signing_key:
|
77
153
|
specification_version: 4
|
78
154
|
summary: Image manipulation in JRuby with ImageScience compatible API
|
@@ -80,5 +156,6 @@ test_files:
|
|
80
156
|
- test/pix.png
|
81
157
|
- test/pix_cmyk.jpg
|
82
158
|
- test/test_image_science.rb
|
159
|
+
- test/test_image_voodoo.rb
|
83
160
|
- test/test_metadata.rb
|
84
|
-
|
161
|
+
- test/test_shapes.rb
|
Binary file
|
data/vendor/xmpcore-5.1.2.jar
DELETED
Binary file
|