image_voodoo 0.8.8 → 0.9.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
- SHA1:
3
- metadata.gz: 10db8a256e32e37a28b94c9246049f7029484a49
4
- data.tar.gz: 27ec82a19aff0bc3171a2c0bff8338c1c7ef19e6
2
+ SHA256:
3
+ metadata.gz: 432be5fdc3ce35d25ccec454aec40066f07f512fdf0d45891ecc49ff28e48368
4
+ data.tar.gz: cacc16a2c686344983bab91d9467ff8a80957f22db50ab037f54553bd1004823
5
5
  SHA512:
6
- metadata.gz: 9bf960b9cd108f06ea22ba69a5f01f7d5ee3ca10dec63fe7a79cf6d2fe986f9a6753ef1969c8eabfa95af8509e0b19211b6ea7c0718d6106c42d998e255e6e36
7
- data.tar.gz: 27e8b1a524c25f7a72b3b15c3a9e37e4bf983111410a8be64d78b45c55ce133ed185ec5cf47ab527b565828d106515fdf053ccc41ee0298b1b1b6df75fc923f3
6
+ metadata.gz: 421f317327a6d6ecb7c799cd1d4bee0a8a0193ce5f9395c55c2b642387d4fb8b6f62533255b565a5698d379c5ac91d19b0c0fc9fa7776116efee90c537ecf7dd
7
+ data.tar.gz: 2fe8bfed88aaa7645ed9eb240a652a0c47c095e72043f62dddfe5effcf415c3d833a2b5f6991ad852bb9a9bd06e4bd3363742807229c7efb0b227ab0b1d123af
data/.gitignore CHANGED
@@ -1,2 +1,6 @@
1
1
  /pkg
2
2
  *~
3
+ Gemfile.lock
4
+ lib/image_voodoo_jars.rb
5
+ lib/com
6
+ .idea
data/.rubocop.yml ADDED
@@ -0,0 +1,165 @@
1
+ # Experiment to tweak source based on what rubocop wanted me to. I basically
2
+ # gave up and made the following exceptions. Personally, I find the tool did
3
+ # find many interesting/questionable code Qs in the project but it is soooo
4
+ # opinionated in pretty unimportant ways (like who cares how I write my
5
+ # comments, or why can't I use kind_of? or why give me a fail for a less
6
+ # readable but more performant pattern).
7
+ #
8
+ # I can obviously tweak rules (like below) but I keep hearing of people pulling
9
+ # their hair out over all the unimportant rules; I question why this project is
10
+ # "all-in" on it's rules versus leaving most of the style rules as some preset
11
+ # profiles people can opt in to.
12
+ #
13
+ # So I am committing this and I will try and run this every now and then to
14
+ # see what it thinks about what I wrote but you will not see this as a
15
+ # requirement for commits since I think by the time I configured it to my
16
+ # liking I could have finished implementing this library. Perhaps if I
17
+ # continue using this here and there I will end up with a profile I find
18
+ # acceptable? I did find value but all the piddly shit just made me angry.
19
+ # I will reflect on it some more...
20
+
21
+ # This is a Java AWT call. It is not what the tool thinks it is...which
22
+ # might be an issue for users interacting with Java from JRuby.
23
+ Lint/UselessSetterCall:
24
+ Exclude:
25
+ - 'lib/image_voodoo/awt.rb'
26
+
27
+ # This is just impossible for them to call properly. I am doing something
28
+ # like rotate_impl and it is a bunch of reasonably simple math. If you look
29
+ # for this transformation in a text book it will look like this code. Putting
30
+ # a bunch of math within different methods would get the score down but
31
+ # it would not help readability. (addendum: I did try and break it apart more
32
+ # and never reached 15 but got closer. I felt this rule is neat but the
33
+ # score really depends on what it is.
34
+ Metrics/AbcSize:
35
+ Max: 16.5
36
+
37
+ # This is triggered for correct_orientation_impl. I could put these transforms
38
+ # in a table and then execute lambdas for each orientation but this is much
39
+ # more clear.
40
+ Metrics/CyclomaticComplexity:
41
+ Max: 10
42
+
43
+ # A bunch of fields in a hash are basically generated data. Correcting them
44
+ # for column seems much too pedantic. I guess exclude is the right thing for
45
+ # an unusual file?
46
+ Layout/LineLength:
47
+ Max: 132
48
+ Exclude:
49
+ - 'lib/image_voodoo/metadata.rb'
50
+
51
+ # Metadata classes have data in them. awt.rb is big and perhaps could be
52
+ # shrunk but it is not a hard file to navigate and the cleaving points are
53
+ # not super obvious. These sorts of rules feel very arbitrary and if I have
54
+ # n highly related things and they do not fit into a more restrictive
55
+ # taxonomy why would the file being longer matter? I do understand the
56
+ # motivation here but as a default rule this feels wrong to me.
57
+ Metrics/ClassLength:
58
+ Max: 250
59
+
60
+ # I do not find this very useful. There is no performance difference and
61
+ # sometimes I want to highlight this string does not involve interpolation.
62
+ # Other times it is not worth pointing out.
63
+ Style/StringLiterals:
64
+ Enabled: false
65
+
66
+ # require 'english' is a step too far for $! which is so baked into my
67
+ # head I do not want to change :)
68
+ Style/SpecialGlobalVars:
69
+ Enabled: false
70
+
71
+ # I am grouping math and using lack of whitespace for separation.
72
+ Layout/SpaceAroundOperators:
73
+ Enabled: false
74
+
75
+ # I prefer tight assignment for opt args.
76
+ Layout/SpaceAroundEqualsInParameterDefault:
77
+ Enabled: false
78
+
79
+ # Java methods which override or implement Java method names cannot be switched
80
+ # to snake case. Do we really need this as a rule anyways? I have never seen
81
+ # a Rubyist do this as a preferred style?
82
+ Naming/MethodName:
83
+ Enabled: false
84
+
85
+ # bin/image_voodoo main options block.
86
+ Metrics/BlockLength:
87
+ Exclude:
88
+ - 'bin/image_voodoo'
89
+
90
+ # Hash rocket looks much more natural in a rakefile for its deps.
91
+ Style/HashSyntax:
92
+ Exclude:
93
+ - 'Rakefile'
94
+
95
+ # Forget it. I do parallel assignment and you will have to peel it out of
96
+ # my cold dead hands.
97
+ Style/ParallelAssignment:
98
+ Enabled: false
99
+
100
+ # FIXME: consider keywords for shapes.
101
+ # I might switch these to keyword args if I ever revisit shapes support.
102
+ # In general lots of params do suck and are hard to remember. This library
103
+ # still is supposed to work in 1.8 but I can probably soon major rev this
104
+ # and switch over to keywords.
105
+ Metrics/ParameterLists:
106
+ Exclude:
107
+ - 'lib/image_voodoo/awt/shapes.rb'
108
+
109
+ # This is complaining that 'x' and 'y' are bad names because they are less
110
+ # than 3 chars. Silly rule even if I appreciate what it is trying to
111
+ # accomplish. Interestingly, in image_voodoo I do use h for height and
112
+ # w for width. Those probably could be written out but they are so common
113
+ # I am basically opting for short-hand. This is something I rarely do except
114
+ # domain-driven code like this (x,y,h,w).
115
+ Naming/MethodParameterName:
116
+ Enabled: false
117
+
118
+ # This represents one of those frustrating dogmatic rules where if I followed
119
+ # this advice I would then violate the column length rule. I specifically
120
+ # use traditional if indented block in cases where if_mod doesn't fit.
121
+ # Gramatically, if_mod can be across two lines but I hate how that looks. The
122
+ # second solution of logical &&/|| change for a raise is alien to for all but
123
+ # assignment.
124
+ Style/IfUnlessModifier:
125
+ Enabled: false
126
+
127
+ # What the hell. Really telling people that encoding: utf-8 should not happen
128
+ # because there are no multi-byte utf-8 characters in it? Why add this noise?
129
+ Style/Encoding:
130
+ Enabled: false
131
+
132
+ # FIXME:
133
+ # This is an unknown error which I should figure out. It must be some
134
+ # StandardError (which is what nothing explicit means) but I should actually
135
+ # be more explicit here.
136
+ Style/RescueStandardError:
137
+ Exclude:
138
+ - 'lib/image_voodoo.rb'
139
+
140
+
141
+ # This was complaining metadata_impl should use @metadata_impl instead of
142
+ # @metadata. I disagree and am unsure why I need to follow this programs
143
+ # opinion on what a good name is? What is commentable is if I change the
144
+ # variable name to @gorgon it still tells me I need to use @metadata_impl.
145
+ # So if I conditionally add any state in any method it will tell me I am
146
+ # memoizing and have to use same ivar as the name of the method? Is it more
147
+ # sophisticated than that? Should I have spent 2-3 minutes trying to figure
148
+ # out how this rule was implemented? :)
149
+ Naming/MemoizedInstanceVariableName:
150
+ Enabled: false
151
+
152
+ # I have two modes of use for private. If it is a small number of individual
153
+ # methods I am explicit and inline the private. If it is a large number of
154
+ # methods especially when the name is fairly obvious that those will be private
155
+ # (like render_impl) then I use block private. Not sure telling me I can only
156
+ # use a single style is very useful.
157
+ Style/AccessModifierDeclarations:
158
+ Enabled: false
159
+
160
+ # I feel for the tiny amount of generation here a better name would not help
161
+ # me understand it better. This is one of those naming rules I feel is
162
+ # probably helpful a minority of the time. Also I have never been confused
163
+ # by what a heredoc text represents because of my heredoc terminator?
164
+ Naming/HeredocDelimiterNaming:
165
+ Enabled: false
data/.travis.yml CHANGED
@@ -1,2 +1,17 @@
1
+ language: ruby
2
+
3
+ sudo: false
4
+
1
5
  rvm:
2
- - jruby-19mode
6
+ - jruby-head
7
+
8
+ before_install:
9
+ - mkdir rvm_tmp
10
+ - cd rvm_tmp
11
+
12
+ before_script:
13
+ - cd ..
14
+ - git clone --depth 1 https://github.com/drewnoakes/metadata-extractor-images.git ../metadata-extractor-images
15
+
16
+ install: JRUBY_OPTS=--dev jruby --dev -S bundle install --jobs=3 --retry=3
17
+
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gemspec
data/Jars.lock ADDED
@@ -0,0 +1,3 @@
1
+ org.yaml:snakeyaml:1.23:compile:
2
+ com.drewnoakes:metadata-extractor:2.11.0:compile:
3
+ com.adobe.xmp:xmpcore:5.1.3:compile:
data/Rakefile CHANGED
@@ -1,13 +1,23 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bundler'
2
4
  require 'rake/testtask'
5
+ require 'jars/installer'
3
6
  Bundler::GemHelper.install_tasks
7
+ Bundler.setup
8
+
9
+ task :default => %i[vendor_jars test]
4
10
 
5
- task :default => :test
11
+ desc 'Vendor Jars'
12
+ task :vendor_jars do
13
+ test_file = File.expand_path File.join('lib', 'image_voodoo_jars.rb'), __dir__
14
+ Jars::Installer.vendor_jars! unless File.exist? test_file
15
+ end
6
16
 
7
- desc "Run tests"
8
- task :test do
17
+ desc 'Run tests'
18
+ task :test => :vendor_jars do
9
19
  Rake::TestTask.new do |t|
10
- t.libs << "lib:vendor"
20
+ t.libs << 'lib:vendor'
11
21
  t.test_files = FileList['test/test*.rb']
12
22
  end
13
23
  end
data/bin/image_voodoo CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  #!/usr/bin/env ruby
2
4
 
3
5
  require 'optparse'
@@ -7,101 +9,91 @@ actions = []
7
9
  images = []
8
10
  original_image = nil
9
11
 
10
- opts = OptionParser.new do |opts|
11
- opts.banner = "Usage: image_voodoo [actions] image_file"
12
- opts.separator "Perform some actions on a source image."
13
-
14
- opts.separator ""
15
- opts.separator "Actions are meant to be chained. Examples:"
16
- opts.separator " # Print the dimensions"
17
- opts.separator " image_voodoo --dim small.jpg"
18
- opts.separator ""
19
- opts.separator " # Convert to a thumbnail, preview, and then save the result"
20
- opts.separator " image_voodoo --thumbnail 50 --preview --save thumb.png large.jpg"
21
- opts.separator ""
22
- opts.separator " # Convert source to 3 thumbnails, showing dimensions and"
23
- opts.separator " # previewing along the way"
24
- opts.separator " image_voodoo --dim --resize 50x50 --dim --preview --save t1.jpg"
25
- opts.separator " --pop --resize 40x40 --dim --preview --save t2.jpg"
26
- opts.separator " --pop --resize 30x30 --dim --preview --save t3.jpg image.jpg"
27
-
28
- opts.separator ""
29
- opts.separator "Actions:"
30
-
31
- opts.on("-a", "--alpha color_value", "Make color transparent in image") do |c|
32
- if c !~ /[[:xdigit:]]{6,6}/
33
- opts.usage "color_value is rrggbb in hexidecimal format"
34
- end
35
- actions << lambda {|img| img.alpha(c) }
36
- end
37
-
38
- opts.on("-b", "--brightness SCALE,OFFSET", "Adjust brightness") do |args|
39
- scale, offset = args.split(/,/).map {|v| v.to_f}
40
- opts.usage "You need to specify proper scale and offset" unless scale && offset
41
- actions << lambda {|img| img.adjust_brightness(scale, offset) }
42
- end
43
-
44
- opts.on("-B", "--border WIDTH,COLOR,STYLE", "Add a simple border") do |args|
12
+ opts = OptionParser.new do |o|
13
+ o.banner = 'Usage: image_voodoo [actions] image_file'
14
+ o.separator 'Perform actions/transformations on an image.'
15
+ o.separator ''
16
+ o.separator 'Examples:'
17
+ o.separator ' image_voodoo --dim small.jpg # Print the dimensions'
18
+ o.separator ''
19
+ o.separator ' # Make a thumbnail, preview it, and then save it.'
20
+ o.separator ' image_voodoo --thumbnail 50 --preview --save thumb.png large.jpg'
21
+ o.separator ''
22
+ o.separator ' # Make 2 thumbnails, showing dimensions and previewing them'
23
+ o.separator ' image_voodoo --dim --resize 50x50 --dim --preview --save t1.jpg'
24
+ o.separator ' --pop --resize 40x40 --dim --preview --save t2.jpg image.jpg'
25
+ o.separator ''
26
+ o.separator 'Actions:'
27
+
28
+ o.on('-a', '--alpha rrggbb', 'Make color transparent in image') do |c|
29
+ o.usage 'rrggbb is in hexidecimal format' if c !~ /[[:xdigit:]]{6,6}/
30
+ actions << ->(img) { img.alpha(c) }
31
+ end
32
+
33
+ o.on('-b', '--brightness SCALE,OFFSET', 'Adjust brightness') do |args|
34
+ scale, offset = args.split(/,/).map(&:to_f)
35
+ o.usage 'You need to specify proper scale and offset' unless scale && offset
36
+ actions << ->(img) { img.adjust_brightness(scale, offset) }
37
+ end
38
+
39
+ o.on('-B', '--border WIDTH,COLOR,STYLE', 'Add a simple border') do |args|
45
40
  width, color, style = args.split(/,/)
46
- options = {:width => width, :color => color, :style => style }
47
-
48
- actions << lambda {|img| img.add_border(options) }
41
+ options = { width: width, color: color, style: style }
42
+ actions << ->(img) { img.add_border(options) }
49
43
  end
50
44
 
51
- opts.on("-d", "--dimensions", "Print the image dimensions") do
52
- actions << lambda {|img| puts "#{img.width}x#{img.height}"; img }
45
+ o.on('-d', '--dimensions', 'Print the image dimensions') do
46
+ actions << ->(img) { img.tap { puts "#{img.width}x#{img.height}" } }
53
47
  end
54
48
 
55
- opts.on("-g", "--greyscale", "Convert image to greyscale") do
56
- actions << lambda {|img| img.greyscale }
49
+ o.on('-g', '--greyscale', 'Convert image to greyscale') do
50
+ actions << ->(img) { img.greyscale }
57
51
  end
58
52
 
59
- opts.on("-h", "--flip_horizontally") do
60
- actions << lambda {|img| img.flip_horizontally }
53
+ o.on('-h', '--flip_horizontally') do
54
+ actions << ->(img) { img.flip_horizontally }
61
55
  end
62
56
 
63
- opts.on("-m", "--metadata") do
64
- actions << lambda {|img| puts img.metadata }
57
+ o.on('-m', '--metadata') do
58
+ actions << ->(img) { img.tap { puts img.metadata } }
65
59
  end
66
60
 
67
- opts.on("-n", "--negative", "Make a negative out of the image") do
68
- actions << lambda {|img| img.negative }
61
+ o.on('-n', '--negative', 'Make a negative out of the image') do
62
+ actions << ->(img) { img.negative }
69
63
  end
70
64
 
71
- opts.on("-o", "--orient", "Rotate image to orient it based on metadata") do
72
- actions << lambda {|img| img.correct_orientation }
65
+ o.on('-o', '--orient', 'Rotate image to orient it based on metadata') do
66
+ actions << ->(img) { img.correct_orientation }
73
67
  end
74
68
 
75
- opts.on("-q", "--quality 0..1", Float, "Set % of quality for lossy compression") do |quality|
76
- actions << lambda {|img| img.quality(quality) }
69
+ o.on('-q', '--quality 0..1', Float, 'Set % of quality for lossy compression') do |quality|
70
+ actions << ->(img) { img.quality(quality) }
77
71
  end
78
72
 
79
- opts.on("-R", "--rotate 0..360", Float, "Set angle to rotate image") do |angle|
80
- actions << lambda {|img| img.rotate(angle.to_f) }
73
+ o.on('-R', '--rotate 0..360', Float, 'Set angle to rotate image') do |angle|
74
+ actions << ->(img) { img.rotate(angle.to_f) }
81
75
  end
82
76
 
83
- opts.on("-r", "--resize WIDTHxHEIGHT", "Create a new image with the specified", "dimensions") do |dim|
84
- width, height = dim.split(/x/i).map {|v| v.to_i}
85
- opts.usage "You need to specify proper dimensions" unless width && width > 0 && height && height > 0
86
- actions << lambda {|img| img.resize(width,height) }
77
+ o.on('-r', '--resize WIDTHxHEIGHT', 'Make a new resized image') do |dim|
78
+ width, height = dim.split(/x/i).map(&:to_i)
79
+ o.usage 'You need to specify proper dimensions' unless width && width > 0 && height && height > 0
80
+ actions << ->(img) { img.resize(width, height) }
87
81
  end
88
82
 
89
-
90
- opts.on("-s", "--save FILENAME", "Save the results to a new file") do |f|
91
- actions << lambda {|img| img.save(f); img }
83
+ o.on('-s', '--save FILENAME', 'Save the results to a new file') do |f|
84
+ actions << ->(img) { img.tap { img.save(f) } }
92
85
  end
93
86
 
94
- opts.on("-t", "--thumbnail SIZE", Integer, "Create a thumbnail of the given size") do |size|
95
- actions << lambda {|img| img.thumbnail(size) }
87
+ o.on('-t', '--thumbnail SIZE', Integer, 'Create a thumbnail of the given size') do |size|
88
+ actions << ->(img) { img.thumbnail(size) }
96
89
  end
97
90
 
98
- opts.on("-v", "--flip_vertically") do
99
- actions << lambda {|img| img.flip_vertically }
100
- end
101
-
102
- opts.on("-p", "--preview", "Preview the image. Close the frame window",
103
- "to continue, or quit the application to", "abort the action pipeline") do
91
+ o.on('-v', '--flip_vertically') { actions << ->(img) { img.flip_vertically } }
104
92
 
93
+ o.on('-p', '--preview',
94
+ 'Preview the image. Close the frame window',
95
+ 'to continue, or quit the application to',
96
+ 'abort the action pipeline') do
105
97
  headless = false
106
98
  actions << lambda do |img|
107
99
  done = false
@@ -111,36 +103,33 @@ opts = OptionParser.new do |opts|
111
103
  end
112
104
  end
113
105
 
114
- opts.on("--push", "Save the current image to be popped later") do
115
- actions << lambda {|img| images << img; img }
106
+ o.on('--push', 'Save the current image to be popped later') do
107
+ actions << ->(img) { img.tap { images << img } }
116
108
  end
117
109
 
118
- opts.on("--pop", "Revert back to the previous saved image", "or the original source image") do
119
- actions << lambda {|img| images.pop || original_image }
110
+ o.on('--pop', 'Revert back to the previous image') do
111
+ actions << -> { images.pop || original_image }
120
112
  end
121
113
 
122
- opts.on("-f", "--format", "Print the image format") do
123
- actions << lambda {|img| puts img.format; img }
114
+ o.on('-f', '--format', 'Print the image format') do
115
+ actions << ->(img) { img.tap { img.format } }
124
116
  end
125
117
 
126
- opts.on_tail("-h", "--help", "Show this message") do
127
- puts opts
128
- exit 0
129
- end
118
+ o.on_tail('-h', '--help', 'Show this message') { o.usage }
130
119
 
131
- def opts.usage(msg)
132
- puts msg
120
+ def o.usage(msg=nil)
121
+ puts msg if msg
133
122
  puts self
134
123
  exit 1
135
124
  end
136
125
  end
137
126
  opts.parse!(ARGV)
138
- opts.usage("You need to supply a source image filename.") unless ARGV.first
139
- opts.usage("You need to supply one or more actions.") unless actions.size > 0
127
+ opts.usage('You need to supply a source image filename.') unless ARGV.first
128
+ opts.usage('You need to supply one or more actions.') if actions.empty?
140
129
 
141
130
  # For this binstub we only want to load non-headless if we are using
142
131
  # the preview feature. top of See lib/image_voodoo.rb for more info...
143
- class ImageVoodoo; NEEDS_HEAD = true; end unless headless
132
+ require 'image_voodoo/needs_head' unless headless
144
133
 
145
134
  require 'image_voodoo'
146
135
  file_name = ARGV.first
data/image_voodoo.gemspec CHANGED
@@ -1,6 +1,8 @@
1
1
  # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path("../lib", __FILE__)
3
- require "image_voodoo/version"
2
+ # frozen_string_literal: true
3
+
4
+ $LOAD_PATH.push File.expand_path('lib', __dir__)
5
+ require 'image_voodoo/version'
4
6
 
5
7
  Gem::Specification.new do |s|
6
8
  s.name = 'image_voodoo'
@@ -12,11 +14,16 @@ Gem::Specification.new do |s|
12
14
  s.summary = 'Image manipulation in JRuby with ImageScience compatible API'
13
15
  s.description = 'Image manipulation in JRuby with ImageScience compatible API'
14
16
 
15
- s.rubyforge_project = "image_voodoo"
16
-
17
17
  s.files = `git ls-files`.split("\n")
18
18
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
- s.require_paths = ["lib", "vendor"]
21
- s.has_rdoc = true
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
20
+ s.require_paths = %w[lib vendor]
21
+
22
+ s.add_development_dependency 'jar-dependencies'
23
+ s.add_development_dependency 'rake'
24
+ s.add_development_dependency 'rubocop'
25
+ s.add_development_dependency 'ruby-maven'
26
+ s.add_development_dependency 'test-unit'
27
+
28
+ s.requirements << 'jar com.drewnoakes, metadata-extractor, 2.11.0'
22
29
  end
data/lib/image_science.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'image_voodoo'
2
4
  # HA HA...let the pin-pricking begin
3
- ImageScience = ImageVoodoo
5
+ ImageScience = ImageVoodoo
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'java'
4
+
5
+ # Hide in ImageVoodoo so awt.rb can see this and we will not polute global
6
+ class ImageVoodoo
7
+ java_import java.awt.image.BufferedImage
8
+
9
+ # Re-open to add convenience methods.
10
+ class BufferedImage
11
+ def each
12
+ height.times { |j| width.times { |i| yield i, j } }
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'java'
4
+
5
+ # Hide in ImageVoodoo so awt.rb can see this and we will not polute global
6
+ class ImageVoodoo
7
+ java_import java.awt.Graphics2D
8
+
9
+ # Re-open to add convenience methods.
10
+ class Graphics2D
11
+ def draw_this_image(image)
12
+ draw_image image, 0, 0, nil
13
+ end
14
+ end
15
+ end
@@ -1,5 +1,44 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class ImageVoodoo
4
+ # (Experimental) An attempt at some primitive drawing in images.
2
5
  module Shapes
6
+ # FIXME: if image has alpha values the border shows through since it is
7
+ # a solid fill.
8
+ ##
9
+ # *AWT* (experimental) Add a border to the image and yield/return a new
10
+ # image. The following options are supported:
11
+ # - width: How thick is the border (default: 3)
12
+ # - color: Which color is the border (in rrggbb hex value)
13
+ # - style: etched, raised, plain (default: plain)
14
+ #
15
+ def add_border(options = {})
16
+ border_width = options[:width].to_i || 2
17
+ new_width, new_height = width + 2*border_width, height + 2*border_width
18
+ target = paint(BufferedImage.new(new_width, new_height, color_type)) do |g|
19
+ paint_border(g, new_width, new_height, options)
20
+ g.draw_image(@src, nil, border_width, border_width)
21
+ end
22
+ block_given? ? yield(target) : target
23
+ end
24
+
25
+ def paint_border(g, new_width, new_height, options)
26
+ g.color = hex_to_color(options[:color])
27
+ fill_method, *args = border_style(options)
28
+ g.send fill_method, 0, 0, new_width, new_height, *args
29
+ end
30
+
31
+ def border_style(options)
32
+ case (options[:style] || "").to_s
33
+ when "raised" then
34
+ [:fill3DRect, true]
35
+ when "etched" then
36
+ [:fill3DRect, false]
37
+ else
38
+ [:fill_rect]
39
+ end
40
+ end
41
+
3
42
  ##
4
43
  # *AWT* Draw a square
5
44
  #
@@ -18,14 +57,14 @@ class ImageVoodoo
18
57
  # *AWT* Draw a rounded square
19
58
  #
20
59
  def square_rounded(x, y, dim, rgb, arc_width=0, fill=true)
21
- rect_rounded(x,y, dim, dim, rgb, arc_width, arc_width, fill)
60
+ rect_rounded(x, y, dim, dim, rgb, arc_width, arc_width, fill)
22
61
  end
23
62
 
24
63
  ##
25
64
  # *AWT* Draw a rounded rectangle
26
65
  #
27
66
  def rect_rounded(x, y, width, height, rgb, arc_width=0, arc_height=0, fill=true)
28
- as_color(ImageVoodoo.hex_to_color(rgb)) do |g|
67
+ as_color(hex_to_color(rgb)) do |g|
29
68
  if fill
30
69
  g.fill_round_rect x, y, width, height, arc_width, arc_height
31
70
  else
@@ -44,4 +83,3 @@ class ImageVoodoo
44
83
  end
45
84
  end
46
85
  end
47
-