GS (20130717) Since Office 2003, there is a library called MODI (Microsoft Office Document Imaging). With it you can perform OCR (Optical Character Recognition) and extract text from document images. So, with less than 10 lines of Tcl you can get your text.
I say less than 10 lines ! OK let's go :
The sample image will be a part of the text from www.tcl.tk in BMP image format :
package require twapi
set doc [twapi::comobj MODI.Document]
$doc Create "tcltk.bmp"
$doc OCR
set img [[$doc Images] Item 0]
set ly [$img Layout]
set page [$ly Text]
$doc Close
In the variable page, you will get this raw text without formatting :
Welcome to the Tcl Developer Xchange!
Join the many thousands of software developers who are already more productive with help from
the Tcl programming language and the Tk graphical user interface toolkit.
Tcl (Tool Command Language) is a very powerful but easy to learn dynamic programming language,
suitable for a very wide range of uses, including web and desktop applications, networking,
administration, testing and many more. Open source and business-friendly, Tcl is a mature yet
evolving language that is truly cross platform, easily deployed and highly extensible.
Tk is a graphical user interface toolkit that takes developing desktop applications to a
higher level than conventional approaches. Tk is the standard GUI not only for Tcl, but
for many other dynamic languages, and can produce rich, native applications that run
unchanged across Windows, Mac OS X, Linux and more.
A few comments about this little funny piece of code set doc [twapi::comobj MODI.Document]
Create an instance of
MODI.Document object.
$doc Create "tcltk.bmp"
Assign an image file to the document instance. Supported image formats are TIFF, multi-page TIFF and BMP.
$doc OCR
Calling the OCR method. The OCR method can take 3 optional parameters :
$doc OCR <LangId> <OCROrientImage> <OCRStraightenImage>LangId : the language of the document. 20 languages are supported. OCR engine always use default regional settings. Czech = 5, Danish = 6, English = 9, Finnish = 11, French = 12, German = 7, Greek = 8, Italian = 16, Spanish = 10, Russian = 25.
OCROrientImage : a boolean value which specifies whether the OCR engine attempts to determine the orientation of the page. Default is true.
OCRStraightenImage : a boolean value which specifies whether the OCR engine attempts to "de-skew" the page to correct for small angles of misalignment from the vertical. Default is true.
set img [[$doc Images] Item 0]
Each page of the document is an image object. We get the first and only image (
Item 0). If you have more than one page, you have to do a loop over all the images and to use TIFF format. The number of images is :
set n [$doc Images] Count] .
set ly [$img Layout]
Get the layout. At this stage you haven't any text because the Text property is in a nested object. To sum up, the object hierarchy is something like that :
(Document (Images (Layout (Text)))) set page [$ly Text]
Finally we get the full text in the Layout.
Now you can process the text easilly with Tcl.
But if you want to go further, you can use the
Words accessor property of the
Layout to retrieve some statistics about the text :
set word [$ly Words]
set nbword [$word Count]
for {set i 0} {$i < $nbword} {incr i} {
set s [$word Item $i]
set t [$s Text]
set Id [$s Id]
set LineId [$s LineId]
set RegionId [$s RegionId]
set FontId [$s FontId]
set RecognitionConfidence [$s RecognitionConfidence]
puts "Id : $Id LineId : $LineId Text : $t \t\t RegionId : $RegionId FontId : $FontId RecognitionConfidence : $RecognitionConfidence"
}
Here is the result :
Id : 0 LineId : 0 Text : Welcome RegionId : 0 FontId : 1 RecognitionConfidence : 209
Id : 1 LineId : 0 Text : to RegionId : 0 FontId : 1 RecognitionConfidence : 210
Id : 2 LineId : 0 Text : the RegionId : 0 FontId : 1 RecognitionConfidence : 211
Id : 3 LineId : 0 Text : Tcl RegionId : 0 FontId : 1 RecognitionConfidence : 59
Id : 4 LineId : 0 Text : Developer RegionId : 0 FontId : 1 RecognitionConfidence : 209
Id : 5 LineId : 0 Text : Xchange! RegionId : 0 FontId : 1 RecognitionConfidence : 108
Id : 6 LineId : 0 Text : Join RegionId : 1 FontId : 2 RecognitionConfidence : 208
Id : 7 LineId : 0 Text : the RegionId : 1 FontId : 2 RecognitionConfidence : 210
Id : 8 LineId : 0 Text : many RegionId : 1 FontId : 2 RecognitionConfidence : 210
Id : 9 LineId : 0 Text : thousands RegionId : 1 FontId : 2 RecognitionConfidence : 210
Id : 10 LineId : 0 Text : of RegionId : 1 FontId : 2 RecognitionConfidence : 210
Id : 11 LineId : 0 Text : software RegionId : 1 FontId : 2 RecognitionConfidence : 207
Id : 12 LineId : 0 Text : developers RegionId : 1 FontId : 2 RecognitionConfidence : 209
Id : 13 LineId : 0 Text : who RegionId : 1 FontId : 2 RecognitionConfidence : 210
Id : 14 LineId : 0 Text : are RegionId : 1 FontId : 2 RecognitionConfidence : 210
Id : 15 LineId : 0 Text : already RegionId : 1 FontId : 2 RecognitionConfidence : 211
Id : 16 LineId : 0 Text : more RegionId : 2 FontId : 2 RecognitionConfidence : 210
Id : 17 LineId : 0 Text : productive RegionId : 2 FontId : 2 RecognitionConfidence : 210
Id : 18 LineId : 0 Text : with RegionId : 2 FontId : 2 RecognitionConfidence : 212
Id : 19 LineId : 0 Text : help RegionId : 2 FontId : 2 RecognitionConfidence : 211
Id : 20 LineId : 0 Text : from RegionId : 2 FontId : 2 RecognitionConfidence : 210
Id : 21 LineId : 0 Text : the RegionId : 2 FontId : 2 RecognitionConfidence : 212
Id : 22 LineId : 0 Text : Tcl RegionId : 2 FontId : 3 RecognitionConfidence : 134
Id : 23 LineId : 0 Text : programming RegionId : 2 FontId : 3 RecognitionConfidence : 199
Id : 24 LineId : 0 Text : language RegionId : 2 FontId : 3 RecognitionConfidence : 208
Id : 25 LineId : 0 Text : and RegionId : 3 FontId : 2 RecognitionConfidence : 207
Id : 26 LineId : 0 Text : the RegionId : 3 FontId : 2 RecognitionConfidence : 210
Id : 27 LineId : 0 Text : Tk RegionId : 3 FontId : 3 RecognitionConfidence : 134
Id : 28 LineId : 0 Text : graphical RegionId : 3 FontId : 3 RecognitionConfidence : 196
Id : 29 LineId : 0 Text : user RegionId : 3 FontId : 3 RecognitionConfidence : 206
Id : 30 LineId : 0 Text : interface RegionId : 3 FontId : 3 RecognitionConfidence : 115
Id : 31 LineId : 0 Text : toolkit. RegionId : 3 FontId : 3 RecognitionConfidence : 200
Id : 32 LineId : 0 Text : Tcl RegionId : 4 FontId : 4 RecognitionConfidence : 169
Id : 33 LineId : 0 Text : (Tool RegionId : 4 FontId : 4 RecognitionConfidence : 206
Id : 34 LineId : 0 Text : Command RegionId : 4 FontId : 4 RecognitionConfidence : 210
Id : 35 LineId : 0 Text : Language) RegionId : 4 FontId : 4 RecognitionConfidence : 205
Id : 36 LineId : 0 Text : is RegionId : 4 FontId : 4 RecognitionConfidence : 209
Id : 37 LineId : 0 Text : a RegionId : 4 FontId : 4 RecognitionConfidence : 212
Id : 38 LineId : 0 Text : very RegionId : 4 FontId : 4 RecognitionConfidence : 211
Id : 39 LineId : 0 Text : powerful RegionId : 4 FontId : 4 RecognitionConfidence : 207
Id : 40 LineId : 0 Text : but RegionId : 4 FontId : 4 RecognitionConfidence : 210
Id : 41 LineId : 0 Text : easy RegionId : 4 FontId : 4 RecognitionConfidence : 210
Id : 42 LineId : 0 Text : to RegionId : 4 FontId : 4 RecognitionConfidence : 212
Id : 43 LineId : 0 Text : learn RegionId : 4 FontId : 4 RecognitionConfidence : 212
Id : 44 LineId : 0 Text : dynamic RegionId : 4 FontId : 4 RecognitionConfidence : 210
Id : 45 LineId : 0 Text : programming RegionId : 5 FontId : 4 RecognitionConfidence : 212
Id : 46 LineId : 0 Text : language, RegionId : 5 FontId : 4 RecognitionConfidence : 202
Id : 47 LineId : 0 Text : suitable RegionId : 5 FontId : 4 RecognitionConfidence : 212
Id : 48 LineId : 0 Text : for RegionId : 5 FontId : 4 RecognitionConfidence : 212
Id : 49 LineId : 0 Text : a RegionId : 5 FontId : 4 RecognitionConfidence : 213
Id : 50 LineId : 0 Text : very RegionId : 5 FontId : 4 RecognitionConfidence : 211
Id : 51 LineId : 0 Text : wide RegionId : 5 FontId : 4 RecognitionConfidence : 210
Id : 52 LineId : 0 Text : range RegionId : 5 FontId : 4 RecognitionConfidence : 213
Id : 53 LineId : 0 Text : of RegionId : 5 FontId : 4 RecognitionConfidence : 213
Id : 54 LineId : 0 Text : uses, RegionId : 5 FontId : 4 RecognitionConfidence : 206
Id : 55 LineId : 0 Text : including RegionId : 5 FontId : 4 RecognitionConfidence : 212
Id : 56 LineId : 0 Text : web RegionId : 5 FontId : 4 RecognitionConfidence : 213
Id : 57 LineId : 0 Text : and RegionId : 5 FontId : 4 RecognitionConfidence : 213
Id : 58 LineId : 0 Text : desktop RegionId : 6 FontId : 4 RecognitionConfidence : 210
Id : 59 LineId : 0 Text : applications, RegionId : 6 FontId : 4 RecognitionConfidence : 207
Id : 60 LineId : 0 Text : networking, RegionId : 6 FontId : 4 RecognitionConfidence : 204
Id : 61 LineId : 0 Text : administration, RegionId : 6 FontId : 4 RecognitionConfidence : 204
Id : 62 LineId : 0 Text : testing RegionId : 6 FontId : 4 RecognitionConfidence : 212
Id : 63 LineId : 0 Text : and RegionId : 6 FontId : 4 RecognitionConfidence : 214
Id : 64 LineId : 0 Text : many RegionId : 6 FontId : 4 RecognitionConfidence : 212
Id : 65 LineId : 0 Text : more. RegionId : 6 FontId : 4 RecognitionConfidence : 201
Id : 66 LineId : 0 Text : Open RegionId : 6 FontId : 4 RecognitionConfidence : 210
Id : 67 LineId : 0 Text : source RegionId : 7 FontId : 4 RecognitionConfidence : 213
Id : 68 LineId : 0 Text : and RegionId : 7 FontId : 4 RecognitionConfidence : 214
Id : 69 LineId : 0 Text : business-friendly, RegionId : 7 FontId : 4 RecognitionConfidence : 204
Id : 70 LineId : 0 Text : Tcl RegionId : 7 FontId : 4 RecognitionConfidence : 125
Id : 71 LineId : 0 Text : is RegionId : 7 FontId : 4 RecognitionConfidence : 214
Id : 72 LineId : 0 Text : a RegionId : 7 FontId : 4 RecognitionConfidence : 214
Id : 73 LineId : 0 Text : mature RegionId : 7 FontId : 4 RecognitionConfidence : 211
Id : 74 LineId : 0 Text : yet RegionId : 7 FontId : 4 RecognitionConfidence : 213
Id : 75 LineId : 0 Text : evolving RegionId : 7 FontId : 4 RecognitionConfidence : 210
Id : 76 LineId : 0 Text : language RegionId : 7 FontId : 4 RecognitionConfidence : 212
Id : 77 LineId : 0 Text : that RegionId : 7 FontId : 4 RecognitionConfidence : 210
Id : 78 LineId : 0 Text : is RegionId : 7 FontId : 4 RecognitionConfidence : 214
Id : 79 LineId : 0 Text : truly RegionId : 7 FontId : 4 RecognitionConfidence : 211
Id : 80 LineId : 0 Text : cross RegionId : 8 FontId : 4 RecognitionConfidence : 212
Id : 81 LineId : 0 Text : platform, RegionId : 8 FontId : 4 RecognitionConfidence : 209
Id : 82 LineId : 0 Text : easily RegionId : 8 FontId : 4 RecognitionConfidence : 212
Id : 83 LineId : 0 Text : deployed RegionId : 8 FontId : 4 RecognitionConfidence : 212
Id : 84 LineId : 0 Text : and RegionId : 8 FontId : 4 RecognitionConfidence : 214
Id : 85 LineId : 0 Text : highly RegionId : 8 FontId : 4 RecognitionConfidence : 211
Id : 86 LineId : 0 Text : extensible. RegionId : 8 FontId : 4 RecognitionConfidence : 204
Id : 87 LineId : 0 Text : Tk RegionId : 9 FontId : 4 RecognitionConfidence : 190
Id : 88 LineId : 0 Text : is RegionId : 9 FontId : 4 RecognitionConfidence : 210
Id : 89 LineId : 0 Text : a RegionId : 9 FontId : 4 RecognitionConfidence : 210
Id : 90 LineId : 0 Text : graphical RegionId : 9 FontId : 4 RecognitionConfidence : 212
Id : 91 LineId : 0 Text : user RegionId : 9 FontId : 4 RecognitionConfidence : 210
Id : 92 LineId : 0 Text : interface RegionId : 9 FontId : 4 RecognitionConfidence : 212
Id : 93 LineId : 0 Text : toolkit RegionId : 9 FontId : 4 RecognitionConfidence : 212
Id : 94 LineId : 0 Text : that RegionId : 9 FontId : 4 RecognitionConfidence : 212
Id : 95 LineId : 0 Text : takes RegionId : 9 FontId : 4 RecognitionConfidence : 211
Id : 96 LineId : 0 Text : developing RegionId : 9 FontId : 4 RecognitionConfidence : 211
Id : 97 LineId : 0 Text : desktop RegionId : 9 FontId : 4 RecognitionConfidence : 212
Id : 98 LineId : 0 Text : applications RegionId : 9 FontId : 4 RecognitionConfidence : 212
Id : 99 LineId : 0 Text : to RegionId : 10 FontId : 4 RecognitionConfidence : 212
Id : 100 LineId : 0 Text : a RegionId : 10 FontId : 4 RecognitionConfidence : 214
Id : 101 LineId : 0 Text : higher RegionId : 10 FontId : 4 RecognitionConfidence : 212
Id : 102 LineId : 0 Text : level RegionId : 10 FontId : 4 RecognitionConfidence : 211
Id : 103 LineId : 0 Text : than RegionId : 10 FontId : 4 RecognitionConfidence : 212
Id : 104 LineId : 0 Text : conventional RegionId : 10 FontId : 4 RecognitionConfidence : 212
Id : 105 LineId : 0 Text : approaches. RegionId : 10 FontId : 4 RecognitionConfidence : 189
Id : 106 LineId : 0 Text : Tk RegionId : 10 FontId : 4 RecognitionConfidence : 195
Id : 107 LineId : 0 Text : is RegionId : 10 FontId : 4 RecognitionConfidence : 212
Id : 108 LineId : 0 Text : the RegionId : 10 FontId : 4 RecognitionConfidence : 212
Id : 109 LineId : 0 Text : standard RegionId : 10 FontId : 4 RecognitionConfidence : 211
Id : 110 LineId : 0 Text : GUI RegionId : 10 FontId : 4 RecognitionConfidence : 205
Id : 111 LineId : 0 Text : not RegionId : 10 FontId : 4 RecognitionConfidence : 211
Id : 112 LineId : 0 Text : only RegionId : 10 FontId : 4 RecognitionConfidence : 211
Id : 113 LineId : 0 Text : for RegionId : 11 FontId : 4 RecognitionConfidence : 211
Id : 114 LineId : 0 Text : Tcl, RegionId : 11 FontId : 4 RecognitionConfidence : 167
Id : 115 LineId : 0 Text : but RegionId : 11 FontId : 4 RecognitionConfidence : 212
Id : 116 LineId : 0 Text : for RegionId : 11 FontId : 4 RecognitionConfidence : 212
Id : 117 LineId : 0 Text : many RegionId : 11 FontId : 4 RecognitionConfidence : 213
Id : 118 LineId : 0 Text : other RegionId : 11 FontId : 4 RecognitionConfidence : 212
Id : 119 LineId : 0 Text : dynamic RegionId : 11 FontId : 4 RecognitionConfidence : 212
Id : 120 LineId : 0 Text : languages, RegionId : 11 FontId : 4 RecognitionConfidence : 204
Id : 121 LineId : 0 Text : and RegionId : 11 FontId : 4 RecognitionConfidence : 213
Id : 122 LineId : 0 Text : can RegionId : 11 FontId : 4 RecognitionConfidence : 210
Id : 123 LineId : 0 Text : produce RegionId : 11 FontId : 4 RecognitionConfidence : 212
Id : 124 LineId : 0 Text : rich, RegionId : 11 FontId : 4 RecognitionConfidence : 204
Id : 125 LineId : 0 Text : native RegionId : 11 FontId : 4 RecognitionConfidence : 211
Id : 126 LineId : 0 Text : applications RegionId : 12 FontId : 4 RecognitionConfidence : 210
Id : 127 LineId : 0 Text : that RegionId : 12 FontId : 4 RecognitionConfidence : 212
Id : 128 LineId : 0 Text : run RegionId : 12 FontId : 4 RecognitionConfidence : 213
Id : 129 LineId : 0 Text : unchanged RegionId : 12 FontId : 4 RecognitionConfidence : 210
Id : 130 LineId : 0 Text : across RegionId : 12 FontId : 4 RecognitionConfidence : 214
Id : 131 LineId : 0 Text : Windows, RegionId : 12 FontId : 4 RecognitionConfidence : 202
Id : 132 LineId : 0 Text : Mac RegionId : 12 FontId : 4 RecognitionConfidence : 206
Id : 133 LineId : 0 Text : OS RegionId : 12 FontId : 4 RecognitionConfidence : 177
Id : 134 LineId : 0 Text : X, RegionId : 12 FontId : 4 RecognitionConfidence : 186
Id : 135 LineId : 0 Text : Linux RegionId : 12 FontId : 4 RecognitionConfidence : 205
Id : 136 LineId : 0 Text : and RegionId : 12 FontId : 4 RecognitionConfidence : 212
Id : 137 LineId : 0 Text : more. RegionId : 12 FontId : 4 RecognitionConfidence : 202
References :
-
http://msdn.microsoft.com/en-us/library/aa202819%28v=office.11%29.aspx-
http://www.documentsnap.com/using-microsoft-office-document-imaging-to-ocr-for-free/PO Added OCR functionality in
CAWT version 1.0.2.
GS (20130730) Nice addition. CAWT is becoming a usefull toolbox.