mork 0.18.1 → 0.19.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9c871eb798a14173c833892d6cb6030e266158239058f9ef0fbb2ff359c1073f
4
- data.tar.gz: 8e2ac94ee3e806455d617f959459eebe6964521c9711064e5f0c86facf9fda8f
3
+ metadata.gz: 8d1ff44d3b000b420e231a5ab3823293dad26ef69ec29ade174e74db32b16b9c
4
+ data.tar.gz: 520167a98213a49bec5820fb7d2476416197484dd93785ed861bb4998b9ca2ec
5
5
  SHA512:
6
- metadata.gz: 464bb64cfe62e30bba0037b154d527a00d165b1bd71b4ffa4534bc28cace42fd86aa8455d927d6d660c218d25be92cca4292f60aa66b787af8ce9ed7bea82ba9
7
- data.tar.gz: 37ab32c16c165c6c120a8addca74a6bafbe44a02d494ab80968a499dd5d44bad1b6402031c3ff8703a94b8ffbcdd8fc6afd093369b9535883aa49aa2ff2dd0e3
6
+ metadata.gz: 6c66b3b59d316efe183f978e7702c03608ef08208a202640648a5e76d023d54d9bd6985db7d9307d677ca5c6f85776f1264fe141f9edcebb8ecf206956f4ca49
7
+ data.tar.gz: 580d00362722d80ea7af5411486174f714328de9ddf936a59aa911f86525725e27c5452aaa909ea2d2bc89abd57ee6b46e7e9434f239201c7ae12ea738f06bdf
data/README.md CHANGED
@@ -315,7 +315,7 @@ system 'open corrections.jpg' # this works in macOS
315
315
 
316
316
  `overlay_corrections` applies:
317
317
 
318
- - a green outline on the marked cell when the response is correct
318
+ - a green outline and semitransparent green fill on the marked cell when the response is correct
319
319
  - a red outline on the expected cell and a red cross on the marked cell when the response is incorrect
320
320
  - a red outline on the expected cell when the response is blank or invalid
321
321
 
data/lib/mork/magicko.rb CHANGED
@@ -18,7 +18,11 @@ module Mork
18
18
  # a default of 150 dpi seems sensible. It should not affect bitmaps.
19
19
  density = 150
20
20
  # inspect the source file
21
- s1, s2, s3 = Open3.capture3 "identify -density #{density} -format '%w %h %m' #{path}"
21
+ identify = MiniMagick.identify
22
+ identify.density density
23
+ identify.format '%w %h %m'
24
+ identify << path
25
+ s1, s2, s3 = Open3.capture3(*identify.command)
22
26
  if s3.success?
23
27
  # parse the identify command output
24
28
  w, h, @type = s1.split(' ')
@@ -54,16 +58,17 @@ module Mork
54
58
  # (i.e. the centers of the four registration marks)
55
59
  # pp: a hash in the form of pp[:tl][:x], pp[:tl][:y], etc.
56
60
  def registered_bytes(pp)
57
- read_bytes "-distort Perspective '#{pps pp}'"
61
+ read_bytes '-distort', 'Perspective', pps(pp)
58
62
  end
59
63
 
60
64
  # Reading from the image file the bytes from one of the four corner
61
65
  # squares encompassing each registration mark; the blur and dilation
62
66
  # manipulations may prevent registration misalignments due to stray dark pixels
63
67
  def rm_patch(c, blr=0, dlt=0)
64
- b = blr==0 ? '' : " -blur #{blr*3}x#{blr}"
65
- d = dlt==0 ? '' : " -morphology Dilate Octagon:#{dlt}"
66
- read_bytes "-crop #{c.cropper}#{b}#{d}"
68
+ params = ['-crop', c.cropper]
69
+ params.concat ['-blur', "#{blr*3}x#{blr}"] unless blr == 0
70
+ params.concat ['-morphology', 'Dilate', "Octagon:#{dlt}"] unless dlt == 0
71
+ read_bytes(*params)
67
72
  end
68
73
 
69
74
  ##################################
@@ -76,6 +81,13 @@ module Mork
76
81
  coords.each { |c| @cmd << [:draw, shape(c, rounded)] }
77
82
  end
78
83
 
84
+ def highlight_green(coords, rounded)
85
+ return if coords.empty?
86
+ @cmd << [:stroke, 'none']
87
+ @cmd << [:fill, 'rgba(0, 255, 0, 0.3)']
88
+ coords.each { |c| @cmd << [:draw, shape(c, rounded)] }
89
+ end
90
+
79
91
  def outline(coords, rounded)
80
92
  outline_with_color(coords, rounded, 'green')
81
93
  end
@@ -171,10 +183,18 @@ module Mork
171
183
 
172
184
  # calling imagemagick and capturing the converted image
173
185
  # into an array of bytes
174
- def read_bytes(params=nil)
175
- d = @density ? "-density #{@density}" : nil
176
- cmd = "magick -depth 8 #{d} #{@path} #{params} gray:-"
177
- stdout, stderr, status = Open3.capture3(cmd)
186
+ def read_bytes(*params)
187
+ # MiniMagick selects `convert` on ImageMagick 6 and `magick` on
188
+ # ImageMagick 7. Execute its argv directly to preserve binary stdout
189
+ # (MiniMagick::Tool#call strips a trailing newline) and avoid a shell.
190
+ command = MiniMagick.convert
191
+ command.depth 8
192
+ command.density @density if @density
193
+ command << @path
194
+ command.merge!(params)
195
+ command << 'gray:-'
196
+
197
+ stdout, stderr, status = Open3.capture3(*command.command)
178
198
  if status.success?
179
199
  stdout.unpack('C*')
180
200
  else
@@ -165,10 +165,10 @@ module Mork
165
165
 
166
166
  # Applies correctness-aware overlays to the image using an answer key.
167
167
  #
168
- # Correct responses receive a green outline on the marked cell. Incorrect
169
- # responses receive a red outline on the expected cell and a red cross on
170
- # the given cell. Blank or invalid responses receive only the red outline
171
- # on the expected cell.
168
+ # Correct responses receive a green outline and semitransparent green fill
169
+ # on the marked cell. Incorrect responses receive a red outline on the
170
+ # expected cell and a red cross on the given cell. Blank or invalid
171
+ # responses receive only the red outline on the expected cell.
172
172
  #
173
173
  # @param correct_choices [Array<Integer, Array<Integer>, nil>] one entry per
174
174
  # question. Each entry can be an integer choice index, a 1-element array
@@ -183,6 +183,7 @@ module Mork
183
183
  actual = marked_responses(marked)
184
184
 
185
185
  green_outlines = Array.new(expected.length) { [] }
186
+ green_highlights = Array.new(expected.length) { [] }
186
187
  red_outlines = Array.new(expected.length) { [] }
187
188
  red_crosses = Array.new(expected.length) { [] }
188
189
 
@@ -192,6 +193,7 @@ module Mork
192
193
  marked_cells = actual[question]
193
194
  if marked_cells == [choice]
194
195
  green_outlines[question] = [choice]
196
+ green_highlights[question] = [choice]
195
197
  next
196
198
  end
197
199
 
@@ -200,6 +202,7 @@ module Mork
200
202
  end
201
203
 
202
204
  @mim.overlay :outline_green, green_outlines
205
+ @mim.overlay :highlight_green, green_highlights
203
206
  @mim.overlay :outline_red, red_outlines
204
207
  @mim.overlay :check_red, red_crosses
205
208
  end
data/lib/mork/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Mork
2
- VERSION = '0.18.1'
2
+ VERSION = '0.19.0'
3
3
  end
@@ -39,6 +39,30 @@ module Mork
39
39
  end
40
40
  end
41
41
 
42
+ describe 'ImageMagick command selection' do
43
+ let(:status) { instance_double(Process::Status, success?: true) }
44
+
45
+ it 'uses ImageMagick 6 convert through MiniMagick and preserves raw bytes' do
46
+ magicko = ma
47
+ allow(MiniMagick).to receive(:imagemagick7?).and_return(false)
48
+ expect(Open3).to receive(:capture3).with(
49
+ 'convert', '-depth', '8', sh.image_path, '-crop', co.cropper, 'gray:-'
50
+ ).and_return(["\x00\x0a\xff".b, '', status])
51
+
52
+ expect(magicko.rm_patch(co)).to eq [0, 10, 255]
53
+ end
54
+
55
+ it 'uses ImageMagick 7 magick through MiniMagick' do
56
+ magicko = ma
57
+ allow(MiniMagick).to receive(:imagemagick7?).and_return(true)
58
+ expect(Open3).to receive(:capture3).with(
59
+ 'magick', '-depth', '8', sh.image_path, '-crop', co.cropper, 'gray:-'
60
+ ).and_return(["\x00".b, '', status])
61
+
62
+ expect(magicko.rm_patch(co)).to eq [0]
63
+ end
64
+ end
65
+
42
66
  describe 'overlay stroke width' do
43
67
  it 'defaults to the legacy 3-pixel width' do
44
68
  expect(ma.overlay_stroke_width).to eq 3
@@ -49,6 +73,14 @@ module Mork
49
73
  ma.outline [co], false
50
74
  expect(ma.instance_variable_get(:@cmd)).to include([:strokewidth, 6])
51
75
  end
76
+
77
+ it 'draws a semitransparent green fill over the cell' do
78
+ ma.highlight_green [co], false
79
+ commands = ma.instance_variable_get(:@cmd)
80
+ expect(commands).to include([:stroke, 'none'])
81
+ expect(commands).to include([:fill, 'rgba(0, 255, 0, 0.3)'])
82
+ expect(commands).to include([:draw, 'rectangle 0 0 50 50'])
83
+ end
52
84
  end
53
85
  end
54
86
  end
@@ -167,6 +167,7 @@ module Mork
167
167
  allow(omr).to receive(:marked_choices).and_return([[1], [2], [], [3, 4]])
168
168
 
169
169
  expect(mim).to receive(:overlay).with(:outline_green, [[1], [], [], []]).ordered
170
+ expect(mim).to receive(:overlay).with(:highlight_green, [[1], [], [], []]).ordered
170
171
  expect(mim).to receive(:overlay).with(:outline_red, [[], [0], [2], [3]]).ordered
171
172
  expect(mim).to receive(:overlay).with(:check_red, [[], [2], [], []]).ordered
172
173
 
@@ -179,6 +180,7 @@ module Mork
179
180
  omr.set_choices [5] * 2
180
181
 
181
182
  expect(mim).to receive(:overlay).with(:outline_green, [[], []]).ordered
183
+ expect(mim).to receive(:overlay).with(:highlight_green, [[], []]).ordered
182
184
  expect(mim).to receive(:overlay).with(:outline_red, [[3], [1]]).ordered
183
185
  expect(mim).to receive(:overlay).with(:check_red, [[1, 2], [0]]).ordered
184
186
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mork
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.18.1
4
+ version: 0.19.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Giuseppe Bertini