rtesseract 2.0.1 → 2.2.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
  SHA1:
3
- metadata.gz: 6eae58279cf744227e79b7bbc9180f7aea852547
4
- data.tar.gz: 3836aa96d24b7f1a0b957cf803553f547cc33544
3
+ metadata.gz: cb2f55f98e4b22827068fd2284a893788d72a751
4
+ data.tar.gz: f6b3ff2bfff6d4e250c75b239354485670b3d732
5
5
  SHA512:
6
- metadata.gz: 0ef57359c7c7f43094a50838b6d29d28d7808c9cadd8f2b8514c613be030161f8d640c41ba3d403c00fb59fdf85ffcbc57795f6c65b8418ad348eb1a6c07e901
7
- data.tar.gz: ff5f0f94c8039bd0b38b0c9ec2618b4c38b07b9707e28ff29a3bb943abc85d5afaa543dfba1ba2b9e565d056ea558eda9b7f6d222a6adb43614cd86c6e8fdcac
6
+ metadata.gz: ba2dcb1878a1c98013a6c4c0ad4a583a8b830faf01fede4df8b39a1d6e492ef79cc3610dee60ab856937e7ac7a3c7ae8789ae74fd32f80dbc910cd488a5f0651
7
+ data.tar.gz: aacbcfe446dd8050a6d45b78dab5d38468cb6110c4c6216c1877bfa2bbee08bdc6763e9b0c5c0ec7fe40aac8fc43a553da533b33449c60f40d21f6e6c8034faa
data/.rspec CHANGED
@@ -1 +1,2 @@
1
1
  --color
2
+ --order rand
data/.travis.yml CHANGED
@@ -1,13 +1,13 @@
1
+ sudo: required
2
+ dist: trusty
1
3
  language: ruby
2
4
  addons:
3
5
  apt:
4
6
  packages:
5
7
  - tesseract-ocr
6
8
 
7
- sudo: false
8
9
  rvm:
9
- - 1.9.3
10
- - 2.0.0
11
- - 2.1.5
12
- - 2.2.2
13
- - 2.3.0
10
+ - 2.1.10
11
+ - 2.2.6
12
+ - 2.3.3
13
+ - 2.4.0
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## v2.1.0
2
+
3
+ #### Added
4
+
5
+ * Support to generate searchable PDF
6
+
1
7
  ## v2.0.1
2
8
 
3
9
  #### Changed
data/Gemfile CHANGED
@@ -7,8 +7,9 @@ group :development do
7
7
  gem 'rspec'
8
8
  gem 'rdoc'
9
9
  gem 'bundler'
10
- gem 'jeweler', '~> 2.1.1'
10
+ gem 'jeweler'
11
11
  gem 'simplecov'
12
+ gem 'json'
12
13
  gem 'coveralls', require: false
13
14
  end
14
15
 
data/Gemfile.lock CHANGED
@@ -2,83 +2,87 @@ GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
4
  addressable (2.4.0)
5
- builder (3.2.2)
6
- coveralls (0.8.13)
7
- json (~> 1.8)
8
- simplecov (~> 0.11.0)
9
- term-ansicolor (~> 1.3)
10
- thor (~> 0.19.1)
11
- tins (~> 1.6.0)
5
+ builder (3.2.3)
6
+ coveralls (0.7.2)
7
+ multi_json (~> 1.3)
8
+ rest-client (= 1.6.7)
9
+ simplecov (>= 0.7)
10
+ term-ansicolor (= 1.2.2)
11
+ thor (= 0.18.1)
12
12
  descendants_tracker (0.0.4)
13
13
  thread_safe (~> 0.3, >= 0.3.1)
14
- diff-lcs (1.2.5)
14
+ diff-lcs (1.3)
15
15
  docile (1.1.5)
16
16
  faraday (0.9.2)
17
17
  multipart-post (>= 1.2, < 3)
18
18
  git (1.3.0)
19
- github_api (0.13.1)
19
+ github_api (0.16.0)
20
20
  addressable (~> 2.4.0)
21
21
  descendants_tracker (~> 0.0.4)
22
22
  faraday (~> 0.8, < 0.10)
23
23
  hashie (>= 3.4)
24
- multi_json (>= 1.7.5, < 2.0)
25
- oauth2
26
- hashie (3.4.3)
27
- highline (1.7.8)
28
- jeweler (2.1.1)
24
+ mime-types (>= 1.16, < 3.0)
25
+ oauth2 (~> 1.0)
26
+ hashie (3.5.7)
27
+ highline (1.7.10)
28
+ jeweler (2.3.7)
29
29
  builder
30
- bundler (>= 1.0)
30
+ bundler (>= 1)
31
31
  git (>= 1.2.5)
32
- github_api
32
+ github_api (~> 0.16.0)
33
33
  highline (>= 1.6.15)
34
34
  nokogiri (>= 1.5.10)
35
+ psych (~> 2.2)
35
36
  rake
36
37
  rdoc
37
- semver
38
- json (1.8.3)
39
- jwt (1.5.1)
40
- mini_magick (4.5.1)
41
- mini_portile2 (2.0.0)
42
- multi_json (1.11.2)
43
- multi_xml (0.5.5)
38
+ semver2
39
+ json (2.1.0)
40
+ jwt (1.5.6)
41
+ mime-types (2.99.3)
42
+ mini_magick (4.8.0)
43
+ mini_portile2 (2.3.0)
44
+ multi_json (1.12.2)
45
+ multi_xml (0.6.0)
44
46
  multipart-post (2.0.0)
45
- nokogiri (1.6.7.2)
46
- mini_portile2 (~> 2.0.0.rc2)
47
- oauth2 (1.1.0)
48
- faraday (>= 0.8, < 0.10)
49
- jwt (~> 1.0, < 1.5.2)
47
+ nokogiri (1.8.1)
48
+ mini_portile2 (~> 2.3.0)
49
+ oauth2 (1.4.0)
50
+ faraday (>= 0.8, < 0.13)
51
+ jwt (~> 1.0)
50
52
  multi_json (~> 1.3)
51
53
  multi_xml (~> 0.5)
52
54
  rack (>= 1.2, < 3)
53
- rack (1.6.4)
54
- rake (11.1.2)
55
- rdoc (4.2.2)
56
- json (~> 1.4)
57
- rmagick (2.15.4)
58
- rspec (3.4.0)
59
- rspec-core (~> 3.4.0)
60
- rspec-expectations (~> 3.4.0)
61
- rspec-mocks (~> 3.4.0)
62
- rspec-core (3.4.4)
63
- rspec-support (~> 3.4.0)
64
- rspec-expectations (3.4.0)
55
+ psych (2.2.4)
56
+ rack (2.0.3)
57
+ rake (12.3.0)
58
+ rdoc (6.0.1)
59
+ rest-client (1.6.7)
60
+ mime-types (>= 1.16)
61
+ rmagick (2.16.0)
62
+ rspec (3.7.0)
63
+ rspec-core (~> 3.7.0)
64
+ rspec-expectations (~> 3.7.0)
65
+ rspec-mocks (~> 3.7.0)
66
+ rspec-core (3.7.1)
67
+ rspec-support (~> 3.7.0)
68
+ rspec-expectations (3.7.0)
65
69
  diff-lcs (>= 1.2.0, < 2.0)
66
- rspec-support (~> 3.4.0)
67
- rspec-mocks (3.4.1)
70
+ rspec-support (~> 3.7.0)
71
+ rspec-mocks (3.7.0)
68
72
  diff-lcs (>= 1.2.0, < 2.0)
69
- rspec-support (~> 3.4.0)
70
- rspec-support (3.4.1)
71
- semver (1.0.1)
72
- simplecov (0.11.2)
73
+ rspec-support (~> 3.7.0)
74
+ rspec-support (3.7.0)
75
+ semver2 (3.4.2)
76
+ simplecov (0.15.1)
73
77
  docile (~> 1.1.0)
74
- json (~> 1.8)
78
+ json (>= 1.8, < 3)
75
79
  simplecov-html (~> 0.10.0)
76
- simplecov-html (0.10.0)
77
- term-ansicolor (1.3.2)
78
- tins (~> 1.0)
79
- thor (0.19.1)
80
- thread_safe (0.3.5)
81
- tins (1.6.0)
80
+ simplecov-html (0.10.2)
81
+ term-ansicolor (1.2.2)
82
+ tins (~> 0.8)
83
+ thor (0.18.1)
84
+ thread_safe (0.3.6)
85
+ tins (0.13.2)
82
86
 
83
87
  PLATFORMS
84
88
  ruby
@@ -86,7 +90,8 @@ PLATFORMS
86
90
  DEPENDENCIES
87
91
  bundler
88
92
  coveralls
89
- jeweler (~> 2.1.1)
93
+ jeweler
94
+ json
90
95
  mini_magick
91
96
  nokogiri
92
97
  rdoc
@@ -95,4 +100,4 @@ DEPENDENCIES
95
100
  simplecov
96
101
 
97
102
  BUNDLED WITH
98
- 1.11.2
103
+ 1.16.1
data/README.rdoc CHANGED
@@ -16,6 +16,8 @@ To work properly rtesseract are needed:
16
16
 
17
17
  Atention: Version 1.0.0 works fine with Ruby 2.0 and tesseract 3.0 and lower versions of rtesseract works fine with Ruby 1.8 and tesseract 2.0.4.
18
18
 
19
+ PDF support requires a newer version of tesseract, specifically V.3.03 or above.
20
+
19
21
  == EXAMPLE USAGE
20
22
 
21
23
  It's very simple to use rtesseract:
@@ -23,7 +25,19 @@ It's very simple to use rtesseract:
23
25
  === CONVERT IMAGE TO STRING
24
26
 
25
27
  image = RTesseract.new("my_image.jpg")
26
- image.to_s #Getting the value
28
+ image.to_s # Getting the value
29
+
30
+ === CONVERT IMAGE TO SEARCHABLE PDF
31
+
32
+ image = RTesseract.new("my_image.jpg")
33
+ image.to_pdf # Getting the pdf path
34
+ image.to_s # Still can get the value only.
35
+ # ...
36
+ # some stuff
37
+ # ...
38
+ image.clean # to delete file once finished
39
+
40
+ This will preserve the image colors, pictures and structure in the generated pdf.
27
41
 
28
42
  === CHANGE THE IMAGE
29
43
 
@@ -89,6 +103,7 @@ Language Options
89
103
  * por - Portuguese
90
104
  * spa - Spanish
91
105
  * vie - Vietnamese
106
+ * or any other supported by tesseract.
92
107
  Note: Make sure you have installed the language to tesseract
93
108
 
94
109
  Other Options
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.0.1
1
+ 2.2.0
@@ -21,10 +21,10 @@ class RTesseract
21
21
  cat = source.is_a?(Pathname) ? read_with_processor(source.to_s) : source
22
22
  cat.format('tif') do |c|
23
23
  c.compress 'None'
24
- c.alpha 'off'
24
+ c.alpha 'off' if MiniMagick.cli != :graphicsmagick
25
25
  end
26
26
  cat.crop("#{points[:w]}x#{points[:h]}+#{points[:x]}+#{points[:y]}") if points.is_a?(Hash) && points.values.compact != []
27
- cat.alpha 'off'
27
+ cat.alpha 'off' if MiniMagick.cli != :graphicsmagick
28
28
  cat.write tmp_file.path.to_s
29
29
  tmp_file
30
30
  end
@@ -40,4 +40,4 @@ class RTesseract
40
40
  end
41
41
  end
42
42
  end
43
- end
43
+ end
@@ -3,7 +3,7 @@ class RTesseract
3
3
  # Read image from memory blob
4
4
  def self.read(src = nil, options = {})
5
5
  fail RTesseract::ImageNotSelectedError if src.nil?
6
- processor = RTesseract::Processor.choose_processor!(options.option(:processor, nil))
6
+ processor = RTesseract::Processor.choose_processor!(options[:processor])
7
7
  image = processor.read_with_processor(src.to_s)
8
8
  yield(image)
9
9
  object = RTesseract.new('', options).from_blob(image.to_blob)
@@ -31,4 +31,4 @@ class RTesseract
31
31
  rescue => error
32
32
  raise RTesseract::ConversionError.new(error), error, caller
33
33
  end
34
- end
34
+ end
@@ -29,7 +29,7 @@ class RTesseract
29
29
 
30
30
  # Read the result file
31
31
  def parse_file
32
- html = Nokogiri::HTML(File.read(text_file_with_ext))
32
+ html = Nokogiri::HTML(File.read(file_with_ext))
33
33
  html.css('span.ocrx_word, span.ocr_word')
34
34
  end
35
35
 
@@ -42,7 +42,7 @@ class RTesseract
42
42
 
43
43
  # Move file html to hocr
44
44
  def after_convert_hook
45
- FileUtils.mv(text_file_with_ext('.html'), text_file_with_ext) rescue nil
45
+ FileUtils.mv(file_with_ext('.html'), file_with_ext) rescue nil
46
46
  end
47
47
 
48
48
  # Output value
@@ -16,7 +16,7 @@ class RTesseract
16
16
 
17
17
  # Read the result file
18
18
  def parse_file
19
- File.read(text_file_with_ext).to_s
19
+ File.read(file_with_ext).to_s
20
20
  end
21
21
 
22
22
  def convert_text
@@ -14,7 +14,7 @@ class RTesseract
14
14
 
15
15
  # Configuration class
16
16
  class Configuration
17
- attr_accessor :processor, :lang, :psm, :tessdata_dir, :user_words, :user_patterns, :command, :debug, :options_cmd
17
+ attr_accessor :processor, :lang, :psm, :oem, :tessdata_dir, :user_words, :user_patterns, :command, :debug, :options_cmd
18
18
 
19
19
  def initialize
20
20
  @processor = 'rmagick'
@@ -43,6 +43,15 @@ class RTesseract
43
43
  def self.configure
44
44
  self.configuration ||= Configuration.new
45
45
  yield(configuration)
46
+ self.clear_pdf_option
47
+ end
48
+
49
+ # Clear pdf option
50
+ def self.clear_pdf_option
51
+ if self.configuration.options_cmd
52
+ self.configuration.options_cmd.delete('pdf')
53
+ self.configuration.options_cmd.delete(:pdf)
54
+ end
46
55
  end
47
56
 
48
57
  # Default command
@@ -57,9 +66,10 @@ class RTesseract
57
66
  RTesseract::Configuration.new.tap do |config|
58
67
  config.command = config.option(options, :command, RTesseract.default_command)
59
68
  config.processor = config.option(options, :processor, 'rmagick')
60
- config.load_options(options, [:lang, :psm, :tessdata_dir, :user_words, :user_patterns])
69
+ config.load_options(options, [:lang, :psm, :oem, :tessdata_dir, :user_words, :user_patterns])
61
70
  config.debug = config.option(options, :debug, false)
62
- config.options_cmd = [options.option(:options, nil)].flatten.compact
71
+ pdf_opts = lambda { |o| o == 'pdf' || o == :pdf }
72
+ config.options_cmd = [options.option(:options, nil)].delete_if(&pdf_opts).flatten.compact
63
73
  end
64
74
  end
65
- end
75
+ end
@@ -12,4 +12,10 @@ class RTesseract
12
12
  class ConversionError < ErrorWithMemory; end
13
13
  class ImageNotSelectedError < ErrorWithMemory; end
14
14
  class TempFilesNotRemovedError < ErrorWithMemory; end
15
+
16
+ class TesseractVersionError < StandardError
17
+ def initialize
18
+ super "Tesseract version is unknown or below 3.03 which is required for pdf output."
19
+ end
20
+ end
15
21
  end
@@ -1,3 +1,5 @@
1
+ require 'open3'
2
+
1
3
  # RTesseract
2
4
  class RTesseract
3
5
  # Some utils methods
@@ -22,6 +24,14 @@ class RTesseract
22
24
  end
23
25
  true
24
26
  end
27
+
28
+ # Extract tesseract version number
29
+ def self.version_number
30
+ output, st = Open3.capture2e(RTesseract.default_command, "--version")
31
+
32
+ version = output.split("\n")[0].split(" ")[1].split('.')[0, 2].join('.')
33
+ Float(version) rescue nil
34
+ end
25
35
  end
26
36
  end
27
37
 
@@ -31,4 +41,4 @@ class Hash
31
41
  def option(attr_name, default)
32
42
  delete(attr_name.to_s) || delete(attr_name) || default
33
43
  end
34
- end
44
+ end
@@ -0,0 +1,47 @@
1
+ # encoding: UTF-8
2
+ # RTesseract
3
+ class RTesseract
4
+ # Alternative approach to Mixed when you want to read from specific areas.
5
+ # Requires `-psm 4` which means the text must be "a single column of text of variable sizes".
6
+ class Uzn < RTesseract
7
+ attr_reader :areas
8
+ DEFAULT_ALPHABET = 'Text/Latin'
9
+
10
+ def initialize(src = '', options = {})
11
+ @areas = options.delete(:areas) || []
12
+ @alphabet = options.delete(:alphabet) || DEFAULT_ALPHABET
13
+ super(src, options.merge(psm: 4))
14
+ yield self if block_given?
15
+ end
16
+
17
+ # Add areas
18
+ def area(points)
19
+ areas << points
20
+ end
21
+
22
+ def convert_command
23
+ @image = image
24
+ write_uzn_file
25
+ `#{configuration.command} "#{@image}" "#{file_dest}" #{lang} #{psm} #{tessdata_dir} #{user_words} #{user_patterns} #{config_file} #{clear_console_output} #{options_cmd.join(' ')}`
26
+ end
27
+
28
+ def after_convert_hook
29
+ RTesseract::Utils.remove_files([@uzn_file])
30
+ end
31
+
32
+ private
33
+
34
+ def write_uzn_file
35
+ folder = File.dirname(@image)
36
+ basename = File.basename(@image, '.tif')
37
+ @uzn_file = File.new("#{folder}/#{basename}.uzn", File::CREAT|File::TRUNC|File::RDWR)
38
+
39
+ areas.each do |points|
40
+ s = "#{points[:x]} #{points[:y]} #{points[:w]} #{points[:h]} #{@alphabet}\n"
41
+ @uzn_file.write(s)
42
+ @uzn_file.flush
43
+ end
44
+ end
45
+
46
+ end
47
+ end
data/lib/rtesseract.rb CHANGED
@@ -15,10 +15,9 @@ class RTesseract
15
15
  def initialize(src = '', options = {})
16
16
  self.configuration = RTesseract.local_config(options)
17
17
  @options = options || {}
18
- @value = nil
19
18
  @points = {}
20
19
  @processor = RTesseract::Processor.choose_processor!(configuration.processor)
21
- @source = @processor.image?(src) ? src : Pathname.new(src)
20
+ self.source = src
22
21
  initialize_hook
23
22
  end
24
23
 
@@ -29,6 +28,7 @@ class RTesseract
29
28
  # Define the source
30
29
  def source=(src)
31
30
  @value = nil
31
+ @pdf_path = nil
32
32
  @source = @processor.image?(src) ? src : Pathname.new(src)
33
33
  end
34
34
 
@@ -70,6 +70,11 @@ class RTesseract
70
70
  option_to_string('-psm', configuration.psm)
71
71
  end
72
72
 
73
+ # Engine Mode
74
+ def oem
75
+ option_to_string '--oem', configuration.oem
76
+ end
77
+
73
78
  # Tessdata Dir
74
79
  def tessdata_dir
75
80
  option_to_string('--tessdata-dir', configuration.tessdata_dir)
@@ -127,24 +132,50 @@ class RTesseract
127
132
  '.txt'
128
133
  end
129
134
 
135
+ # Detect version number
136
+ def tesseract_version
137
+ RTesseract::Utils.version_number
138
+ end
139
+
140
+
130
141
  # Rand file path
131
- def text_file
132
- @text_file = Pathname.new(Dir.tmpdir).join("#{Time.now.to_f}#{rand(1500)}").to_s
142
+ def file_dest
143
+ @file_dest = Pathname.new(Dir.tmpdir).join("#{Time.now.to_f}#{rand(1500)}").to_s
133
144
  end
134
145
 
135
- # Full path of file with extension
136
- def text_file_with_ext(ext = nil)
137
- [@text_file, ext || file_ext].join('')
146
+ # Full path of file with txt extension
147
+ def file_with_ext(ext = nil)
148
+ [@file_dest, ext || file_ext].join('')
138
149
  end
139
150
 
140
151
  # Run command
141
152
  def convert_command
142
- `#{configuration.command} "#{image}" "#{text_file}" #{lang} #{psm} #{tessdata_dir} #{user_words} #{user_patterns} #{config_file} #{clear_console_output} #{configuration.options_cmd.join(' ')}`
153
+ `#{configuration.command} "#{image}" "#{file_dest}" #{lang} #{oem} #{psm} #{tessdata_dir} #{user_words} #{user_patterns} #{config_file} #{clear_console_output} #{options_cmd.join(' ')}`
154
+ end
155
+
156
+ # Is pdf output?
157
+ def pdf?
158
+ options_cmd.include? 'pdf'
143
159
  end
144
160
 
145
161
  # Read result file
146
162
  def convert_text
147
- @value = File.read(text_file_with_ext).to_s
163
+ @value = File.read(file_with_ext).to_s
164
+ end
165
+
166
+ # Store pdf result path
167
+ def convert_pdf
168
+ @pdf_path = file_with_ext('.pdf')
169
+ end
170
+
171
+ # Convert result to proper type
172
+ def convert_result
173
+ if pdf?
174
+ convert_pdf
175
+ else
176
+ convert_text
177
+ RTesseract::Utils.remove_files([@image, file_with_ext])
178
+ end
148
179
  end
149
180
 
150
181
  # Hook to convert
@@ -155,15 +186,14 @@ class RTesseract
155
186
  def convert
156
187
  convert_command
157
188
  after_convert_hook
158
- convert_text
159
- RTesseract::Utils.remove_files([@image, text_file_with_ext])
189
+ convert_result
160
190
  rescue => error
161
191
  raise RTesseract::ConversionError.new(error), error, caller
162
192
  end
163
193
 
164
194
  # Output value
165
195
  def to_s
166
- return @value if @value != nil
196
+ return @value if @value
167
197
 
168
198
  if @processor.image?(@source) || @source.file?
169
199
  convert
@@ -175,11 +205,34 @@ class RTesseract
175
205
 
176
206
  # Remove spaces and break-lines
177
207
  def to_s_without_spaces
178
- to_s.delete(' ').delete("\n").delete("\r")
208
+ to_s.gsub(/\s/, '')
179
209
  end
210
+
211
+ # Output pdf path
212
+ def to_pdf
213
+ return @pdf_path if @pdf_path
214
+
215
+ fail TesseractVersionError.new if tesseract_version.nil? || tesseract_version < 3.03
216
+
217
+ if @processor.image?(@source) || @source.file?
218
+ options_cmd << 'pdf'
219
+ convert
220
+ options_cmd.delete('pdf')
221
+ @pdf_path
222
+ else
223
+ fail RTesseract::ImageNotSelectedError.new(@source)
224
+ end
225
+ end
226
+
227
+ # Destroy pdf file
228
+ def clean
229
+ RTesseract::Utils.remove_files([@pdf_path])
230
+ end
231
+
180
232
  end
181
233
 
182
234
  require 'rtesseract/mixed'
235
+ require 'rtesseract/uzn'
183
236
  require 'rtesseract/box'
184
237
  require 'rtesseract/box_char'
185
238
  require 'rtesseract/blob'
data/rtesseract.gemspec CHANGED
@@ -2,18 +2,18 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: rtesseract 2.0.1 ruby lib
5
+ # stub: rtesseract 2.2.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
- s.name = "rtesseract"
9
- s.version = "2.0.1"
8
+ s.name = "rtesseract".freeze
9
+ s.version = "2.2.0"
10
10
 
11
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
- s.require_paths = ["lib"]
13
- s.authors = ["Danilo Jeremias da Silva"]
14
- s.date = "2016-05-17"
15
- s.description = "Ruby library for working with the Tesseract OCR."
16
- s.email = "dannnylo@gmail.com"
11
+ s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
+ s.require_paths = ["lib".freeze]
13
+ s.authors = ["Danilo Jeremias da Silva".freeze]
14
+ s.date = "2018-01-05"
15
+ s.description = "Ruby library for working with the Tesseract OCR.".freeze
16
+ s.email = "dannnylo@gmail.com".freeze
17
17
  s.extra_rdoc_files = [
18
18
  "LICENSE.txt",
19
19
  "README.rdoc"
@@ -41,6 +41,7 @@ Gem::Specification.new do |s|
41
41
  "lib/rtesseract/mixed.rb",
42
42
  "lib/rtesseract/processor.rb",
43
43
  "lib/rtesseract/utils.rb",
44
+ "lib/rtesseract/uzn.rb",
44
45
  "rtesseract.gemspec",
45
46
  "spec/configs/eng.user-words.txt",
46
47
  "spec/images/README.pdf",
@@ -48,6 +49,7 @@ Gem::Specification.new do |s|
48
49
  "spec/images/mixed.tif",
49
50
  "spec/images/orientation_reverse.png",
50
51
  "spec/images/test with spaces.tif",
52
+ "spec/images/test-pdf.png",
51
53
  "spec/images/test.bmp",
52
54
  "spec/images/test.jpg",
53
55
  "spec/images/test.png",
@@ -58,41 +60,45 @@ Gem::Specification.new do |s|
58
60
  "spec/rtesseract_box_spec.rb",
59
61
  "spec/rtesseract_mixed_spec.rb",
60
62
  "spec/rtesseract_spec.rb",
63
+ "spec/rtesseract_uzn_spec.rb",
61
64
  "spec/spec_helper.rb"
62
65
  ]
63
- s.homepage = "http://github.com/dannnylo/rtesseract"
64
- s.licenses = ["MIT"]
65
- s.rubygems_version = "2.4.8"
66
- s.summary = "Ruby library for working with the Tesseract OCR."
66
+ s.homepage = "http://github.com/dannnylo/rtesseract".freeze
67
+ s.licenses = ["MIT".freeze]
68
+ s.rubygems_version = "2.6.14".freeze
69
+ s.summary = "Ruby library for working with the Tesseract OCR.".freeze
67
70
 
68
71
  if s.respond_to? :specification_version then
69
72
  s.specification_version = 4
70
73
 
71
74
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
72
- s.add_runtime_dependency(%q<nokogiri>, [">= 0"])
73
- s.add_development_dependency(%q<rspec>, [">= 0"])
74
- s.add_development_dependency(%q<rdoc>, [">= 0"])
75
- s.add_development_dependency(%q<bundler>, [">= 0"])
76
- s.add_development_dependency(%q<jeweler>, ["~> 2.1.1"])
77
- s.add_development_dependency(%q<simplecov>, [">= 0"])
78
- s.add_development_dependency(%q<coveralls>, [">= 0"])
75
+ s.add_runtime_dependency(%q<nokogiri>.freeze, [">= 0"])
76
+ s.add_development_dependency(%q<rspec>.freeze, [">= 0"])
77
+ s.add_development_dependency(%q<rdoc>.freeze, [">= 0"])
78
+ s.add_development_dependency(%q<bundler>.freeze, [">= 0"])
79
+ s.add_development_dependency(%q<jeweler>.freeze, [">= 0"])
80
+ s.add_development_dependency(%q<simplecov>.freeze, [">= 0"])
81
+ s.add_development_dependency(%q<json>.freeze, [">= 0"])
82
+ s.add_development_dependency(%q<coveralls>.freeze, [">= 0"])
79
83
  else
80
- s.add_dependency(%q<nokogiri>, [">= 0"])
81
- s.add_dependency(%q<rspec>, [">= 0"])
82
- s.add_dependency(%q<rdoc>, [">= 0"])
83
- s.add_dependency(%q<bundler>, [">= 0"])
84
- s.add_dependency(%q<jeweler>, ["~> 2.1.1"])
85
- s.add_dependency(%q<simplecov>, [">= 0"])
86
- s.add_dependency(%q<coveralls>, [">= 0"])
84
+ s.add_dependency(%q<nokogiri>.freeze, [">= 0"])
85
+ s.add_dependency(%q<rspec>.freeze, [">= 0"])
86
+ s.add_dependency(%q<rdoc>.freeze, [">= 0"])
87
+ s.add_dependency(%q<bundler>.freeze, [">= 0"])
88
+ s.add_dependency(%q<jeweler>.freeze, [">= 0"])
89
+ s.add_dependency(%q<simplecov>.freeze, [">= 0"])
90
+ s.add_dependency(%q<json>.freeze, [">= 0"])
91
+ s.add_dependency(%q<coveralls>.freeze, [">= 0"])
87
92
  end
88
93
  else
89
- s.add_dependency(%q<nokogiri>, [">= 0"])
90
- s.add_dependency(%q<rspec>, [">= 0"])
91
- s.add_dependency(%q<rdoc>, [">= 0"])
92
- s.add_dependency(%q<bundler>, [">= 0"])
93
- s.add_dependency(%q<jeweler>, ["~> 2.1.1"])
94
- s.add_dependency(%q<simplecov>, [">= 0"])
95
- s.add_dependency(%q<coveralls>, [">= 0"])
94
+ s.add_dependency(%q<nokogiri>.freeze, [">= 0"])
95
+ s.add_dependency(%q<rspec>.freeze, [">= 0"])
96
+ s.add_dependency(%q<rdoc>.freeze, [">= 0"])
97
+ s.add_dependency(%q<bundler>.freeze, [">= 0"])
98
+ s.add_dependency(%q<jeweler>.freeze, [">= 0"])
99
+ s.add_dependency(%q<simplecov>.freeze, [">= 0"])
100
+ s.add_dependency(%q<json>.freeze, [">= 0"])
101
+ s.add_dependency(%q<coveralls>.freeze, [">= 0"])
96
102
  end
97
103
  end
98
104
 
Binary file
@@ -1,6 +1,7 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
2
  # encoding: UTF-8
3
3
  require 'pathname'
4
+ RTesseract::Processor::RMagickProcessor.setup
4
5
 
5
6
  # Class to rise error
6
7
  class MakeStringError
@@ -13,6 +14,7 @@ describe 'Rtesseract' do
13
14
  before do
14
15
  @path = Pathname.new(__FILE__.gsub('rtesseract_spec.rb', '')).expand_path
15
16
  @image_tif = @path.join('images', 'test.tif').to_s
17
+ @image_for_pdf = @path.join('images', 'test-pdf.png').to_s
16
18
  end
17
19
 
18
20
  it ' be instantiable' do
@@ -94,12 +96,43 @@ describe 'Rtesseract' do
94
96
  expect(RTesseract.new(@image_tif, options: [:digits, :quiet]).options_cmd).to eql([:digits, :quiet])
95
97
  end
96
98
 
99
+ it ' support pdf output mode' do
100
+ # Internal test. Consider 'pdf' option only when #to_pdf is called.
101
+ expect(RTesseract.new(@image_tif, options: 'pdf').options_cmd).to eql([])
102
+ expect(RTesseract.new(@image_for_pdf, options: :pdf).options_cmd).to eql([])
103
+
104
+ pdf_ocr = RTesseract.new(@image_for_pdf)
105
+ expect(File.exists?(pdf_ocr.to_pdf)).to eql(true)
106
+ expect(File.extname(pdf_ocr.to_pdf)).to eql('.pdf')
107
+ # Comment next line and go to tmp dir to see generated pdf.
108
+ expect(pdf_ocr.clean).to eq(true)
109
+ expect(File.exists?(pdf_ocr.to_pdf)).to eql(false)
110
+
111
+ # Still have original functionality (i.e. #to_s, #to_s_without_spaces).
112
+ pdf_ocr = RTesseract.new(@image_tif)
113
+ expect(File.exists?(pdf_ocr.to_pdf)).to eql(true)
114
+ expect(File.extname(pdf_ocr.to_pdf)).to eql('.pdf')
115
+ expect(pdf_ocr.to_s_without_spaces).to eql('43XF')
116
+ expect(pdf_ocr.clean).to eq(true)
117
+ expect(File.exists?(pdf_ocr.to_pdf)).to eql(false)
118
+ end
119
+
120
+ it ' warn when tesseract cannot give pdf' do
121
+ rtesseract = RTesseract.new(@image_for_pdf)
122
+
123
+ allow(rtesseract).to receive(:tesseract_version).and_return(3.02)
124
+ expect { rtesseract.to_pdf }.to raise_error(RTesseract::TesseractVersionError)
125
+
126
+ allow(rtesseract).to receive(:tesseract_version).and_return(3.03)
127
+ expect { rtesseract.to_pdf }.not_to raise_error
128
+ end
129
+
97
130
  it ' be configurable' do
98
131
  expect(RTesseract.new(@image_tif, chop_enable: 0, enable_assoc: 0, display_text: 0).config).to eql("chop_enable 0\nenable_assoc 0\ndisplay_text 0")
99
132
  expect(RTesseract.new(@image_tif, chop_enable: 0).config).to eql('chop_enable 0')
100
133
  expect(RTesseract.new(@image_tif, chop_enable: 0, enable_assoc: 0).config).to eql("chop_enable 0\nenable_assoc 0")
101
134
  expect(RTesseract.new(@image_tif, chop_enable: 0).to_s_without_spaces).to eql('43XF')
102
- expect(RTesseract.new(@image_tif, tessedit_char_whitelist: "ABCDEF12345").to_s_without_spaces).to eql('43F')
135
+ expect(RTesseract.new(@image_tif, tessedit_char_whitelist: 'ABCDEF12345').to_s_without_spaces).to eql('43F')
103
136
  end
104
137
 
105
138
  it ' crop image' do
@@ -165,6 +198,13 @@ describe 'Rtesseract' do
165
198
  expect(test.to_s_without_spaces).to eql('3R8F')
166
199
  end
167
200
 
201
+ it 'does not raise on read with image_magick processor' do
202
+ expect {
203
+ instance = RTesseract.read(@image_tif, processor: 'mini_magick') {}
204
+ expect(instance.processor.a_name?('mini_magick')).to be_truthy
205
+ }.not_to raise_error
206
+ end
207
+
168
208
  it ' get a error' do
169
209
  expect { RTesseract.new(@path.join('images', 'test.jpg').to_s, command: 'tesseract_error').to_s }.to raise_error(RTesseract::ConversionError)
170
210
  expect { RTesseract.new(@path.join('images', 'test_not_exists.png').to_s).to_s }.to raise_error(RTesseract::ImageNotSelectedError)
@@ -179,7 +219,11 @@ describe 'Rtesseract' do
179
219
  expect { RTesseract::Utils.remove_files(Pathname.new(Dir.tmpdir).join('test_not_exists')) }.to raise_error(RTesseract::TempFilesNotRemovedError)
180
220
  end
181
221
 
182
- it ' support default config processors' do
222
+ it ' get a numeric value for tesseract version' do
223
+ expect(RTesseract::Utils.version_number).to be_a Float
224
+ end
225
+
226
+ it ' support default config processors' do
183
227
  # Rmagick
184
228
  RTesseract.configure { |config| config.processor = 'rmagick' }
185
229
  expect(RTesseract.new(@image_tif).processor.a_name?('rmagick')).to eql(true)
@@ -212,6 +256,18 @@ describe 'Rtesseract' do
212
256
  expect(RTesseract.new(@image_tif).user_patterns).to eql(' --user-patterns /tmp/test ')
213
257
  end
214
258
 
259
+ it ' configure pdf has no effect and kept in-house' do
260
+ # So it does not interfere with #to_s outputting.
261
+ RTesseract.configure { |config| config.options_cmd = ['pdf'] }
262
+ expect(RTesseract.new(@image_tif).options_cmd).to eql([])
263
+
264
+ RTesseract.configure { |config| config.options_cmd = [:pdf] }
265
+ expect(RTesseract.new(@image_tif).options_cmd).to eql([])
266
+
267
+ RTesseract.configure { |config| config.options_cmd = [:pdf, 'pdf'] }
268
+ expect(RTesseract.new(@image_tif).options_cmd).to eql([])
269
+ end
270
+
215
271
  it ' support new configs' do
216
272
  expect(RTesseract.new(@image_tif, tessdata_dir: '/tmp/test').tessdata_dir).to eql(' --tessdata-dir /tmp/test ')
217
273
  expect(RTesseract.new(@image_tif, user_words: '/tmp/test').user_words).to eql(' --user-words /tmp/test ')
@@ -0,0 +1,56 @@
1
+ # encoding: UTF-8
2
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
3
+
4
+ describe 'Rtesseract::Uzn' do
5
+ before do
6
+ @path = Pathname.new(__FILE__.gsub('rtesseract_uzn_spec.rb', '')).expand_path
7
+ @image_tif = @path.join('images', 'mixed.tif').to_s
8
+ end
9
+
10
+ it 'should be instantiable' do
11
+ expect(RTesseract::Uzn.new.class).to eql(RTesseract::Uzn)
12
+ expect(RTesseract::Uzn.new(@image_tif).class).to eql(RTesseract::Uzn)
13
+ end
14
+
15
+ it 'should translate parts of the image to text from a block' do
16
+ uzn_block = RTesseract::Uzn.new(@image_tif) do |image|
17
+ image.area(x: 28, y: 19, w: 25, h: 25) # position of 4
18
+ image.area(x: 180, y: 22, w: 20, h: 28) # position of 3
19
+ image.area(x: 218, y: 22, w: 24, h: 28) # position of F
20
+ image.area(x: 248, y: 24, w: 22, h: 22) # position of F
21
+ end
22
+
23
+ expect(uzn_block.to_s_without_spaces).to eql('43FF')
24
+ end
25
+
26
+ it 'should translate parts of the image to text from initializer options' do
27
+ @areas = []
28
+ @areas << { x: 28, y: 19, w: 25, h: 25 } # position of 4
29
+ @areas << { x: 180, y: 22, w: 20, h: 28 } # position of 3
30
+ @areas << { x: 218, y: 22, w: 24, h: 28 } # position of f
31
+ @areas << { x: 248, y: 24, w: 22, h: 22 } # position of f
32
+
33
+ uzn_block = RTesseract::Uzn.new(@image_tif, areas: @areas)
34
+ expect(uzn_block.to_s_without_spaces).to eql('43FF')
35
+ end
36
+
37
+ it 'should handle a blank image' do
38
+ @areas = []
39
+ @areas << { x: 28, y: 19, w: 25, h: 25 } # position of 4
40
+ @areas << { x: 180, y: 22, w: 20, h: 28 } # position of 3
41
+ @areas << { x: 218, y: 22, w: 24, h: 28 } # position of f
42
+ @areas << { x: 248, y: 24, w: 22, h: 22 } # position of f
43
+ uzn_block = RTesseract::Uzn.new(@path.join('images', 'blank.tif').to_s, areas: @areas)
44
+ expect(uzn_block.to_s_without_spaces).to eql('')
45
+ end
46
+
47
+ it ' get a error' do
48
+ @areas = [{ x: 28, y: 19, w: 25, h: 25 }]
49
+
50
+ uzn_block = RTesseract::Uzn.new(@path.join('images', 'test_not_exists.png').to_s, areas: @areas, psm: 7)
51
+ expect { uzn_block.to_s_without_spaces }.to raise_error(RTesseract::ImageNotSelectedError)
52
+
53
+ uzn_block = RTesseract::Uzn.new(@image_tif, areas: @areas, psm: 7, command: 'tesseract_error')
54
+ expect { uzn_block.to_s }.to raise_error(RTesseract::ConversionError)
55
+ end
56
+ end
data/spec/spec_helper.rb CHANGED
@@ -14,5 +14,8 @@ require 'rtesseract'
14
14
  # in ./support/ and its subdirectories.
15
15
  Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
16
16
 
17
- RSpec.configure do # |config|
17
+ RSpec.configure do |config|
18
+ config.after(:each) do
19
+ RTesseract.configuration = RTesseract::Configuration.new
20
+ end
18
21
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rtesseract
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Danilo Jeremias da Silva
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-05-17 00:00:00.000000000 Z
11
+ date: 2018-01-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -70,16 +70,16 @@ dependencies:
70
70
  name: jeweler
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - "~>"
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
- version: 2.1.1
75
+ version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - "~>"
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
- version: 2.1.1
82
+ version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: simplecov
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: json
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
97
111
  - !ruby/object:Gem::Dependency
98
112
  name: coveralls
99
113
  requirement: !ruby/object:Gem::Requirement
@@ -138,6 +152,7 @@ files:
138
152
  - lib/rtesseract/mixed.rb
139
153
  - lib/rtesseract/processor.rb
140
154
  - lib/rtesseract/utils.rb
155
+ - lib/rtesseract/uzn.rb
141
156
  - rtesseract.gemspec
142
157
  - spec/configs/eng.user-words.txt
143
158
  - spec/images/README.pdf
@@ -145,6 +160,7 @@ files:
145
160
  - spec/images/mixed.tif
146
161
  - spec/images/orientation_reverse.png
147
162
  - spec/images/test with spaces.tif
163
+ - spec/images/test-pdf.png
148
164
  - spec/images/test.bmp
149
165
  - spec/images/test.jpg
150
166
  - spec/images/test.png
@@ -155,6 +171,7 @@ files:
155
171
  - spec/rtesseract_box_spec.rb
156
172
  - spec/rtesseract_mixed_spec.rb
157
173
  - spec/rtesseract_spec.rb
174
+ - spec/rtesseract_uzn_spec.rb
158
175
  - spec/spec_helper.rb
159
176
  homepage: http://github.com/dannnylo/rtesseract
160
177
  licenses:
@@ -176,7 +193,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
176
193
  version: '0'
177
194
  requirements: []
178
195
  rubyforge_project:
179
- rubygems_version: 2.4.8
196
+ rubygems_version: 2.6.14
180
197
  signing_key:
181
198
  specification_version: 4
182
199
  summary: Ruby library for working with the Tesseract OCR.