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.