mork 0.8.1 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -1
- data/README.md +107 -35
- data/lib/mork/coord.rb +1 -1
- data/lib/mork/extensions.rb +3 -0
- data/lib/mork/grid.rb +13 -6
- data/lib/mork/grid_const.rb +11 -9
- data/lib/mork/grid_omr.rb +15 -5
- data/lib/mork/grid_pdf.rb +1 -0
- data/lib/mork/magicko.rb +46 -28
- data/lib/mork/mimage.rb +113 -52
- data/lib/mork/mimage_list.rb +6 -5
- data/lib/mork/npatch.rb +16 -18
- data/lib/mork/sheet_omr.rb +210 -125
- data/lib/mork/sheet_pdf.rb +15 -8
- data/lib/mork/version.rb +1 -1
- data/mork.gemspec +2 -0
- data/mork.sublime-project +1 -1
- data/spec/mork/extensions_spec.rb +3 -3
- data/spec/mork/grid_omr_spec.rb +2 -1
- data/spec/mork/grid_spec.rb +34 -35
- data/spec/mork/magicko_spec.rb +2 -2
- data/spec/mork/mimage_spec.rb +22 -63
- data/spec/mork/sheet_omr_spec.rb +96 -201
- data/spec/mork/sheet_pdf_spec.rb +9 -10
- data/spec/out/{.gitignore → barcode/.gitignore} +0 -0
- data/spec/out/highlight/.gitignore +4 -0
- data/spec/out/mark/.gitignore +4 -0
- data/spec/out/outline/.gitignore +4 -0
- data/spec/out/pdf/.gitignore +4 -0
- data/spec/out/registration/.gitignore +4 -0
- data/spec/out/text/.gitignore +4 -0
- data/spec/samples/angolo.jpg +0 -0
- data/spec/samples/angolo2.jpg +0 -0
- data/spec/samples/angolo3.jpg +0 -0
- data/spec/samples/boxy.yml +0 -0
- data/spec/samples/grid.yml +0 -0
- data/spec/samples/grid160.yml +0 -0
- data/spec/samples/grid_omr_layout.yml +56 -0
- data/spec/samples/info.yml +15 -39
- data/spec/samples/jdoe/JohnDoe1.jpeg +0 -0
- data/spec/samples/jdoe/JohnDoe2.jpeg +0 -0
- data/spec/samples/jdoe/JohnDoe3.jpeg +0 -0
- data/spec/samples/jdoe/layout.yml +58 -0
- data/spec/samples/layout.yml +2 -2
- data/spec/samples/lucrezia/border1.pdf +0 -0
- data/spec/samples/lucrezia/border2.pdf +0 -0
- data/spec/samples/lucrezia/bw1.pdf +0 -0
- data/spec/samples/lucrezia/bw2.pdf +0 -0
- data/spec/samples/lucrezia/gray1.pdf +0 -0
- data/spec/samples/lucrezia/gray2.pdf +0 -0
- data/spec/samples/{syst/IMG_20150104_0004.jpg → marisol/marisol1.jpg} +0 -0
- data/spec/samples/{syst/IMG_20150104_0009.jpg → marisol/marisol2.jpg} +0 -0
- data/spec/samples/{syst/IMG_20150104_0011.jpg → marisol/marisol3.jpg} +0 -0
- data/spec/samples/reg_mark.jpg +0 -0
- data/spec/samples/rm00.jpeg +0 -0
- data/spec/samples/rm01.jpeg +0 -0
- data/spec/samples/rm02.jpeg +0 -0
- data/spec/samples/rm03.jpeg +0 -0
- data/spec/samples/rm04.jpeg +0 -0
- data/spec/samples/rm05.jpeg +0 -0
- data/spec/samples/syst/barr0.jpg +0 -0
- data/spec/samples/syst/barr1.jpg +0 -0
- data/spec/samples/syst/barr2.jpg +0 -0
- data/spec/samples/syst/bell0.jpg +0 -0
- data/spec/samples/syst/bell1.jpg +0 -0
- data/spec/samples/syst/bell2.jpg +0 -0
- data/spec/samples/syst/bila0.jpg +0 -0
- data/spec/samples/syst/bila1.jpg +0 -0
- data/spec/samples/syst/bila2.jpg +0 -0
- data/spec/samples/syst/bila3.jpg +0 -0
- data/spec/samples/syst/bila4.jpg +0 -0
- data/spec/samples/syst/bone0.jpg +0 -0
- data/spec/samples/syst/bone1.jpg +0 -0
- data/spec/samples/syst/bone2.jpg +0 -0
- data/spec/samples/syst/cost0.jpg +0 -0
- data/spec/samples/syst/cost1.jpg +0 -0
- data/spec/samples/syst/cost2.jpg +0 -0
- data/spec/samples/syst/cost3.jpg +0 -0
- data/spec/samples/syst/cost4.jpg +0 -0
- data/spec/samples/syst/dald0.jpg +0 -0
- data/spec/samples/syst/dald1.jpg +0 -0
- data/spec/samples/syst/dald2.jpg +0 -0
- data/spec/samples/syst/dald3.jpg +0 -0
- data/spec/samples/syst/dald4.jpg +0 -0
- data/spec/samples/syst/dign0.jpg +0 -0
- data/spec/samples/syst/dign1.jpg +0 -0
- data/spec/samples/syst/dign2.jpg +0 -0
- data/spec/samples/syst/dive0.jpg +0 -0
- data/spec/samples/syst/dive1.jpg +0 -0
- data/spec/samples/syst/dive2.jpg +0 -0
- data/spec/samples/syst/histo.m +0 -0
- data/spec/samples/{syst_grid.yml → syst/layout.yml} +0 -0
- data/spec/spec_helper.rb +29 -29
- metadata +49 -62
- data/auto.txt +0 -0
- data/spec/samples/out-1.jpg +0 -0
- data/spec/samples/qzc013.jpg +0 -0
- data/spec/samples/sample02.jpg +0 -0
- data/spec/samples/sample_gray.jpg +0 -0
- data/spec/samples/sheet.jpg +0 -0
- data/spec/samples/sheet666.jpg +0 -0
- data/spec/samples/slanted.jpg +0 -0
- data/spec/samples/slanted.yml +0 -54
- data/spec/samples/syst/IMG_20150104_0004.txt +0 -4955
- data/spec/samples/syst/IMG_20150104_0009.txt +0 -4955
- data/spec/samples/syst/IMG_20150104_0011.txt +0 -4955
- data/spec/samples/syst/SCN_0001.jpg +0 -0
- data/spec/samples/syst/SCN_0001.txt +0 -4955
- data/spec/samples/syst/barr0.txt +0 -4955
- data/spec/samples/syst/barr1.txt +0 -4955
- data/spec/samples/syst/barr2.txt +0 -4955
- data/spec/samples/syst/bell0.txt +0 -4955
- data/spec/samples/syst/bell1.txt +0 -4955
- data/spec/samples/syst/bell2.txt +0 -4955
- data/spec/samples/syst/bila0.txt +0 -4955
- data/spec/samples/syst/bila1.txt +0 -4955
- data/spec/samples/syst/bila2.txt +0 -4955
- data/spec/samples/syst/bila3.txt +0 -4955
- data/spec/samples/syst/bila4.txt +0 -4955
- data/spec/samples/syst/bone0.txt +0 -4955
- data/spec/samples/syst/bone1.txt +0 -4955
- data/spec/samples/syst/bone2.txt +0 -4955
- data/spec/samples/syst/cost0.txt +0 -4955
- data/spec/samples/syst/cost1.txt +0 -4955
- data/spec/samples/syst/cost2.txt +0 -4955
- data/spec/samples/syst/cost3.txt +0 -4955
- data/spec/samples/syst/cost4.txt +0 -4955
- data/spec/samples/syst/dald0.txt +0 -4955
- data/spec/samples/syst/dald1.txt +0 -4955
- data/spec/samples/syst/dald2.txt +0 -4955
- data/spec/samples/syst/dald3.txt +0 -4955
- data/spec/samples/syst/dald4.txt +0 -4955
- data/spec/samples/syst/dign0.txt +0 -4955
- data/spec/samples/syst/dign1.txt +0 -4955
- data/spec/samples/syst/dign2.txt +0 -4955
- data/spec/samples/syst/dive0.txt +0 -4955
- data/spec/samples/syst/dive1.txt +0 -4955
- data/spec/samples/syst/dive2.txt +0 -4955
- data/spec/samples/syst/out0000.jpg +0 -0
- data/spec/samples/syst/out0000.txt +0 -4955
- data/spec/samples/syst/out0001.jpg +0 -0
- data/spec/samples/syst/out0001.txt +0 -4955
- data/spec/samples/syst/out0002.jpg +0 -0
- data/spec/samples/syst/out0002.txt +0 -4955
- data/spec/samples/syst/qzc013.jpg +0 -0
- data/spec/samples/syst/qzc013.txt +0 -4955
- data/spec/samples/syst/sample_gray.jpg +0 -0
- data/spec/samples/syst/sample_gray.txt +0 -4955
- data/spec/samples/two_pages.pdf +0 -0
data/spec/mork/mimage_spec.rb
CHANGED
@@ -4,81 +4,40 @@ module Mork
|
|
4
4
|
describe Mimage do
|
5
5
|
let(:qna) { [5] * 100 }
|
6
6
|
|
7
|
-
context '
|
8
|
-
let(:img) { sample_img '
|
9
|
-
let(:
|
7
|
+
context 'John Doe' do
|
8
|
+
let(:img) { sample_img 'jdoe1' }
|
9
|
+
let(:fn) { File.basename(img.image_path) }
|
10
|
+
let(:mim) { Mimage.new img.image_path, [img.nchoices]*img.nitems, GridOMR.new(img.grid_path) }
|
10
11
|
describe 'basics' do
|
11
12
|
it 'should be valid' do
|
12
|
-
mim.highlight_rm_centers
|
13
|
-
mim.highlight_rm_areas
|
14
|
-
mim.write 'spec/out/slanted.jpg', false
|
15
13
|
expect(mim.valid?).to be_truthy
|
16
14
|
end
|
17
15
|
|
18
16
|
it 'should return the correct regmark coordinates' do
|
19
17
|
[:tl, :tr, :br, :bl].each do |corner|
|
20
18
|
crn = mim.rm[corner]
|
21
|
-
expect(crn[:x]).to be_within(2).of(img.
|
22
|
-
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
context 'problematic sheets' do
|
29
|
-
let(:mim) { Mimage.new 'spec/samples/out-1.jpg', qna, GridOMR.new('spec/samples/grid.yml') }
|
30
|
-
let(:bila) { Mimage.new 'spec/samples/syst/bila0.jpg', qna, GridOMR.new('spec/samples/grid.yml') }
|
31
|
-
|
32
|
-
it 'writes all cell values to a text file', exclude: true do
|
33
|
-
d=Dir['spec/samples/syst/*.jpg']
|
34
|
-
d.each do |f|
|
35
|
-
fn = File.basename f, '.jpg'
|
36
|
-
m = Mimage.new "spec/samples/syst/#{fn}.jpg", qna, GridOMR.new('spec/samples/grid.yml')
|
37
|
-
puts fn
|
38
|
-
File.open("spec/samples/syst/#{fn}.txt",'w') do |f|
|
39
|
-
f.puts "ink:#{m.send :ink_black}"
|
40
|
-
f.puts "drk:#{m.send :darkest_cell_mean}"
|
41
|
-
f.puts "pap:#{m.send :paper_white}"
|
42
|
-
f.puts "cal:#{m.send :cal_cell_mean}"
|
43
|
-
f.puts "cho:#{m.send :choice_threshold}"
|
44
|
-
100.times do |q|
|
45
|
-
5.times do |c|
|
46
|
-
f.puts m.send('choice_cell_averages')[q, c]
|
47
|
-
end
|
48
|
-
end
|
19
|
+
expect(crn[:x]).to be_within(2).of(img.send(corner)[0])
|
20
|
+
expect(crn[:x]).to be_within(2).of(img.send(corner)[0])
|
49
21
|
end
|
50
22
|
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
context 'Old specs' do
|
55
|
-
let(:sgi) { sample_img 'sample-gray' }
|
56
|
-
let(:sg) { Mimage.new sgi.filename, qna, GridOMR.new(sgi.grid_file) }
|
57
|
-
|
58
|
-
describe 'basics' do
|
59
|
-
it 'returns the pixels as an array' do
|
60
|
-
expect(sg.send :reg_pixels).to be_a NPatch
|
61
|
-
end
|
62
|
-
|
63
|
-
it 'returns the correct number of pixels' do
|
64
|
-
expect(sg.send(:reg_pixels).length).to eq sgi.width * sgi.height
|
65
|
-
end
|
66
|
-
|
67
|
-
it 'returns the stretched array' do
|
68
|
-
expect(sg.send(:reg_pixels).length).to eq sgi.width * sgi.height
|
69
|
-
end
|
70
|
-
end
|
71
23
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
24
|
+
xit 'writes all cell values to a text file' do
|
25
|
+
d=Dir['spec/samples/syst/*.jpg']
|
26
|
+
d.each do |f|
|
27
|
+
fname = File.basename f, '.jpg'
|
28
|
+
m = Mimage.new "spec/samples/syst/#{fname}.jpg", qna, GridOMR.new('spec/samples/grid.yml')
|
29
|
+
puts fname
|
30
|
+
File.open("spec/out/text/#{fname}.txt",'w') do |f|
|
31
|
+
f.puts "ink:#{m.send :ink_black}"
|
32
|
+
f.puts "drk:#{m.send :darkest_cell_mean}"
|
33
|
+
f.puts "pap:#{m.send :paper_white}"
|
34
|
+
f.puts "cal:#{m.send :cal_cell_mean}"
|
35
|
+
f.puts "cho:#{m.send :choice_threshold}"
|
36
|
+
100.times do |q|
|
37
|
+
5.times do |c|
|
38
|
+
f.puts m.send('choice_cell_averages')[q, c]
|
39
|
+
end
|
80
40
|
end
|
81
|
-
f.puts "#{q+1}: #{t.join(' ')}"
|
82
41
|
end
|
83
42
|
end
|
84
43
|
end
|
data/spec/mork/sheet_omr_spec.rb
CHANGED
@@ -3,258 +3,153 @@ require 'fileutils'
|
|
3
3
|
|
4
4
|
module Mork
|
5
5
|
describe SheetOMR do
|
6
|
-
context '
|
7
|
-
let(:img) { sample_img '
|
8
|
-
let(:
|
6
|
+
context 'with a valid response sheet' do
|
7
|
+
let(:img) { sample_img 'jdoe1' }
|
8
|
+
let(:fn) { File.basename(img.image_path) }
|
9
|
+
let(:omr) { SheetOMR.new img.image_path, choices: [img.nchoices]*img.nitems, layout: img.grid_path }
|
9
10
|
describe '#new' do
|
10
|
-
it 'raises an error if the provided path is invalid' do
|
11
|
-
expect { SheetOMR.new 'non_existing_file.jpg'}.to raise_error IOError
|
12
|
-
end
|
13
|
-
|
14
11
|
it 'creates a SheetOMR object' do
|
15
12
|
expect(omr).to be_a SheetOMR
|
16
13
|
end
|
17
14
|
|
18
|
-
it '
|
19
|
-
expect
|
20
|
-
end
|
21
|
-
|
22
|
-
it 'writes out the registration' do
|
23
|
-
omr.write_registration 'spec/out/slanted2.jpg'
|
15
|
+
it 'raises an error if the provided path is invalid' do
|
16
|
+
expect { SheetOMR.new 'non_existing_file.jpg'}.to raise_error IOError
|
24
17
|
end
|
25
18
|
end
|
26
|
-
end
|
27
|
-
# context 'problematic' do
|
28
|
-
# let(:shinfo) { sample_img 'bianchi' }
|
29
|
-
# let(:sheet) { SheetOMR.new shinfo.filename, shinfo.grid_file }
|
30
|
-
#
|
31
|
-
# it 'has a status' do
|
32
|
-
# sheet.status.should == {:tl=>:ok, :tr=>:ok, :br=>:ok, :bl=>:ok, :write=>nil}
|
33
|
-
# end
|
34
|
-
#
|
35
|
-
# it 'has a barcode' do
|
36
|
-
# sheet.barcode.should == shinfo.barcode_int
|
37
|
-
# end
|
38
|
-
#
|
39
|
-
# it 'writes the registered and marked image' do
|
40
|
-
# sheet.cross_marked
|
41
|
-
# sheet.write 'spec/out/bianchi.jpg'
|
42
|
-
# sheet.status[:write].should == :fail
|
43
|
-
# end
|
44
|
-
#
|
45
|
-
# it 'writes the registration areas' do
|
46
|
-
# sheet.highlight_registration
|
47
|
-
# sheet.write_raw 'spec/out/reg_bianchi.jpg'
|
48
|
-
# end
|
49
|
-
#
|
50
|
-
# end
|
51
|
-
#
|
52
|
-
context 'slanted' do
|
53
|
-
let(:sh) { sample_img 'slanted' }
|
54
|
-
let(:sheet) { SheetOMR.new sh.filename, [5]*120, sh.grid_file }
|
55
|
-
|
56
|
-
it 'gets in trouble' do
|
57
|
-
sheet.write_registration 'spec/out/laurout.jpg'
|
58
|
-
end
|
59
|
-
|
60
|
-
it 'gets more in trouble' do
|
61
|
-
sheet.highlight_marked
|
62
|
-
sheet.write 'spec/out/lauraout2.jpg'
|
63
|
-
end
|
64
|
-
|
65
|
-
it 'should be valid' do
|
66
|
-
expect(sheet.valid?).to be_truthy
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
context 'highlighting' do
|
71
|
-
# since these specs change the @crop, they must be run in isolation
|
72
|
-
# with the SheetOMR rebuilt each time, even though it is time consuming!
|
73
|
-
let(:shinfo) { sample_img 'sample-gray' }
|
74
|
-
let(:sheet) { SheetOMR.new shinfo.filename, [5]*120, shinfo.grid_file }
|
75
|
-
|
76
|
-
it 'writes the sheet with registrations highlighted' do
|
77
|
-
sheet.write_registration 'spec/out/sample_gray_registered.jpg'
|
78
|
-
end
|
79
|
-
|
80
|
-
it 'highlights all choice cells' do
|
81
|
-
sheet.highlight_all_choices
|
82
|
-
sheet.write 'spec/out/all_highlights.jpg'
|
83
|
-
end
|
84
|
-
|
85
|
-
it 'highlights marked cells' do
|
86
|
-
sheet.highlight_marked
|
87
|
-
sheet.write 'spec/out/marked_highlights.jpg'
|
88
|
-
end
|
89
|
-
|
90
|
-
it 'crossed marked cells' do
|
91
|
-
sheet.cross_marked
|
92
|
-
sheet.write 'spec/out/marked_crosses.jpg'
|
93
|
-
end
|
94
19
|
|
95
|
-
|
96
|
-
|
97
|
-
|
20
|
+
describe '#valid?' do
|
21
|
+
it 'registers correctly' do
|
22
|
+
expect(omr.valid?).to be_truthy
|
23
|
+
end
|
98
24
|
end
|
99
25
|
|
100
|
-
|
101
|
-
|
102
|
-
|
26
|
+
describe '#status' do
|
27
|
+
it 'returns the registration status for each of the four corners' do
|
28
|
+
expect(omr.status).to eq({ tl: :ok, tr: :ok, br: :ok, bl: :ok })
|
29
|
+
end
|
103
30
|
end
|
104
31
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
tsheet.write
|
32
|
+
describe '#barcode' do
|
33
|
+
it 'returns the integer form of the barcode' do
|
34
|
+
expect(omr.barcode).to eq img.barcode_int
|
35
|
+
end
|
110
36
|
end
|
111
37
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
38
|
+
describe '#barcode_string' do
|
39
|
+
it 'returns the binary string version of the barcode' do
|
40
|
+
expect(omr.barcode_string).to eq img.barcode_str
|
41
|
+
end
|
116
42
|
end
|
117
43
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
44
|
+
describe '#marked?' do
|
45
|
+
it 'returns true if the given cell was marked, false otherwise' do
|
46
|
+
expect(omr.marked? 0, 0).to be_truthy
|
47
|
+
expect(omr.marked? 0, 1).to be_falsy
|
48
|
+
expect(omr.marked? 119, 4).to be_truthy
|
49
|
+
expect(omr.marked? 119, 3).to be_falsy
|
50
|
+
end
|
123
51
|
end
|
124
52
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
s.write 'spec/out/code_bits.jpg'
|
53
|
+
describe '#marked_choices' do
|
54
|
+
it 'returns an array of marked choices as position indices' do
|
55
|
+
expect(omr.marked_choices).to eq standard_mark_array(24)
|
56
|
+
end
|
130
57
|
end
|
131
|
-
end
|
132
58
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
end
|
59
|
+
describe '#marked_choices' do
|
60
|
+
it 'returns an array of marked choices as position indexes' do
|
61
|
+
expect(omr.marked_choices ).to eq standard_mark_array(24)
|
62
|
+
end
|
138
63
|
|
139
|
-
|
140
|
-
it 'returns
|
141
|
-
|
64
|
+
let(:om2) { SheetOMR.new img.image_path, choices: [5, 4, 3, 2, 1], layout: img.grid_path }
|
65
|
+
it 'returns marked choices only for existing choice cells' do
|
66
|
+
expect(om2.marked_choices).to eq [[0], [1], [2], [], []]
|
142
67
|
end
|
143
68
|
end
|
144
69
|
|
145
|
-
describe '#
|
146
|
-
it 'returns
|
147
|
-
expect(
|
148
|
-
expect(@sheet.marked?(1,1)).to be_truthy
|
149
|
-
expect(@sheet.marked?(2,2)).to be_truthy
|
70
|
+
describe '#marked_logicals' do
|
71
|
+
it 'returns an array of logicals for the marked choices' do
|
72
|
+
expect(omr.marked_logicals).to eq standard_mark_logical_array(24)
|
150
73
|
end
|
74
|
+
end
|
151
75
|
|
152
|
-
|
153
|
-
|
154
|
-
expect(
|
155
|
-
expect(@sheet.marked?(2,3)).to be_falsy
|
76
|
+
describe '#marked_letters' do
|
77
|
+
it 'returns an array of characters for the marked choices' do
|
78
|
+
expect(omr.marked_letters).to eq standard_mark_char_array(24)
|
156
79
|
end
|
80
|
+
end
|
157
81
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
end
|
164
|
-
mf.puts x.join(' ')
|
82
|
+
it 'writes out markedness' do
|
83
|
+
mf = File.open('spec/out/text/marked.txt', 'w')
|
84
|
+
img.nitems.times do |q|
|
85
|
+
x = 5.times.collect do |c|
|
86
|
+
omr.marked?(q,c) ? '1' : '0'
|
165
87
|
end
|
166
|
-
mf.
|
88
|
+
mf.puts x.join(' ')
|
167
89
|
end
|
90
|
+
mf.close
|
168
91
|
end
|
169
92
|
|
170
|
-
|
171
|
-
it '
|
172
|
-
|
173
|
-
end
|
174
|
-
|
175
|
-
it 'should return an array of marked choices for the specified question set' do
|
176
|
-
@sheet.mark_array([0, 1, 13, 16, 31, 104, 21]).should == [[0], [1], [3,4], [2], [1], [], [0,1,2,3,4]]
|
93
|
+
context 'creating overlays' do
|
94
|
+
it 'registration highlighted' do
|
95
|
+
omr.save_registration "spec/out/registration/#{fn}"
|
177
96
|
end
|
178
97
|
|
179
|
-
it '
|
180
|
-
|
98
|
+
it 'highlights all choice cells' do
|
99
|
+
omr.overlay :highlight, :all
|
100
|
+
omr.save "spec/out/highlight/#{fn}"
|
181
101
|
end
|
182
|
-
end
|
183
102
|
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
[true, false, false, false, false],
|
188
|
-
[false, true, false, false, false],
|
189
|
-
[false, false, true, false, false],
|
190
|
-
[false, false, false, true, false],
|
191
|
-
[false, false, false, false, true],
|
192
|
-
]
|
103
|
+
it 'highlights marked cells' do
|
104
|
+
omr.overlay :highlight, :marked
|
105
|
+
omr.save "spec/out/highlight/marked-#{fn}"
|
193
106
|
end
|
194
|
-
end
|
195
107
|
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
@sheet.barcode.should == 1099511627775
|
108
|
+
it 'checks marked cells' do
|
109
|
+
omr.overlay :check, :marked
|
110
|
+
omr.save "spec/out/mark/#{fn}"
|
200
111
|
end
|
201
112
|
|
202
|
-
it '
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
s2.barcode.should == 8608
|
113
|
+
it 'outlines and crosses marked cells' do
|
114
|
+
omr.overlay :outline, standard_mark_array(24)
|
115
|
+
omr.overlay :check
|
116
|
+
omr.save "spec/out/outline/#{fn}"
|
207
117
|
end
|
208
118
|
|
209
|
-
it '
|
210
|
-
|
211
|
-
|
212
|
-
s2.barcode.should == sh.barcode_int
|
119
|
+
it 'highlights the barcode' do
|
120
|
+
omr.overlay :outline, :barcode
|
121
|
+
omr.save "spec/out/barcode/#{fn}"
|
213
122
|
end
|
214
123
|
end
|
215
|
-
|
216
|
-
end
|
217
|
-
|
218
|
-
context 'marking a problematic sheet' do
|
219
|
-
let(:sheet) { SheetOMR.new 'spec/samples/out-1.jpg', [5]*100, 'spec/samples/grid.yml' }
|
220
|
-
|
221
|
-
it 'highlights the registration' do
|
222
|
-
sheet.write_registration 'spec/out/problematic.jpg'
|
223
|
-
end
|
224
|
-
|
225
|
-
it 'highlights the barcode' do
|
226
|
-
sheet.highlight_barcode
|
227
|
-
sheet.write 'spec/out/barcode.jpg'
|
228
|
-
end
|
229
124
|
end
|
230
125
|
|
231
|
-
context 'systematic tests' do
|
126
|
+
context 'systematic tests', exclude: true do
|
232
127
|
let(:bila) { 'CCEBEBCEEACCDCABDBEBCADEADDCCCACCACDBBDAECDDABDEEBCEEDCBAAADEEEEDCADEABCBDECCCCDDDCABBECAADADBBEEABA'.split '' }
|
233
|
-
let(:bila0) { SheetOMR.new 'spec/samples/syst/bila0.jpg', [5]*100,
|
234
|
-
let(:bila1) { SheetOMR.new 'spec/samples/syst/bila1.jpg', [5]*100,
|
235
|
-
let(:bila2) { SheetOMR.new 'spec/samples/syst/bila2.jpg', [5]*100,
|
236
|
-
let(:bila3) { SheetOMR.new 'spec/samples/syst/bila3.jpg', [5]*100,
|
237
|
-
let(:bila4) { SheetOMR.new 'spec/samples/syst/bila4.jpg', [5]*100,
|
128
|
+
let(:bila0) { SheetOMR.new 'spec/samples/syst/bila0.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
|
129
|
+
let(:bila1) { SheetOMR.new 'spec/samples/syst/bila1.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
|
130
|
+
let(:bila2) { SheetOMR.new 'spec/samples/syst/bila2.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
|
131
|
+
let(:bila3) { SheetOMR.new 'spec/samples/syst/bila3.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
|
132
|
+
let(:bila4) { SheetOMR.new 'spec/samples/syst/bila4.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
|
238
133
|
let(:dald) { 'DDDBECAAADBAEEEAEEEBAACAEDBDECDBDCDCDDEDCCDCDBDCADEEDBCCBEBBAADDCDBBECBBBDEABADABADADBABAEABACBDADDA'.split '' }
|
239
|
-
let(:dald0) { SheetOMR.new 'spec/samples/syst/dald0.jpg', [5]*100,
|
240
|
-
let(:dald1) { SheetOMR.new 'spec/samples/syst/dald1.jpg', [5]*100,
|
241
|
-
let(:dald2) { SheetOMR.new 'spec/samples/syst/dald2.jpg', [5]*100,
|
242
|
-
let(:dald3) { SheetOMR.new 'spec/samples/syst/dald3.jpg', [5]*100,
|
243
|
-
let(:dald4) { SheetOMR.new 'spec/samples/syst/dald4.jpg', [5]*100,
|
134
|
+
let(:dald0) { SheetOMR.new 'spec/samples/syst/dald0.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
|
135
|
+
let(:dald1) { SheetOMR.new 'spec/samples/syst/dald1.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
|
136
|
+
let(:dald2) { SheetOMR.new 'spec/samples/syst/dald2.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
|
137
|
+
let(:dald3) { SheetOMR.new 'spec/samples/syst/dald3.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
|
138
|
+
let(:dald4) { SheetOMR.new 'spec/samples/syst/dald4.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
|
244
139
|
let(:cost) { 'ABBDDBAEAEBAADEAAECBCDBBDABABADEECCACBCAEDDAEBEABBCDABECAACEEEBADECBBEAADBBBEABDAEBDEEABBABEBEDDAEEC'.split '' }
|
245
|
-
let(:cost0) { SheetOMR.new 'spec/samples/syst/cost0.jpg', [5]*100,
|
246
|
-
let(:cost1) { SheetOMR.new 'spec/samples/syst/cost1.jpg', [5]*100,
|
247
|
-
let(:cost2) { SheetOMR.new 'spec/samples/syst/cost2.jpg', [5]*100,
|
248
|
-
let(:cost3) { SheetOMR.new 'spec/samples/syst/cost3.jpg', [5]*100,
|
249
|
-
let(:cost4) { SheetOMR.new 'spec/samples/syst/cost4.jpg', [5]*100,
|
140
|
+
let(:cost0) { SheetOMR.new 'spec/samples/syst/cost0.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
|
141
|
+
let(:cost1) { SheetOMR.new 'spec/samples/syst/cost1.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
|
142
|
+
let(:cost2) { SheetOMR.new 'spec/samples/syst/cost2.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
|
143
|
+
let(:cost3) { SheetOMR.new 'spec/samples/syst/cost3.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
|
144
|
+
let(:cost4) { SheetOMR.new 'spec/samples/syst/cost4.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
|
250
145
|
let(:bone) { 'CECBBABAECADEDCACBBDEECBADBECDCEDECABCAADCBDEDACAEEDCCADBEDCEBCCBBDCCACDEDDAAECEBDBADCBAAEBAEDABCBDC'.split '' }
|
251
|
-
let(:bone0) { SheetOMR.new 'spec/samples/syst/bone0.jpg', [5]*100,
|
252
|
-
let(:bone1) { SheetOMR.new 'spec/samples/syst/bone1.jpg', [5]*100,
|
253
|
-
let(:bone2) { SheetOMR.new 'spec/samples/syst/bone2.jpg', [5]*100,
|
146
|
+
let(:bone0) { SheetOMR.new 'spec/samples/syst/bone0.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
|
147
|
+
let(:bone1) { SheetOMR.new 'spec/samples/syst/bone1.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
|
148
|
+
let(:bone2) { SheetOMR.new 'spec/samples/syst/bone2.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
|
254
149
|
let(:barr) { 'ACECAAADDBCECCCDBEBECDEDAECEDDEEDCDEADDCCBCCCBBEACBCAEDEEDDDABBBBABEBDCEADEEDEBCBADBCEDCDBACEBCBDCDA'.split '' }
|
255
|
-
let(:barr0) { SheetOMR.new 'spec/samples/syst/barr0.jpg', [5]*100,
|
256
|
-
let(:barr1) { SheetOMR.new 'spec/samples/syst/barr1.jpg', [5]*100,
|
257
|
-
let(:barr2) { SheetOMR.new 'spec/samples/syst/barr2.jpg', [5]*100,
|
150
|
+
let(:barr0) { SheetOMR.new 'spec/samples/syst/barr0.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
|
151
|
+
let(:barr1) { SheetOMR.new 'spec/samples/syst/barr1.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
|
152
|
+
let(:barr2) { SheetOMR.new 'spec/samples/syst/barr2.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
|
258
153
|
|
259
154
|
it 'checks bila' do
|
260
155
|
expect(bila0.mark_char_array.flatten).to eq(bila)
|
data/spec/mork/sheet_pdf_spec.rb
CHANGED
@@ -40,8 +40,8 @@ module Mork
|
|
40
40
|
end
|
41
41
|
|
42
42
|
it 'creates a basic PDF sheet' do
|
43
|
-
s = SheetPDF.new(content
|
44
|
-
s.save('spec/out/sheet.pdf')
|
43
|
+
s = SheetPDF.new(content)
|
44
|
+
s.save('spec/out/pdf/sheet.pdf')
|
45
45
|
end
|
46
46
|
|
47
47
|
it 'creates a boxed PDF sheet' do
|
@@ -52,39 +52,38 @@ module Mork
|
|
52
52
|
signature: 'Signature'
|
53
53
|
}
|
54
54
|
s = SheetPDF.new(content.merge({header: h}), 'spec/samples/boxy.yml')
|
55
|
-
s.save('spec/out/boxy.pdf')
|
55
|
+
s.save('spec/out/pdf/boxy.pdf')
|
56
56
|
end
|
57
57
|
|
58
58
|
it 'creates a basic PDF sheet with a code of 15' do
|
59
59
|
s = SheetPDF.new(content.merge({barcode: 15}))
|
60
|
-
s.save('spec/out/sheet16.pdf')
|
60
|
+
s.save('spec/out/pdf/sheet16.pdf')
|
61
61
|
end
|
62
62
|
|
63
63
|
it 'creates a basic PDF sheet with a code of 666666666666' do
|
64
64
|
s = SheetPDF.new(content.merge({barcode: 666666666666}))
|
65
|
-
s.save('spec/out/sheet666.pdf')
|
65
|
+
s.save('spec/out/pdf/sheet666.pdf')
|
66
66
|
end
|
67
67
|
|
68
68
|
it 'creates a PDF sheet with the maximum possible barcode' do
|
69
69
|
s = SheetPDF.new(content.merge({barcode: 1099511627775}))
|
70
|
-
s.save('spec/out/maxcode.pdf')
|
70
|
+
s.save('spec/out/pdf/maxcode.pdf')
|
71
71
|
end
|
72
72
|
|
73
73
|
it 'creates a PDF sheet with 160 items' do
|
74
74
|
s = SheetPDF.new(content.merge({choices: [5] * 160}), 'spec/samples/grid160.yml')
|
75
|
-
s.save('spec/out/i160.pdf')
|
76
|
-
# system 'open spec/out/i160.pdf'
|
75
|
+
s.save('spec/out/pdf/i160.pdf')
|
77
76
|
end
|
78
77
|
|
79
78
|
it 'creates a PDF sheet with unequal choices per item' do
|
80
79
|
s = SheetPDF.new(content.merge({choices: [5, 4, 3, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2, 1]}), 'spec/samples/layout.yml')
|
81
|
-
s.save('spec/out/uneq.pdf')
|
80
|
+
s.save('spec/out/pdf/uneq.pdf')
|
82
81
|
end
|
83
82
|
|
84
83
|
it 'creates 20 PDF sheets' do
|
85
84
|
c = content
|
86
85
|
s = SheetPDF.new([c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c])
|
87
|
-
s.save('spec/out/p20.pdf')
|
86
|
+
s.save('spec/out/pdf/p20.pdf')
|
88
87
|
end
|
89
88
|
end
|
90
89
|
end
|
File without changes
|
data/spec/samples/angolo.jpg
CHANGED
File without changes
|
Binary file
|
Binary file
|
data/spec/samples/boxy.yml
CHANGED
File without changes
|
data/spec/samples/grid.yml
CHANGED
File without changes
|
data/spec/samples/grid160.yml
CHANGED
File without changes
|
@@ -0,0 +1,56 @@
|
|
1
|
+
page_size: # all measurements in mm
|
2
|
+
width: 210 # width of the paper sheet
|
3
|
+
height: 297 # height of the paper sheet
|
4
|
+
reg_marks:
|
5
|
+
margin: 10 # distance from each page border to registration mark center
|
6
|
+
radius: 2.5 # registration mark radius
|
7
|
+
offset: 2 # distance between the search area and each page border (*)
|
8
|
+
crop: 20
|
9
|
+
blur: 2
|
10
|
+
dilate: 5
|
11
|
+
header:
|
12
|
+
name: # ‘name’ is just a label; you can add arbitrary header elements
|
13
|
+
top: 5 # margin relative to registration frame top side
|
14
|
+
left: 15 # margin relative to registration frame left side
|
15
|
+
width: 170 # text will be fitted to this width
|
16
|
+
height: 7 # text will be fitted to this height
|
17
|
+
size: 14 # font size
|
18
|
+
title:
|
19
|
+
top: 15
|
20
|
+
left: 15
|
21
|
+
width: 180
|
22
|
+
height: 12
|
23
|
+
size: 12
|
24
|
+
code:
|
25
|
+
top: 5
|
26
|
+
left: 165
|
27
|
+
width: 20
|
28
|
+
height: 10
|
29
|
+
size: 14
|
30
|
+
signature:
|
31
|
+
top: 30
|
32
|
+
left: 7.5
|
33
|
+
width: 120
|
34
|
+
height: 15
|
35
|
+
size: 7
|
36
|
+
box: true # header element will be enclosed in a box
|
37
|
+
items:
|
38
|
+
top: 55.5 # response area margin, relative to reg frame
|
39
|
+
left: 10.5 # response area margin, relative to reg frame
|
40
|
+
rows: 30 # number of items per column
|
41
|
+
columns: 4 # number of columns
|
42
|
+
column_width: 44 #
|
43
|
+
x_spacing: 7 # horizontal distance between ajacent cell centers
|
44
|
+
y_spacing: 7 # vertical distance between ajacent cell centers
|
45
|
+
cell_width: 6 # width of each choice and calibration cell
|
46
|
+
cell_height: 5 # height of each choice and calibration cell
|
47
|
+
max_cells: 5 # maximum number of choices per item
|
48
|
+
font_size: 9 # size of both the item number and choice cell letter
|
49
|
+
number_width: 8 #
|
50
|
+
number_margin: 2 # margin between
|
51
|
+
barcode:
|
52
|
+
bits: 40 # the maximum sheet identifier is 2 to the power or bits
|
53
|
+
left: 15 # distance between registration frame side and the first barcode bit
|
54
|
+
width: 3 # width of each barcode bit
|
55
|
+
height: 2.5 # height of each barcode bit from the registration frame bottom side
|
56
|
+
spacing: 4 # horizontal distance between adjacent barcode bit centers
|