Screengrab --> OCR -- text, GUI for options/results
Hardware: fast laptop with SSD
Software: Win 7 Home Premium 64-bit, android for phone and tablet
To fix the script, open ShowOCRUnderMouse.ahk, go to line 77, and replace "gocr.exe" with "gocr047.exe" (the name of the newly downloaded gocr binary). Good to go!
#Include GDIplusWrapper.ahk GetOcr(thisX, thisY) { fileNameDestJ = ResultImage.jpg If (GDIplus_Start() != 0) Goto GDIplusError If (GDIplus_CaptureScreenRectangle(bitmap, thisX, thisY, 100, 20) != 0) Goto GDIplusError If (GDIplus_GetEncoderCLSID(jpgEncoder, #GDIplus_mimeType_JPG) != 0) Goto GDIplusError GDIplus_InitEncoderParameters(jpegEncoderParams, 1) jpegQuality = 100 If (GDIplus_AddEncoderParameter(jpegEncoderParams, #EncoderQuality, jpegQuality) != 0) Goto GDIplusError If (GDIplus_SaveImage(bitmap, fileNameDestJ, jpgEncoder, jpegEncoderParams) != 0) Goto GDIplusError ; Wait for jpg Loop, { IfExist, %fileNameDestJ% Break } RunWait, djpeg.exe -pnm -grayscale %fileNameDestJ% in.pnm RunWait, gocr.exe -l 0 -s 1 -i in.pnm -o output.txt FileRead, result, output.txt GDIplusError: If (#GDIplus_lastError != "") MsgBox 16, GDIplus Test, (Error in % #GDIplus_lastError% (at %step%)) GDIplusEnd: GDIplus_FreeImage(bitmap) GDIplus_Stop() ; Cleanup ;FileDelete, in.pnm ;FileDelete, %fileNameDestJ% Return, result }
As you can tell I've gotten rid of the need to use cmdstub.exe because I have the 32bit gocr.exe. After some investigation the error seems to be coming from GDIplus_ScreenCaptureRectangle, apparently its #GpStatus@13 = UnknownImageFormat, though I've left n-l-i-d's portion of that code almost untouched =/
Anyone able to help me out? Would be greatly appreciated =)
Interesting project. I just downloaded the files. If they work I'll test them against ABBYY Screenshot Reader, which is a commercial alternative. I've also tried ScanSoft's Omnipage 16 for regular OCR, but didn't like it.
UPDATE: I had problems getting the scripts to work so I wasn't able to test them out yet, until now. Today I finally got around to setting them up:
1. For the ShowOCRUnderMouse.ahk I had to replace gocr.exe with the newer gocr047.exe (but renamed to gocr.exe for obvious reasons).
It works ok: Accuracy is poor, but the conversion is instantaneous, whereas other OCR scripts need a few seconds to process the input. Examples:
2. I had lots of trouble setting up m2's Screengrab script - maybe he was using an older version of AHK with slighly different syntax. In any case, I had to remove every instance of "cmd /c" from the RunWait commands to get his Screengrab script to work. I've only tried it on notepad text, but so far I'm impressed (the result is in a text box in the lower right corner).
Selection:
Result:
m2's script nailed that one (grabbed the cursor too). ABBYY's Screenshot Reader can get that too. Both use a draw-box-with-mouse-to-select-input interface. I only did one comparison shot so far, and they both did about the same. Judge for yourself (both with default settings):
So yes, I'm impressed. That said, I have no idea how m2's script will perform with different backgrounds, fonts, text colors, etc. Also, I think the ABBYY program (full version, not Screenshot Reader alone) may be able to learn. Then again, the tesseract engine can probably do the same
Here's here the ABBYY app looks when called out of the system tray:
Insignificant details for completeness (don't read):
-I used the following settings for paths:
; Default variables
TmpDir =Z:\temp
TmpFile =image_out
ImageFormat =pgm
TmpImageFormat =ppm ; This is the only format supported
; Program paths for dependencies
convert_path =Z:\My Programs\ImageMagick
mkbitmap_path =Z:\My Programs\Potrace
potrace_path =Z:\My Programs\Potrace
gocr_path =Z:\My Programs\gOCR
tesseract_path =C:\WINDOWS
I downloaded the full portable version of ImageMagick (ImageMagick-6.5.2-Q16-windows.zip), potrace with mkbitmap package (potrace-1.8.win32-i386.tar.gz package, and finally Windows-binary gocr047.exe (but renamed to gocr.exe). I also installed the super stable version of NetPBM from the previous link - just in case, but in hindsight I don't think it's needed or used by m2's version of gOCR. Finally, the version of tesseract I have came with Softi FreeOCR. It put tesseract.exe and tessdata folder into my Windows directory; the rest of the program resides in various Program Files and Documents and Settings folders, but I suppose m2's script doesn't need those.
Hardware: fast laptop with SSD
Software: Win 7 Home Premium 64-bit, android for phone and tablet
1. Both m2's ScreenGrab and ABBYY pick up AHK forum heading and subtitle fine:
Blue web text is not a problem:
However, m2's script gets tripped up by non-uniform background while ABBYY handled the AHK forum logo pic fine:
Suggestions:
-I would (and will) change the hotkey from Ctrl+LeftClick -- that gets triggered too easily because people (I at least) use it instinctively to select multiple files in a folder. I'd go with:
(i) a similar hotkey setup to the screenshot script presented in this thread: http://www.autohotke...opic.php?t=4086 (i.e. WINKEY+S to trigger script (launches screen mask) and pics up the next LeftClick down and LeftClick up to determine the box to screengrab.
(ii) leftclick tray icon option to launch the screen mask. (I'd change the tray icon too while at it)
-please keep the project alive; it's quite impressive imo.
Hardware: fast laptop with SSD
Software: Win 7 Home Premium 64-bit, android for phone and tablet
However, the selection method is a bit slower than the original one (but smoother).
I left in my own paths, so if anyone tries to use this version, you'll need to change the icon path on line 4, and dependencies paths on line 17, and 23-27.
;#Include GDIPlusHelper.ahk #Persistent #SingleInstance force Menu, Tray, Icon, Z:\My Programs\AutoHotkey\icons\smiley.ico Menu, Tray, Add ; separator Menu, Tray, Add, About and Options, AboutOptions Menu, Tray, Add, Grab screen, GrabIt Menu, Tray, Default, Grab screen Menu, Tray, Click, 1 ; Default GUI options FileSave = 0 InfoWindow = 1 ; Default variables TmpDir =Z:\temp TmpFile =image_out ImageFormat =pgm TmpImageFormat =ppm ; This is the only format supported ; Program paths for dependencies convert_path =Z:\My Programs\ImageMagick mkbitmap_path =Z:\My Programs\Potrace potrace_path =Z:\My Programs\Potrace gocr_path =Z:\My Programs\gOCR tesseract_path =C:\WINDOWS ; Default processing options ; Image preprocessing ; mkbitmap mkb_s =3 ; scale and interpolate mkb_s1 =0 ;-2 linear scale mkb_s2 =1 ;-3 cubic scale mkb_i =0 ; -i invert mkb_f =4 ; highpassfilter mkb_t =0.45 ; threshold ; potrace pre_potrace = 1 ; Run bitmap thru potrace pot_z =minority ;how to resolve ambiguities in path decomposition ;black, white, right, left, minority|, majority, or random pot_t =2 ;suppress speckles of up to this size (default 2) pot_a =4 ;corner threshold parameter (default 1) pot_n =0 ;-n turn off curve optimization pot_O =0.2 ;curve optimization tolerance (default 0.2) pot_u =10 ;Quantize output to 1/unit pixel pot_k =0.5 ; Black/white cutof pot_i =0 ;-i ; -i invert pot_r =0 ; Rotate clock wise degree ; OCR ocr_d =-1 ; -d, Dust size ocr_s =0 ; -d, Spacewidth ocr_m =32 ; -m, operational modes ocr_n =0 ; -n, numbers only ; OCR/TEXT postprocessing NoLineReturn = 1 Return #q::Goto, GrabIt ;press win + q (for "start") GrabIt: Sleep, 100 stop=0 ; First method for positioning of screengrab ;Mask Screen Gui, Color, FFFFFF Gui +LastFound WinSet, Transparent, 50 Gui, -Caption Gui, +AlwaysOnTop Gui, Show, x0 y0 h%A_ScreenHeight% w%A_ScreenWidth%,"AutoHotkeySnapshotApp" ;Drag Mouse CoordMode, Mouse, Screen CoordMode, Tooltip, Screen WinGet, hw_frame_m,ID,"AutoHotkeySnapshotApp" hdc_frame_m := DllCall( "GetDC", "uint", hw_frame_m) KeyWait, LButton, D MouseGetPos, scan_x_start, scan_y_start Loop { Sleep, 10 KeyIsDown := GetKeyState("LButton") if (KeyIsDown = 1) { MouseGetPos, scan_x, scan_y DllCall( "gdi32.dll\Rectangle", "uint", hdc_frame_m, "int", 0,"int",0,"int", A_ScreenWidth,"int",A_ScreenWidth) DllCall( "gdi32.dll\Rectangle", "uint", hdc_frame_m, "int", scan_x_start,"int",scan_y_start,"int", scan_x,"int",scan_y) } else break } ;KeyWait, LButton, U MouseGetPos, scan_x_end, scan_y_end if (scan_x_end < scan_x_start) { tmp := scan_x_start scan_x_start := scan_x_end scan_x_end := tmp } if (scan_y_end < scan_y_start) { tmp := scan_y_start scan_y_start := scan_y_end scan_y_end := tmp } ; Main scanning function TrayTip, , Scanning...., , 1 CoordMode, Pixel, Screen CoordMode, Mouse, Screen MouseGetPos, scan_x_end, scan_y_end scan_current_y=%scan_y_start% scan_current_x=%scan_x_start% scan_current_line= scan_current_line_source= Loop { scan_current_x := scan_current_x + 1 if scan_current_x > %scan_x_end% { scan_current_line =%scan_current_line%`n scan_current_line_source =%scan_current_line_source%`n scan_current_y := scan_current_y + 1 if scan_current_y > %scan_y_end% break scan_current_x = %scan_x_start% continue } PixelGetColor, found_color, %scan_current_x%, %scan_current_y% StringMid, scan_rgb_r, found_color, 3, 2 StringMid, scan_rgb_g, found_color, 5, 2 StringMid, scan_rgb_b, found_color, 7, 2 scan_current_line_source =%scan_current_line_source% %found_color% scan_rgb_r =0x%scan_rgb_r% scan_rgb_g =0x%scan_rgb_g% scan_rgb_b =0x%scan_rgb_b% SetFormat, integer, d scan_rgb_r -= 0 scan_rgb_g -= 0 scan_rgb_b -= 0 scan_rgb_r := " " . scan_rgb_r scan_rgb_g := " " . scan_rgb_g scan_rgb_b := " " . scan_rgb_b StringRight, scan_rgb_r, scan_rgb_r, 3 StringRight, scan_rgb_g, scan_rgb_g, 3 StringRight, scan_rgb_b, scan_rgb_b, 3 found_color =%scan_rgb_r% %scan_rgb_g% %scan_rgb_b% ;scan_current_line=%scan_current_line% %found_color% ;/* if scan_current_x > %scan_x_start% { scan_current_line=%scan_current_line% %found_color% } else { scan_current_line=%scan_current_line%%found_color% } ;*/ } ; Add Header for image file format :="P3" comment :="#File made in Autohotkey" hight :=scan_y_end - scan_y_start width :=scan_x_end - scan_x_start colors :="255" file_data = ( %format% %comment% %width% %hight% %colors% %scan_current_line% ) TrayTip, , Scan complete, , 1 sleep, 1000 TrayTip GoSub, MainProcess ;MsgBox, The MainProcess subroutine has returned (it is finished). return MainProcess: Gui Destroy ; File Save, function to allow save a file of the screengrab image if FileSave = 1 { FileSelectFile, SelectedFile, 16, , Save image, (*.ppm) if SelectedFile = { MsgBox,,Save canceled, No image saved. } else { IfExist %SelectedFile% { FileDelete %SelectedFile% if ErrorLevel <> 0 { MsgBox The attempt to overwrite "%SelectedFile%" failed. return } else { FileAppend, %file_data%, *%SelectedFile% } } } } ; End function, File Save ; Cleaning, Functions for cleaning up temporary files from previus grabs IfExist %TmpDir%\%TmpFile%.ppm { FileDelete %TmpDir%\%TmpFile%.ppm if ErrorLevel <> 0 { MsgBox The attempt to remove "%TmpDir%\%TmpFile%.ppm" failed. return } } IfExist %TmpDir%\%TmpFile%.%ImageFormat% { FileDelete %TmpDir%\%TmpFile%.%ImageFormat% if ErrorLevel <> 0 { MsgBox The attempt to remove "%TmpDir%\%TmpFile%.%ImageFormat%" failed. return } } IfExist %TmpDir%\%TmpFile%.txt { FileDelete %TmpDir%\%TmpFile%.txt if ErrorLevel <> 0 { MsgBox The attempt to remove "%TmpDir%\%TmpFile%.txt" failed. return } } IfExist %TmpDir%\%TmpFile%.png { FileDelete %TmpDir%\%TmpFile%.png if ErrorLevel <> 0 { MsgBox The attempt to remove "%TmpDir%\%TmpFile%.png" failed. return } } ; End Cleaning funtions ; Write, function to write the screengrab image to file FileAppend, %file_data%, *%TmpDir%\%TmpFile%.ppm ; Start Preprocessing image if mkb_i = 1 { mkb_ii :="-i " } else { mkb_ii = } RunWait, %mkbitmap_path%\mkbitmap %mkb_ii% -f %mkb_f% -s %mkb_s% -t %mkb_t% -o %TmpFile%.pbm %TmpFile%.ppm, %TmpDir%, hide, IfNotExist %TmpDir%\%TmpFile%.pbm { MsgBox, ( Running mkbitmap "%TmpDir%\%TmpFile%.pbm" failed. %mkbitmap_path%\mkbitmap %mkb_ii% -f %mkb_f% -s %mkb_s% -t %mkb_t% -o %TmpFile%.pbm %TmpFile%.ppm ) return } If pre_potrace = 1 { if pot_i = 1 { pot_ii =-i } else { pot_ii = } if pot_n = 1 { pot_nn :="-n " } else { pot_nn = } RunWait %potrace_path%\potrace %pot_ii%%pot_nn% -O %pot_o% -k %pot_k% -r %pot_r% -t %pot_t% -g -a %pot_a% -o %TmpFile%.pgm %TmpFile%.pbm, %TmpDir%, hide, IfNotExist %TmpDir%\%TmpFile%.pgm { MsgBox, ( Running potrace "%TmpDir%\%TmpFile%.pgm" failed. %potrace_path%\potrace %pot_ii%%pot_nn% -O %pot_o% -k %pot_k% -r %pot_r% -t %pot_t% -g -a %pot_a% -o %TmpFile%.pgm %TmpFile%.pbm ) return } RunWait %convert_path%\convert %TmpFile%.pgm %TmpFile%.pbm, %TmpDir%, hide, } ; End Preprocessing ; Start OCR processing ; Need to run gocr thru cmd, ??? RunWait %gocr_path%\gocr -i %TmpDir%\%TmpFile%.pbm -s %ocr_s% -d %ocr_d% -m %ocr_m% -n %ocr_n% -o %TmpFile%.txt, %TmpDir%, hide, IfNotExist %TmpDir%\%TmpFile%.txt { MsgBox, ( Running gocr "%TmpDir%\%TmpFile%.txt" failed. cmd /c %gocr_path%\gocr %TmpDir%\%TmpFile%.pbm -s %ocr_s% -d %ocr_d% -m %ocr_m% -n %ocr_n% -o %TmpFile%.txt ) return } FileRead, ocr_text, %TmpDir%\%TmpFile%.txt ; Test Tesseract, a other OCR ; Tesseract needs a BMP image RunWait %convert_path%\convert %TmpFile%.pbm %TmpFile%.t.bmp, %TmpDir%, hide, ; Start OCR processing RunWait %tesseract_path%\tesseract %TmpFile%.t.bmp %TmpFile%.t, %TmpDir%, hide, IfNotExist %TmpDir%\%TmpFile%.t.txt { MsgBox, ( Running gocr "%TmpDir%\%TmpFile%.t.txt" failed. cmd /c %tesseract_path%\tesseract %TmpFile%.t.bmp output %TmpFile%.t.txt ) return } FileRead, ocr_t_text, %TmpDir%\%TmpFile%.t.txt ; Save the raw OCR result into variable, could be useful ocr_raw =%ocr_text% ocr_t_raw =%ocr_t_text% ; End OCR processing ; Start OCR postprocessing ; Remove all CR+LF's from the contents If NoLineReturn = 1 { StringReplace, ocr_text, ocr_text, `r`n, , All } ; Remove all underscors from the contents: StringReplace, ocr_text, ocr_text, _, " ", All ; Remove all spaces from the contents: StringReplace, ocr_text, ocr_text, %A_SPACE%, , All ; Remove all " from the contents: StringReplace, ocr_text, ocr_text, """, "", All /* ; Only allow characters in CharOK, not finished CharOk := "abc" Loop { IfInString, CharOK, `r`n } */ ; End OCR postprocessing ; Copy postprocessed text to clipboard Clipboard =%ocr_text% /* ; Functions to post the result into a search #g:: Send, ^c Run, http://www.google.com/search?q=%Clipboard% Return #w:: Send, ^c Run, http://en.wikipedia.org/wiki/Special:Search?search=%Clipboard% Return */ ; Start GUI info Windows, function to show what we got, and how. For debugging mainly If InfoWindow = 1 { ; Print size data of screengrab Gui, +owner Gui, font, s10, Verdana ; Set 10-point Verdana. Gui, Add, Text,, The hight is %hight%, %scan_y_start% - %scan_y_end%. Gui, Add, Text,, The width is %width%, %scan_x_start% - %scan_x_end%. ; Show asci of raw screengrab in hex and preprocessed to rgb ; Start Fix, Edit field seems to krasch if large ImageArea := hight * width hex =Grab to large to show all hex, show first 10000 chars ony rgb =Grab to large to show all rgb, show first 10000 chars ony If ImageArea < 1000 { hex =%scan_current_line_source% rgb =%scan_current_line% gui, font,s2, Terminal Gui, Add, Edit, w600 h100 -wrap +HScroll +VScroll, %hex% Gui, Add, Edit, w600 h100 -wrap +HScroll +VScroll, %rgb% } else { StringLeft, hex_short, scan_current_line_source, 10000 StringLeft, rgb_short, scan_current_line, 10000 Gui, font, s10, Verdana ; Set 10-point Verdana. Gui, Add, Text,, %hex% gui, font,s2, Terminal Gui, Add, Edit, w600 h100 -wrap +HScroll +VScroll, %hex_short% Gui, font, s10, Verdana ; Set 10-point Verdana. Gui, Add, Text,, %rgb% gui, font,s2, Terminal Gui, Add, Edit, w600 h100 -wrap +HScroll +VScroll, %rgb_short% } ; End fix Gui, font, s10, Verdana ; Set 10-point Verdana. ; Convert images to compatible format for GUI, adjust size if large screengrab If ImageArea > 5000 { ; convert options to resize image con_options =-resize 300x200 } RunWait %convert_path%\convert %con_options% %TmpFile%.ppm %TmpFile%.bmp, %TmpDir%, hide, RunWait %convert_path%\convert %con_options% %TmpFile%.pbm %TmpFile%_ocr.bmp, %TmpDir%, hide, Gui, Add, Picture,, %TmpDir%\%TmpFile%.bmp Gui, Add, Picture,, %TmpDir%\%TmpFile%_ocr.bmp Gui, Add, Text,, ( Text from OCR: ) Gui, Add, Edit, xp+100, %Clipboard% Gui, Add, Edit, xp+150, %ocr_t_text% Gui, Add, Button, default, OK ; The label ButtonOK (if it exists) will be run when the button is pressed. Gui, Add, Button, Default xp+60, Rerun Gui, Show, AutoSize, Return ButtonOK: GuiClose: GuiEscape: Gui Destroy Return ButtonRerun: Gui, Submit Gosub, MainProcess Return } ; End GUI info Window /* ; Alternate method for positioning of screengrab ; press ctrl-alt-b (for "begin") ^!b:: CoordMode, Mouse, Screen MouseGetPos, scan_x_start, scan_y_start return */ ; Clean up tmp FileDelete %TmpDir%\%TmpFile%.ppm ; Color image, the raw screengrab picture FileDelete %TmpDir%\%TmpFile%.pgm ; Gray FileDelete %TmpDir%\%TmpFile%.pbm ; BW FileDelete %TmpDir%\%TmpFile%.txt Return Return AboutOptions: Gui, 2:+owner ; Make the main window (Gui #1) the owner of the "about box" (Gui #2). Gui +Disabled ; Disable main window. Gui, font, s12, Verdana ; Set 10-point Verdana. Gui, 2:Add, Text,, Tool for Text extraction from Screen grabs Gui, 2:Add, Text,, Options: Gui, 2:Add, Text, xs+10, Image Preprocessing Gui, 2:Add, Text, xs+20, mkbitmap: Gui, font, s10, Verdana ; Set 10-point Verdana. Gui, 2:Add, Checkbox, vmkb_i checked%mkb_i% xs+25, Invert image Gui, 2:Add, Edit, w35 vmkb_f xs+25, %mkb_f% Gui, 2:Add, Text, xp+40, Highpassfilter Gui, 2:Add, Edit, w35 vmkb_t xs+25, %mkb_t% Gui, 2:Add, Text, xp+40, Threshold Gui, 2:Add, Edit, w35 vmkb_s xs+25, %mkb_s% Gui, 2:Add, Text, xp+40, Scale by integer factor Gui, 2:Add, Radio, Group vmkb_s1 checked%mkb_s1% xs+25, Liner interpolation Gui, 2:Add, radio, vmkb_s2 checked%mkb_s2% xs+25, Cubic interpolation Gui, font, s12, Verdana ; Set 10-point Verdana. Gui, 2:Add, Text, xs+20, potrace: Gui, font, s10, Verdana ; Set 10-point Verdana. Gui, 2:Add, Checkbox, vprepotrace checked%prepotrace% xs+25, Run thrue potrace Gui, 2:Add, DropDownList, w100 vpot_z checked%pot_z% xs+25, black|white|right|left|minority||majority|random Gui, 2:Add, Text, xp+110, Path decomposition Gui, 2:Add, Edit, w35 vpot_t xs+25, %pot_t% Gui, 2:Add, Text, xp+40, Speckles size to remove Gui, 2:Add, Edit, w35 vpot_a xs+25, %pot_a% Gui, 2:Add, Text, xp+40, Corner threshold Gui, 2:Add, Checkbox, vpot_n checked%pot_n% xs+25, No curv optimization Gui, 2:Add, Edit, w35 vpot_o xs+25, %pot_o% Gui, 2:Add, Text, xp+40, Curve optimizion tolerance Gui, 2:Add, Edit, w35 vpot_u xs+25, %pot_u% Gui, 2:Add, Text, xp+40, Quantize output to 1/unit pixel Gui, 2:Add, Edit, w35 vpot_k xs+25, %pot_k% Gui, 2:Add, Text, xp+40, Black/white cutof Gui, 2:Add, Checkbox, vpot_i checked%pot_i% xs+25, Invert image Gui, 2:Add, Edit, w35 vpot_r xs+25, %pot_r% Gui, 2:Add, Text, xp+40, Rotate image clockwise degree Gui, 2:Add, Text,, Gui, font, s12, Verdana ; Set 10-point Verdana. Gui, 2:Add, Text, xs+10, OCR Gui, font, s10, Verdana ; Set 10-point Verdana. Gui, 2:Add, Text, xs+25, Operational Mode: Gui, 2:Add, Edit, w35 vocr_m xp+100, %ocr_m% Gui, 2:Add, Text, xp+40, ( Operation mode: 4 Barcode 16 divide overlapping chars 32 context correction 64 char packing ) Gui, 2:Add, Checkbox, vocr_n checked%ocr_n% xs+25, Only numbers Gui, 2:Add, Text,, Gui, 2:Add, Text, xs+10, OCR Postprocessing Gui, 2:Add, Checkbox, vNoLineReturn checked%NoLineReturn% xs+25, Remove line returns. Gui, 2:Add, Text,, Gui, font, s12, Verdana ; Set 10-point Verdana. Gui, 2:Add, Text, xs+10, GUI Gui, font, s10, Verdana ; Set 10-point Verdana. Gui, 2:Add, Checkbox, vFileSave checked%FileSave%, Allow FileSave Gui, 2:Add, Checkbox, vInfoWindow checked%InfoWindow%, Show Info Window. Gui, 2:Add, Text,, Gui, 2:Add, Button, Default, OK Gui, 2:Add, Button, Default xp+50, Save Gui, 2:Add, Button, Default xp+50, Cancel Gui, 2:Show, r x50 Return 2ButtonOK: Gui, 1:-Disabled ; Re-enable the main window (must be done prior to the next step). Gui, Submit Gui Destroy ; Destroy the about box. Return 2ButtonCancel: Gui, 1:-Disabled ; Re-enable the main window (must be done prior to the next step). Gui Destroy ; Destroy the about box. Return 2ButtonSave: Gui, Submit, NoHide Gui, 1:-Disabled ; Re-enable the main window (must be done prior to the next step). Return #^r:: ; Reload this script Reload Return
Hardware: fast laptop with SSD
Software: Win 7 Home Premium 64-bit, android for phone and tablet
; Requires gocr or tesseract, mkbitmap, potrace, and imagemagick. ; Default variables ; Temporary file options TmpDir = C:\Program Files\gocr\tmp TmpFile = image_out ; mkbitmap options mkbitmap = 1 ; 1, Preprocess screen grab using mkbitmap. 0, false. mkbitmap_path = C:\Program Files\gocr mkb_i = ; -i, inversion. Blank by default. mkb_f = 4 mkb_n = ; -n, nofilter. Turns off highpass filtering. Blank by default. mkb_s = 2 mkb_interpolation = "-1" ; "-3" or "-1". Cubic or linear interpolation. "-1" yields better results for text. mkb_t = 0.45 mkb_g = ; -g, grey. Only scales and greymaps the image. Blank by default. ; potrace options potrace = 1 ; 1, Preprocess screen grab using potrace. 0, false. potrace_path = C:\Program Files\gocr pot_z = minority ; black, white, right, left, minority, majority, random pot_t = 0 pot_a = 1 pot_n = ; Blank by default. "-n" turns off curve optimization. pot_O = 0.2 pot_u = 10 app = "gocr" ; gocr options gocr_path = C:\Program Files\gocr gocr_s = 0 gocr_d = -1 gocr_m = 32 gocr_n = 0 ; tesseract options convert_path = C:\Program Files\gocr tesseract_path = C:\Program Files\gocr ; Needs four variables representing the points needed for the scan. ; A set of coordinates for the upper left corner of the scan area (the origin), and a set for the lower right corner of the scan area. ; Represented by scan_x_start, scan_y_start, scan_x_end, scan_y_end. CoordMode, Pixel, Screen ; Sets pixel actions relative to coordinates of the full desktop window or the active window. Use the mode that you used to obtain the starting and ending coordinates of the image area. scan_current_x = %scan_x_start% ; Sets the starting x point of the scan. The origin of the window is the upper left corner. scan_current_y = %scan_y_start% ; Sets the starting y point of the scan. BlockInput, On Loop { scan_current_y++ if scan_current_y > %scan_y_end% { Break } Loop { scan_current_x++ if scan_current_x > %scan_x_end% { Break } PixelGetColor, current_pixel_color, %scan_current_x%, %scan_current_y%, RGB StringMid, current_pixel_r, current_pixel_color, 3, 2 StringMid, current_pixel_g, current_pixel_color, 5, 2 StringMid, current_pixel_b, current_pixel_color, 7, 2 ; Need to turn the value returned into a hexadecimal value. current_pixel_r = 0x%current_pixel_r% current_pixel_g = 0x%current_pixel_g% current_pixel_b = 0x%current_pixel_b% SetFormat, integer, d ; Need to perform a math operation using the variables in order to get them in integer decimal format. current_pixel_r -= 0 current_pixel_g -= 0 current_pixel_b -= 0 current_pixel_r := " " . current_pixel_r current_pixel_g := " " . current_pixel_g current_pixel_b := " " . current_pixel_b image_data = %image_data% %current_pixel_r% %current_pixel_g% %current_pixel_b% } image_data = %image_data% `n scan_current_x = %scan_x_start% } BlockInput, Off format := "P3`n", comment := "# File made using AutoHotkey.`n", width := scan_x_end - scan_x_start, height := scan_y_end - scan_y_start, max_colors := 255 file_data = %format% %comment% %width% %height% `n %max_colors% `n %image_data% ; Clean old temporary files. IfExist %TmpDir%\%TmpFile%.ppm { FileDelete %TmpDir%\%TmpFile%.ppm } ; End of cleaning. FileAppend, %file_data%, *%TmpDir%\%TmpFile%.ppm ImageFormat = "ppm" If mkbitmap = 1 { RunWait, %mkbitmap_path%\mkbitmap.exe %mkb_i% -f %mkb_f% %mkb_n% -s %mkb_s% %mkb_interpolation% -t %mkb_t% %mkb_g% "%TmpDir%\%TmpFile%.ppm" -o "%TmpDir%\%TmpFile%.pbm", %mkbitmap_path%, hide, ImageFormat = "pbm" } If potrace = 1 { RunWait, %potrace_path%\potrace.exe -z %pot_z% -t %pot_t% -a %pot_a% %pot_n% -O %pot_O% -u %pot_u% -g -o "%TmpDir%\%TmpFile%.pgm" "%TmpDir%\%TmpFile%.%ImageFormat%", %potrace_path%, hide, ImageFormat = "pgm" } If app = "gocr" { RunWait, %gocr_path%\gocr.exe -i "%TmpDir%\%TmpFile%.%ImageFormat%" -s %gocr_s% -d %gocr_d% -m %gocr_m% -n %gocr_n% -o "%TmpDir%\%TmpFile%.txt", %gocr_path%, Hide, } /* Code not functional. Else If app = "tesseract" { RunWait, %convert_path%\convert.exe "%TmpDir%\%TmpFile%.%ImageFormat%" "%TmpDir%\%TmpFile%.bmp", %convert_path%, hide, ImageFormat = "bmp" RunWait, %tesseract_path%\tesseract.exe "%TmpDir%\%TmpFile%.%ImageFormat%" "%TmpDir%\%TmpFile%.txt", %tesseract_path%, UseErrorLevel, MsgBox, %errorlevel% } */
Here's a rewrite of the original script. (Minus selection functionality. This way you could pass coordinates to it as a function.) I couldn't get my tesseract executable to work. Kept getting system error 1.
fwiw, the version of tesseract I have came with Softi FreeOCR. It put tesseract.exe and tessdata folder into my Windows directory; the rest of the program resides in various Program Files and Documents and Settings folders, but I suppose m2's script doesn't need those.
not sure if this works anymore, but I downloaded FreeOCR from here: http://www.brotherso...eocr-59672.html
I wrote a small print text at the bottom of one of my earlier posts with details because I had trouble finding all software needed to go with this project.
Hardware: fast laptop with SSD
Software: Win 7 Home Premium 64-bit, android for phone and tablet
Your documentation has been quite thorough and awesome !fwiw, the version of tesseract I have came with Softi FreeOCR. It put tesseract.exe and tessdata folder into my Windows directory; the rest of the program resides in various Program Files and Documents and Settings folders, but I suppose m2's script doesn't need those.
not sure if this works anymore, but I downloaded FreeOCR from here: http://www.brotherso...eocr-59672.html
I wrote a small print text at the bottom of one of my earlier posts with details because I had trouble finding all software needed to go with this project.
Your work on this has lead me to a workable version that I am content with. Kudos to you and M2 and others that paved the way -- bigtime ! :mrgreen:
Basically re-used Pajenn's last code and set Clipboard =%ocr_t_text%, remove gocr lines [optional]; thats it.
http://www.viddler.c...ngCR/videos/60/ [Full Screen recommended]
you've not published your code/package in zip, etc.,
because you don't want the Finns to get their hands on it ??
hope you all don't mind.
Most of the relative paths *Should* work out of the box... with the exception of the TempDir variable (see below)
screenreader_ocr.zip (17 MB) !!
one small note,
the gocr.exe file needs a dos-passable path.
this means that /Documents and Settings/ doesn't work,
you have to write it /Documen~1/
So for the TempDir Variable (at the top), make sure you write out the whole absolute path, because otherwise the %A_workingDir% won't cut it.
The symptom is that no error messages are displayed, and pictures are popping up, but the final ocr text fields are both blank.
Hopefully this is helpful for someone!
-M1m1K
Thanks for that,
but I can not seem to get it to work - no matter what i select it does not copy the image even to perform the OCR.
Can anyone tell me what I am doing wrong?
Just for info i unzipped it to C:\ocr\ and updated the one line for the Temp file to c:\ocr\temp .
any help would be really appreciated!!!!!
After you press win+q and the screen grays out to take the snapshot, you left click drag the selection box and unleft click BUT it only works on a drag from left to right not right to left.
I was dragging the box right to left......
Hope this helps others
It needs a bit of work on the GUI side, but the capturing/OCR-ing works pretty solidly.
Links to all programs needed are in the script.
Please let me know what you think, this has been a lot of trial and error and I'd love other peoples' opinion as to the usage, settings and my code.
/* requirements: nconvert.exe (place in .\app subfolder) http://www.xnview.com/en/download.html MKBitmap and POTrace (place in app subfolder) http://potrace.sourceforge.net/#downloading Tesseract (place in .\app\tesseract subfolder) http://code.google.com/p/tesseract-ocr/downloads/list GOCR.exe (place in .\app subfolder) http://jocr.sourceforge.net/download.html code borrowed from: http://www.autohotkey.com/forum/viewtopic.php?t=49950 (the grabbing GUI) http://www.autohotkey.com/forum/viewtopic.php?t=35600 (the cursor changes) description: This script allows a user to select a rectangle to OCR to clipboard. What it basically does is : 1. copy the rectangle to the clipboard using the capture subroutine (called by ctrl-leftclick) 2. using NConvert the clipboard is converted to a BMP file 3. using MKBitmap the file is optimised with scaling and filtering 4. using potrace the file is then transformed into vector graphics if Tesseract is set as OCR: 5. using NConvert the clipboard is converted to a TIFF file else if GOCR is set as OCR: 5. using NConvert the clipboard is converted to a BMP file 6. using either Tesseract or GOCR the file is "read" 7. the result is read and copied to the clipboard (if it contains text) to do: - make a GUI to set the parameters of each app - allow user to get rid of line endings in the OCR_Text variable */ #persistent #SingleInstance Force SetBatchLines -1 ; maximum speed for loops #NoEnv #MaxThreadsPerHotkey 1 ; enable correction on accidental press of several hotkeys (only last pressed hotkey will be fired) app_name = ahk-ocr app_version = 0.0.008 app_author = Maestr0 ini_file = %A_ScriptDir%\ahk-ocr.ini app_icon = %A_ScriptDir%\ahk-ocr.ico gosub menu gosub read_variables hotkey Lbutton , capture , off hotkey escape , capture_off, off gosub capture_on return menu: ifexist %app_icon% Menu, Tray, Icon, %app_icon% Menu, Tray, Tip, %app_name% %app_version% Menu, tray, NoStandard Menu, tray, add, %app_name% %app_version%, menu_reload Menu, tray, add Menu, tray, add, Capture, capture_toggle Menu, tray, default, Capture Menu, tray, add if A_IsCompiled <> 1 { Menu, StandardMenu, Standard Menu, tray, add, Standard menu options, :StandardMenu Menu, tray, add } Menu, tray, add, Einde, menu_exit return menu_reload: reload menu_exit: exitapp capture_toggle: if capture_mode = 1 gosub capture_off else gosub capture_on return capture_on: capture_mode = 1 hotkey Lbutton , capture, on hotkey escape , capture_off, on Menu, tray, Check, Capture settimer , tooltip_start , 50 SetSystemCursor("IDC_CROSS") ; sets the mouse cursor to a big + return capture_off: ToolTip ; clears any tooltip that may be showing capture_mode = 0 hotkey Lbutton , capture, off hotkey escape , capture_off, off Menu, tray, Uncheck, Capture gosub RestoreCursors ; restores the mouse cursor settimer , tooltip_start , off return read_variables: IniRead, test, %ini_file%, general, test, 0 IniRead, tmpfolder, %ini_file%, general, tmpfolder, %A_Temp% IniRead, ocr_engine, %ini_file%, general, ocr_engine, Tesseract IniRead, app_nconvert, %ini_file%, general, app_nconvert, %A_ScriptDir%\app\nconvert.exe IniRead, app_mkbitmap, %ini_file%, general, app_mkbitmap, %A_ScriptDir%\app\mkbitmap.exe IniRead, app_potrace, %ini_file%, general, app_potrace, %A_ScriptDir%\app\potrace.exe IniRead, app_tesseract, %ini_file%, general, app_tesseract, %A_ScriptDir%\app\tesseract\tesseract.exe IniRead, app_gocr, %ini_file%, general, app_gocr, %A_ScriptDir%\app\gocr.exe IniRead, url_nconvert, %ini_file%, general, url_nconvert, http://www.xnview.com/en/download.html IniRead, url_mkbitmap, %ini_file%, general, url_mkbitmap, http://potrace.sourceforge.net/#downloading IniRead, url_potrace, %ini_file%, general, url_potrace, http://potrace.sourceforge.net/#downloading IniRead, url_tesseract, %ini_file%, general, url_tesseract, http://code.google.com/p/tesseract-ocr/downloads/list IniRead, url_gocr, %ini_file%, general, url_gocr, http://jocr.sourceforge.net/download.html check_instance(app_nconvert,url_nconvert) check_instance(app_mkbitmap,url_mkbitmap) check_instance(app_potrace,url_potrace) if ocr_engine = gocr check_instance(app_gocr,url_gocr) else check_instance(app_tesseract,url_tesseract) return check_instance(location,url) ; checks the existence for a needed app, if it's not found, a message appears and the script goes dormant again { ifnotexist %location% { msgbox % "A required file does not exist:`n" location "`n`nDownload it using the link below and try again.`n`n" url gosub capture_off return } } capture: ;=== step 0 ======================================================================== ; Before we do anything, read the variables, maybe they changed since the start of the script gosub read_variables ;=== step 1 ======================================================================== ; Allow the user to select an area for the OCR and save selected area without cursor in clipboard if ( clipboard <> "" ) OR ( test <> 1 ) gosub get_area gosub capture_off ; to turn the active mode to off ;=== step 2 ======================================================================== ; Clean up the temporary files that may have been left behind FileDelete %tmpfolder%\1_nconvert_output*.* FileDelete %tmpfolder%\2_mkbitmap_output*.* FileDelete %tmpfolder%\3_potrace_output*.* FileDelete %tmpfolder%\4_nconvert_output*.* FileDelete %tmpfolder%\tesseract_output*.* FileDelete %tmpfolder%\gocr_output*.* ;=== step 3 ======================================================================== ; 3a: Load parameters for command line tools IniRead, parameters_nconvert, %ini_file%, parameters, nconvert, %A_Space% IniRead, parameters_mkbitmap, %ini_file%, parameters, mkbitmap, -f 4 -s 3 -t 0.48 IniRead, parameters_potrace, %ini_file%, parameters, potrace, -O 0.2 -k 0.5 -r 0 -t 2 -g -a 4 IniRead, parameters_tesseract, %ini_file%, parameters, tesseract, %A_Space% ; 3b: NConvert: Convert the clipboard to an image file RunWait , "%app_nconvert%" %parameters_nconvert% -overwrite -out bmp -o 1_nconvert_output.bmp -clipboard, %tmpfolder%, hide ; 3c: MKBitmap: transform images into bitmaps with scaling and filtering RunWait , "%app_mkbitmap%" %parameters_mkbitmap% -o 2_mkbitmap_output.pbm 1_nconvert_output.bmp, %tmpfolder%, hide ; 3d: Potrace: transform bitmaps into vector graphics. RunWait , "%app_potrace%" %parameters_potrace% -o 3_potrace_output.pgm 2_mkbitmap_output.pbm, %tmpfolder%, hide if ocr_engine = gocr { ; 3e: NConvert: Convert the clipboard to an image file RunWait , "%app_nconvert%" -overwrite -out pnm -o 4_nconvert_output.pnm 3_potrace_output.pgm, %tmpfolder%, hide ; 3f: GOCR: The actual OCR RunWait , "%app_gocr%" %parameters_gocr% 4_nconvert_output.pnm gocr_output, %tmpfolder%, hide } else ; this is the default: Tesseract { ; 3e: NConvert: Convert the clipboard to an image file RunWait , "%app_nconvert%" -overwrite -out tiff -o 4_nconvert_output.tif 3_potrace_output.pgm, %tmpfolder%, hide ; 3f: Tesseract: The actual OCR RunWait , "%app_tesseract%" %parameters_tesseract% 4_nconvert_output.tif tesseract_output, %tmpfolder%, hide } ;=== step 4 ======================================================================== ; Read the OCR contents to the clipboard FileRead OCR_text, %tmpfolder%\tesseract_output.txt if OCR_Text = outputdebug Error`, no text was detected. else { n := 5000 SetTimer, tooltip_finish, 50 SetTimer, RemoveToolTip, 5000 clipboard := OCR_text } if test = 1 run %tmpfolder%\tesseract_output.txt return tooltip_start: Tooltip, Maak een kader om de te herkennen tekst.`nDruk op Escape om te annuleren.,%tx%,%ty% return tooltip_finish: n -= 100 sec := ceil(n/1000) MouseGetPos, xpos, ypos xpos += 16 ypos += 16 if sec > 1 Tooltip , De tekst is herkend en op je klembord gezet.`nDit bericht sluit automatisch na %sec% seconden., %xpos%, %ypos%, else Tooltip return RemoveToolTip: SetTimer, RemoveToolTip, Off SetTimer, tooltip_finish, Off ToolTip return ;===Description======================================================================== ; Source: Screen clipping script. Saves selected area to clipboard. http://www.autohotkey.com/forum/viewtopic.php?t=49950 ;===Functions========================================================================== CaptureScreen(aRect) { StringSplit, rt, aRect, `,, %A_Space%%A_Tab% nL := rt1 nT := rt2 nW := rt3 - rt1 nH := rt4 - rt2 znW := rt5 znH := rt6 mDC := DllCall("CreateCompatibleDC", "Uint", 0) hBM := CreateDIBSection(mDC, nW, nH) oBM := DllCall("SelectObject", "Uint", mDC, "Uint", hBM) hDC := DllCall("GetDC", "Uint", 0) DllCall("BitBlt", "Uint", mDC, "int", 0, "int", 0, "int", nW, "int", nH, "Uint", hDC, "int", nL, "int", nT, "Uint", 0x40000000 | 0x00CC0020) DllCall("ReleaseDC", "Uint", 0, "Uint", hDC) DllCall("SelectObject", "Uint", mDC, "Uint", oBM) DllCall("DeleteDC", "Uint", mDC) SetClipboardData(hBM) } CreateDIBSection(hDC, nW, nH, bpp = 32, ByRef pBits = "") { NumPut(VarSetCapacity(bi, 40, 0), bi) NumPut(nW, bi, 4) NumPut(nH, bi, 8) NumPut(bpp, NumPut(1, bi, 12, "UShort"), 0, "Ushort") NumPut(0, bi,16) Return DllCall("gdi32\CreateDIBSection", "Uint", hDC, "Uint", &bi, "Uint", 0, "UintP", pBits, "Uint", 0, "Uint", 0) } SetClipboardData(hBitmap) { DllCall("GetObject", "Uint", hBitmap, "int", VarSetCapacity(oi,84,0), "Uint", &oi) hDIB := DllCall("GlobalAlloc", "Uint", 2, "Uint", 40+NumGet(oi,44)) pDIB := DllCall("GlobalLock", "Uint", hDIB) DllCall("RtlMoveMemory", "Uint", pDIB, "Uint", &oi+24, "Uint", 40) DllCall("RtlMoveMemory", "Uint", pDIB+40, "Uint", NumGet(oi,20), "Uint", NumGet(oi,44)) DllCall("GlobalUnlock", "Uint", hDIB) DllCall("DeleteObject", "Uint", hBitmap) DllCall("OpenClipboard", "Uint", 0) DllCall("EmptyClipboard") DllCall("SetClipboardData", "Uint", 8, "Uint", hDIB) DllCall("CloseClipboard") } get_area: CoordMode, Mouse ,Screen CoordMode, Tooltip ,Screen MouseGetPos, MX, MY Gui, +AlwaysOnTop -caption +Border +ToolWindow +LastFound WinSet, Transparent, 80 Gui, Color, lime ; shut tooltip_start off settimer , tooltip_start , off tooltip While, (GetKeyState("LButton", "p")) { MouseGetPos, MXend, MYend Send {control up} w := abs(MX - MXend) h := abs(MY - MYend) If ( MX < MXend ) { X := MX tx := MX + 2 } Else { X := MXend tx := MX + 16 } If ( MY < MYend ) { Y := MY tY := MY - 20 } Else { Y := MYend tY := MY + 16 } Gui, Show, x%X% y%Y% w%w% h%h% MouseGetPos, xpos, ypos Tooltip, Maak een kader om de te herkennen tekst.,%tx%,%ty% Sleep, 10 } ToolTip gosub RestoreCursors ; restores the mouse cursor MouseGetPos, MXend, MYend Gui, Destroy If ( MX > MXend ) { temp := MX MX := MXend MXend := temp } If ( MY > MYend ) { temp := MY MY := MYend MYend := temp } Area = %MX%, %MY%, %MXend%, %MYend% Sleep, 100 ; if omitted, GUI sometimes stays in picture CaptureScreen(Area) ; Saves selected area without cursor in Clipboard. return OnExit: ToolTip Suspend gosub RestoreCursors ; restores the mouse cursor ExitApp ; -------------- ; below is just to change the mouse cursor so it's clear when the capture mode is active ; source: http://www.autohotkey.com/forum/viewtopic.php?t=35600 SetSystemCursor( Cursor = "", cx = 0, cy = 0 ) { BlankCursor := 0, SystemCursor := 0, FileCursor := 0 ; init SystemCursors = 32512IDC_ARROW,32513IDC_IBEAM,32514IDC_WAIT,32515IDC_CROSS ,32516IDC_UPARROW,32640IDC_SIZE,32641IDC_ICON,32642IDC_SIZENWSE ,32643IDC_SIZENESW,32644IDC_SIZEWE,32645IDC_SIZENS,32646IDC_SIZEALL ,32648IDC_NO,32649IDC_HAND,32650IDC_APPSTARTING,32651IDC_HELP If Cursor = ; empty, so create blank cursor { VarSetCapacity( AndMask, 32*4, 0xFF ), VarSetCapacity( XorMask, 32*4, 0 ) BlankCursor = 1 ; flag for later } Else If SubStr( Cursor,1,4 ) = "IDC_" ; load system cursor { Loop, Parse, SystemCursors, `, { CursorName := SubStr( A_Loopfield, 6, 15 ) ; get the cursor name, no trailing space with substr CursorID := SubStr( A_Loopfield, 1, 5 ) ; get the cursor id SystemCursor = 1 If ( CursorName = Cursor ) { CursorHandle := DllCall( "LoadCursor", Uint,0, Int,CursorID ) Break } } If CursorHandle = ; invalid cursor name given { Msgbox,, SetCursor, Error: Invalid cursor name CursorHandle = Error } } Else If FileExist( Cursor ) { SplitPath, Cursor,,, Ext ; auto-detect type If Ext = ico uType := 0x1 Else If Ext in cur,ani uType := 0x2 Else ; invalid file ext { Msgbox,, SetCursor, Error: Invalid file type CursorHandle = Error } FileCursor = 1 } Else { Msgbox,, SetCursor, Error: Invalid file path or cursor name CursorHandle = Error ; raise for later } If CursorHandle != Error { Loop, Parse, SystemCursors, `, { If BlankCursor = 1 { Type = BlankCursor %Type%%A_Index% := DllCall( "CreateCursor" , Uint,0, Int,0, Int,0, Int,32, Int,32, Uint,&AndMask, Uint,&XorMask ) CursorHandle := DllCall( "CopyImage", Uint,%Type%%A_Index%, Uint,0x2, Int,0, Int,0, Int,0 ) DllCall( "SetSystemCursor", Uint,CursorHandle, Int,SubStr( A_Loopfield, 1, 5 ) ) } Else If SystemCursor = 1 { Type = SystemCursor CursorHandle := DllCall( "LoadCursor", Uint,0, Int,CursorID ) %Type%%A_Index% := DllCall( "CopyImage" , Uint,CursorHandle, Uint,0x2, Int,cx, Int,cy, Uint,0 ) CursorHandle := DllCall( "CopyImage", Uint,%Type%%A_Index%, Uint,0x2, Int,0, Int,0, Int,0 ) DllCall( "SetSystemCursor", Uint,CursorHandle, Int,SubStr( A_Loopfield, 1, 5 ) ) } Else If FileCursor = 1 { Type = FileCursor %Type%%A_Index% := DllCall( "LoadImageA" , UInt,0, Str,Cursor, UInt,uType, Int,cx, Int,cy, UInt,0x10 ) DllCall( "SetSystemCursor", Uint,%Type%%A_Index%, Int,SubStr( A_Loopfield, 1, 5 ) ) } } } } return RestoreCursors: SPI_SETCURSORS := 0x57 DllCall( "SystemParametersInfo", UInt,SPI_SETCURSORS, UInt,0, UInt,0, UInt,0 ) return /* comparison between Tesseract and GOCR with the same image files: --------------- Tesseract For two years I spent my early mornings walking the streets of West Oakland in the San Francisco Bay Area. lt is a neighborhood steeped in history and diversity, from ship workers to blues musicians. Yet, as freeways were built and factories moved in, the neighborhood became cut off from the rest of city and left isolated and forgotten by many. As I spent time photographing in West Oakland, I began to hnd beauty in the unique and improvised envimnment that was born from the neighborhoods very isolation. Sometimes it was a sad and hard beauty, but often it was hopeful and timeless. I also found intimate moments of ritual that stem from the neighborhood's mixed rural Southem and Latino heritage. These photographs describe the stories and spaces that I found on my walks through West Oakland. --------------- GOCR for mo years t spent my early mornings wa lking the streets ot West Oakland in the San francisco 8ay Area. lt is a neighborhood steeped in hi_oN and diversiN, trom ship workers to blues m_sicians. Yet, as freeways were buitt and tactories moved in, the neighborhood became cut off trom the rest of ciN and le_ isolated and torgottenbymany. As l sp$nt _m_ photogr8phing in We_ 08_l8nd, I beg8n to F_nd be8uN in _8 uniqu8 8nd impro_sed 8nvi_nme___w8s born trom _8 neighbomood's _N isol8_on. Same_mes _ w8s 8 s8d 8nd h8rd b$8u_, but o_en it w8s hop$ful 8nd tim$lest l 8lso tound i_m8te mome_ _ r0' 8l th8t stem trom lh_ neighbomood's mixed _r8l Southem 8nd __no hent8g8. mes_ photogr8phs descnb_ lh_ _ones 8nd sp8ces __ I tound on my w8lks _rough Wen 08tI8nd. */
Comments still welcomed
/* requirements: NConvert (place in .\app subfolder) http://www.xnview.com/en/download_nc.html MKBitmap and POTrace (place both in .\app subfolder) http://potrace.sourceforge.net/#downloading Tesseract (place in .\app\tesseract subfolder) http://code.google.com/p/tesseract-ocr/downloads/list GOCR (optional app (default is Tesseract) place in .\app\gocr subfolder) http://jocr.sourceforge.net/download.html code borrowed from: http://www.autohotkey.com/forum/viewtopic.php?t=49950 (the grabbing GUI) http://www.autohotkey.com/forum/viewtopic.php?t=35600 (the cursor changes) description: This script allows a user to select a rectangle to OCR to clipboard. What it basically does is : 1. copy the rectangle to the clipboard using the capture subroutine (called by ctrl-leftclick) 2. using NConvert the clipboard is converted to a BMP file (using parameters) 3. using MKBitmap the file is optimised with scaling and filtering 4. using potrace the file is then transformed into vector graphics if Tesseract is set as OCR: 5. using NConvert the clipboard is converted to a TIFF file (without parameters) else if GOCR is set as OCR: 5. using NConvert the clipboard is converted to a BMP file (without parameters) 6. using either Tesseract or GOCR the file is "read" 7. the result is read and copied to the clipboard (if it contains text) to do: - make a GUI to set the parameters of each app - decide what backend is the best for potrace - allow user to get rid of line endings in the OCR_Text variable - allow a hotkey to enable/disable capture mode - allow the hotkey to enable/disable capture mode to be changed through the GUI - scan for tesseract available languages and allow a choice in the GUI - language problem being entered in the GUI on load */ #persistent #SingleInstance Force SetBatchLines -1 ; maximum speed for loops #NoEnv #MaxThreadsPerHotkey 1 ; enable correction on accidental press of several hotkeys (only last pressed hotkey will be fired) app_name = ahk-ocr app_version = 0.0.011 app_author = Maestr0 ini_file = %A_ScriptDir%\ahk-ocr.ini app_icon = %A_ScriptDir%\ahk-ocr.ico gosub menu gosub read_variables hotkey Lbutton , capture , off hotkey escape , capture_off, off if Capture_on_startup = 1 gosub capture_on gosub gui ; just for testing return read_variables: IniRead, test, %ini_file%, general, test, 0 IniRead, tmpfolder, %ini_file%, general, tmpfolder, %A_Temp% IniRead, ocr_engine, %ini_file%, general, ocr_engine, Tesseract IniRead, app_nconvert, %ini_file%, general, app_nconvert, %A_ScriptDir%\app\nconvert.exe IniRead, app_mkbitmap, %ini_file%, general, app_mkbitmap, %A_ScriptDir%\app\mkbitmap.exe IniRead, app_potrace, %ini_file%, general, app_potrace, %A_ScriptDir%\app\potrace.exe IniRead, app_tesseract, %ini_file%, general, app_tesseract, %A_ScriptDir%\app\tesseract\tesseract.exe IniRead, app_gocr, %ini_file%, general, app_gocr, %A_ScriptDir%\app\gocr\gocr.exe IniRead, url_nconvert, %ini_file%, general, url_nconvert, http://www.xnview.com/en/download.html IniRead, url_mkbitmap, %ini_file%, general, url_mkbitmap, http://potrace.sourceforge.net/#downloading IniRead, url_potrace, %ini_file%, general, url_potrace, http://potrace.sourceforge.net/#downloading IniRead, url_tesseract, %ini_file%, general, url_tesseract, http://code.google.com/p/tesseract-ocr/downloads/list IniRead, url_gocr, %ini_file%, general, url_gocr, http://jocr.sourceforge.net/download.html SplitPath, app_gocr,, path_gocr IniRead, db_gocr, %ini_file%, general, db_gocr, %path_gocr%\db\ StringReplace, db_gocr, db_gocr, %A_ScriptDir%, . ; the ...._n_params are the parameters which have additional values nconvert_n_params = contrast,deinterlace,eedge mkbitmap_n_params = f,s,t potrace_n_params = z,t,a,n,o,u,r tesseract_n_params = l gocr_n_params = p,l,d,s,m,a gosub collect_tesseract_languages check_instance(app_nconvert,url_nconvert) check_instance(app_mkbitmap,url_mkbitmap) check_instance(app_potrace,url_potrace) if ocr_engine = gocr check_instance(app_gocr,url_gocr) else check_instance(app_tesseract,url_tesseract) IniRead, NoLineReturn, %ini_file%, general, NoLineReturn, 0 IniRead, Capture_on_startup, %ini_file%, general, Capture_on_startup, 1 IniRead, CleanTemporaryOutput, %ini_file%, general, CleanTemporaryOutput, 1 IniRead, parameters_nconvert, %ini_file%, parameters, nconvert, %A_Space% IniRead, parameters_mkbitmap, %ini_file%, parameters, mkbitmap, -f 4 -s 3 -t 0.48 IniRead, parameters_potrace, %ini_file%, parameters, potrace, -O 0.2 -r 0 -t 2 -g -a 4 IniRead, parameters_tesseract, %ini_file%, parameters, tesseract, %A_Space% IniRead, parameters_gocr, %ini_file%, parameters, gocr, %A_Space% ; the parameters below are meant for settings that cannot be changed in the GUI, the parameters above in the ini file will be overwritten by selections in the GUI IniRead, parameters_nconvert_override, %ini_file%, parameters, nconvert, %A_Space% IniRead, parameters_mkbitmap_override, %ini_file%, parameters, mkbitmap, %A_Space% IniRead, parameters_potrace_override, %ini_file%, parameters, potrace, %A_Space% IniRead, parameters_tesseract_override, %ini_file%, parameters, tesseract, %A_Space% IniRead, parameters_gocr_override, %ini_file%, parameters, gocr, %A_Space% return check_instance(location,url) ; checks the existence for a needed app, if it's not found, a message appears and the script goes dormant again { ifnotexist %location% { msgbox % "A required file does not exist:`n" location "`n`nDownload it using the link below and try again.`n`n" url gosub capture_off return } } gui: GUI, destroy gosub read_variables ; make sure the last settings are loaded gui_width = 600 tab_left = 22 tab_right = 22 tab_width := gui_width - tab_left - tab_right gui_height := gui_width + 50 tab_top = 32 tab_bottom = 10 tab_height := gui_height - tab_top - tab_bottom ; ---- you shouldn't have to change anything in the GUI below, that's what the variables directly above are for ifexist %app_gocr% Gui, Add, Tab2, % "-wrap h" tab_height " w" gui_width - tab_left, General|NConvert|MKBitmap|Potrace|Tesseract|GOCR|About else Gui, Add, Tab2, % "-wrap h" tab_height " w" gui_width - tab_left, General|NConvert|MKBitmap|Potrace|Tesseract|About GUI, Tab, General GUI, add, Text, x%tab_left% y%tab_top% w%tab_width% section, General settings GUI, add, checkbox, xs w%tab_width% vNoLineReturn checked%NoLineReturn%, Remove Line returns after OCR GUI, add, checkbox, xs w%tab_width% vCapture_on_startup checked%Capture_on_startup%, Start a capture immediately afters loading the script GUI, add, checkbox, xs w%tab_width% vCleanTemporaryOutput checked%CleanTemporaryOutput%, Delete temporary files after OCR ifexist %app_gocr% { GUI, add, Text, xs+15 section, Choose OCR program: GUI, add, DropDownList, ys-3 w150 gchoose_engine vocr_engine, Tesseract|GOCR GUIControl, ChooseString, ocr_engine, %ocr_engine% } /* parse the parameters to figure out which boxes to check and which values to enter mkbitmap, -f 4 -s 3 -t 0.48 potrace, -O 0.2 -k 0.5 -r 0 -t 2 -g -a 4 */ GUI, Tab, mkbitmap GUI, add, Text, x%tab_left% y%tab_top% w%tab_width% section, mkbitmap processing options GUI, add, checkbox, xs w%tab_width% vmkb_i section, %A_Space%-i : Invert the input image. GUI, add, checkbox, xs w%tab_width% vmkb_f gcheckedit section, %A_Space%-f : Apply a highpass filter to the image. GUI, add, edit, xs20 w50 right number limit100 vmkb_f_edit disabled, GUI, add, checkbox, xs w%tab_width% vmkb_n section, %A_Space%-n : Turn off highpass filtering. GUI, add, checkbox, xs w%tab_width% vmkb_b gcheckedit section, %A_Space%-b : Blur the image to reduce visual noise. GUI, add, edit, xs20 w50 right number limit100 vmkb_b_edit disabled, GUI, add, checkbox, xs w%tab_width% vmkb_s gcheckedit section, %A_Space%-s : Scale the image by an integer factor great than 0. GUI, add, edit, xs20 w50 right number limit100 vmkb_s_edit disabled, GUI, add, checkbox, xs w%tab_width% vmkb_l section, %A_Space%-l : Use linear interpolation when scaling to a higher resolution. GUI, add, checkbox, xs w%tab_width% vmkb_3 section, %A_Space%-3 : Use cubic interpolation when scaling to a higher resolution. (default) GUI, add, checkbox, xs w%tab_width% vmkb_t gcheckedit section, %A_Space%-t : Set the threshold grey value for bilevel conversion. (0 = black, 1 = white) GUI, add, edit, xs20 w50 right number limit100 vmkb_t_edit disabled, GUI, add, checkbox, xs w%tab_width% vmkb_g section, %A_Space%-g : Disable bilevel conversion, processing stops after the scaling step and a greymap is output. GUI, add, Text, xs w%tab_width%, `nDescription:`n`nmkbitmap reads an image and applies one or more of the following operations to it`nin this order: inversion, highpass filtering, scaling, and thresholding. Each operation can be individually controlled and turned on or off. /* potrace -b name, --backend name Select backend by name, where name is one of eps, postscript, ps, pdf, pdfpage, svg, pgm, gimppath, xfig. Backend names can be abbreviated by an unambiguous prefix. -e, --eps, -b eps, --backend eps Encapsulated PostScript backend (default). The input is a single bitmap; the output is a stand-alone, encapsulated PostScript file that can be included in other documents. */ GUI, Tab, potrace GUI, add, Text, x%tab_left% y%tab_top% w%tab_width% section, potrace processing options GUI, add, checkbox, xs w%tab_width% vpot_z gcheckedit section, %A_Space%-z : Specify how to resolve ambiguities in path decomposition.`nMust be one of black, white, right, left, minority, majority, or random. Default is minority. GUI, add, edit, xs20 w50 right number limit100 vpot_z_edit disabled, GUI, add, checkbox, xs w%tab_width% vpot_t gcheckedit section, %A_Space%-t : Suppress speckles of up to this many pixels. GUI, add, edit, xs20 w50 right number limit100 vpot_t_edit disabled, GUI, add, checkbox, xs w%tab_width% vpot_a gcheckedit section, %A_Space%-a : Set the corner threshold parameter. The smaller this value, the more sharp corners will be produced. If this parameter is negative, then no smoothing will be performed and the output is a polygon. GUI, add, edit, xs20 w50 right number limit100 vpot_a_edit disabled, GUI, add, checkbox, xs w%tab_width% vpot_n gcheckedit section, %A_Space%-n : Turn off curve optimization. Larger values allow more consecutive Bezier curve segments to be joined together in a single segment, at the expense of accuracy. GUI, add, edit, xs20 w50 right number limit100 vpot_n_edit disabled, GUI, add, checkbox, xs w%tab_width% vpot_o gcheckedit section, %A_Space%-o : Set the curve optimization tolerance. Larger values allow more consecutive Bezier curve segments at the expense of accuracy. GUI, add, edit, xs20 w50 right number limit100 vpot_o_edit disabled, GUI, add, checkbox, xs w%tab_width% vpot_u gcheckedit section, %A_Space%-u : Set output quantization, output is rounded to 1/unit pixels. The default of 10 usually gives good results. For some of the debug modes, a value of 100 gives more accurate output. GUI, add, edit, xs20 w50 right number limit100 vpot_u_edit disabled, GUI, add, checkbox, xs w%tab_width% vpot_i section, %A_Space%-i : Invert GUI, add, checkbox, xs w%tab_width% vpot_r gcheckedit section, %A_Space%-r : set the resolution (in dpi). Note that it follows that a larger value results in a smaller output image. It is possible to specify different resolutions in the x and y directions by giving an argument of the form nxn. GUI, add, edit, xs20 w50 right number limit100 vpot_r_edit disabled, GUI, add, Text, xs w%tab_width%, `nDescription:`n`npotrace is a utility for tracing a bitmap, which means, transforming a bitmap into a smooth, scalable image. The input is a bitmap, which means, a pixel-based image composed of the two colors black and white only. The default output is an encapsulated PostScript file (EPS). A typical use is to create EPS files from scanned data, such as company or university logos, handwritten notes, etc. The resulting image is not "jaggy" like a bitmap, but smooth. It can then be rendered at any resolution. GUI, Tab, NConvert ; contrast,deinterlace,eedge GUI, add, Text, x%tab_left% y%tab_top% w%tab_width% section, NConvert converting options GUI, add, checkbox, xs w%tab_width% vncon_autocontrast section, %A_Space%-autocontrast : Auto Contrast GUI, add, checkbox, xs w%tab_width% vncon_autolevels section, %A_Space%-autolevels : Auto Levels GUI, add, checkbox, xs w%tab_width% vncon_contrast gcheckedit section, %A_Space%-contrast : Modify contrast (-100...100) GUI, add, edit, xs20 w50 right number limit100 vncon_contrast_edit disabled, GUI, add, checkbox, xs w%tab_width% vncon_dither section, %A_Space%-dither : Use Bayer dithering for conversion (Colors and Grey only) GUI, add, checkbox, xs w%tab_width% vncon_deinter gcheckedit section, %A_Space%-deinter : De-interlace (k = even or odd, n = dup or int) GUI, add, edit, xs20 w50 right number limit100 vncon_deinter_edit disabled, GUI, add, checkbox, xs w%tab_width% vncon_edetail section, %A_Space%-edetail : Enhance detail GUI, add, checkbox, xs w%tab_width% vncon_efocus section, %A_Space%-efocus : Enhance focus GUI, add, checkbox, xs w%tab_width% vncon_eedge gcheckedit section, %A_Space%-eedge : Enhance edges (1...100) GUI, add, edit, xs20 w50 right number limit100 vncon_eedge_edit disabled, GUI, add, checkbox, xs w%tab_width% vncon_equalize section, %A_Space%-equalize : Equalize GUI, add, checkbox, xs w%tab_width% vncon_floyd section, %A_Space%-floyd : Use floydSteinberg dithering for conversion (Colors and Grey only) GUI, add, Text, xs w%tab_width%, `nDescription:`n`nNConvert is a batch utility for converting graphic files. `nNConvert is provided as FREEWARE for private non-commercial or educational use (including non-profit organization) /* ; nconvert -frestore : Focus restoration -gamma value : Modify gamma (0.01<->5.0 -gammasat value : Modify gamma (0.01<->5.0 -log : Apply logarithmic correction -negate : Negate -new bpp w h : Create new bitmap -noise reduce : Reduce noise -normalize : Normalize -rotate_flag : Rotate flags smooth : Use smooth rotate -rotate degrees : Rotate -sepia percent : Sepia -sharpen percent : Sharpen (1...100) -shear : Shear -slice : Slice -soften percent : Soften (1...100) -solarize value : Solarize (1...255) -text_font name size : Font name and size -text_color r g b : Text color -text_back r g b : Text background color -text_flag pos : Position of text top-left, top-center, top-right center-left, center, center-right bottom-left, bottom-center, bottom-right -text_pos x y : Position or offset -text_rotation degrees : Rotation -truecolours : Convert in True Colors */ GUI, Tab, Tesseract GUI, add, Text, x%tab_left% y%tab_top% w%tab_width% section, Tesseract processing options GUI, add, checkbox, xs w%tab_width% vtess_l gcheckedit section, %A_Space%-l : Language of scanned text. GUI, add, DropDownList, xs20 w100 limit100 vtess_l_edit disabled, %lang% GUI, add, Text, xs w%tab_width%, `nDescription:`n`nTesseract is a free software optical character recognition engine for various operating systems.`nOriginally developed as proprietary software at Hewlett-Packard between 1985 and 1995, it had very little work done on it in the following decade. It was then released as open source in 2005 by Hewlett Packard and UNLV. Tesseract development is currently sponsored by Google. It is released under the Apache License, Version 2.0.`n`nTesseract is considered one of the most accurate free software OCR engines currently available ifexist %app_gocr% { GUI, Tab, GOCR GUI, add, Text, x%tab_left% y%tab_top% w%tab_width% section, GOCR processing options GUI, add, checkbox, xs w%tab_width% vgocr_p gcheckedit section, %A_Space%-p : database path including final slash (default is ./db/) GUI, add, edit, % "xs20 w" tab_width - 60 " vgocr_p_edit section disabled", %db_gocr% GUI, add, button, ys w30 gfunction_browse, ... GUI, add, Text, x%tab_left% ys+5 h0 section, GUI, add, checkbox, xs w%tab_width% vgocr_l gcheckedit section, %A_Space%-l : threshold grey level 0<160<=255 (0 = autodetect) GUI, add, edit, xs20 w50 right number limit100 vgocr_l_edit disabled, GUI, add, checkbox, xs w%tab_width% vgocr_d gcheckedit section, %A_Space%-d : dust_size (remove small clusters, -1 = autodetect) GUI, add, edit, xs20 w50 right number limit100 vgocr_d_edit number disabled, GUI, add, checkbox, xs w%tab_width% vgocr_s gcheckedit section, %A_Space%-s : spacewidth/dots (0 = autodetect) GUI, add, edit, xs20 w50 right number limit100 vgocr_s_edit disabled, GUI, add, checkbox, xs w%tab_width% vgocr_m gcheckedit section, %A_Space%-m : operation modes (bitpattern, see manual) GUI, add, edit, xs20 w50 right number limit100 vgocr_m_edit disabled, GUI, add, checkbox, xs w%tab_width% vgocr_a gcheckedit section, %A_Space%-a : value of certainty (in percent, 0..100, default=95) GUI, add, edit, xs20 w50 right number limit100 vgocr_a_edit disabled, GUI, add, Text, xs w%tab_width%, `nDescription:`n`nGOCR is an OCR (Optical Character Recognition) program, developed under the GNU Public License. It converts scanned images of text back to text files. } GUI, Tab, About GUI, Tab ; Future controls are not part of any tab control. GUI, Add, Button, % "x" gui_width - 125 " y" gui_height - tab_bottom - 18 " w50 gbutton_cancel section", Cancel GUI, Add, Button, ys w50 gbutton_ok default, OK gosub parse_parameters ; to make sure the set parameters are reflected in the GUI GUI, show, h%gui_height% w%gui_width%, %app_name% %app_version% - preferences and settings return choose_engine: GUI, submit, nohide IniWrite, %ocr_engine%, %ini_file%, general, ocr_engine return checkedit: ; this subroutine disables and enables the edit gui control accompanying a checkbox gui, submit, nohide ; needed so we can tell if the checkbox is checked if %A_GuiControl% = 1 GUIControl, enable, %A_GuiControl%_edit else GUIControl, disable, %A_GuiControl%_edit return function_browse: gui, submit, nohide ; needed so we can tell if the checkbox is checked if gocr_p <> 1 return GUI, submit, nohide FileSelectFolder, db_gocr , *%db_gocr%, , %App_Name% : Select GOCR database folder if db_gocr <> { db_gocr = %db_gocr%\ GuiControl,, gocr_p_edit, %db_gocr% } outputdebug > %gocr_p_edit% return collect_tesseract_languages: ; collects the available language for Tesseract lang := SplitPath, app_tesseract , , OutDir Loop, %OutDir%\tessdata\*.traineddata { if lang = lang = %A_LoopFileName% else lang = %lang%|%A_LoopFileName% } StringReplace, lang, lang, .traineddata,,ALL return about: msgbox %App_name% - %App_version%`nby %App_author%`n`nabout text. return button_cancel: GUI, destroy return parse_parameters: ; parse_parameters is the subroutine that turns parameters_mkbitmap is turned into : vmkb_x and more function_parse("ncon",parameters_nconvert,nconvert_n_params) function_parse("mkb",parameters_mkbitmap,mkbitmap_n_params) function_parse("pot",parameters_potrace,potrace_n_params) function_parse("tess",parameters_tesseract,tesseract_n_params) ifexist %app_gocr% function_parse("gocr",parameters_gocr,gocr_n_params) return ; function_parse will parse the parameters found in the ini, compare them to the ..._n_params above and fill the GUI with them function_parse(name,list,n_params) { loop, parse, list, %A_Space% { if A_LoopField <> { if n <> 1 ; n = 1 means that previously, a parameter has been found that has a value after it { ; not a value, so check if this parameter will have a value stringreplace , param, A_LoopField, -,,ALL ; first get rid of the - in the parameter if param in %n_params% n = 1 ; has no value else n = 0 ; has a value GUIControl,, %name%_%param%, 1 ;outputdebug gui %name%_%param% = 1 } else { if param in %n_params% { GUIControl, enable, %name%_%param%_edit GUIControl,, %name%_%param%_edit, %A_LoopField% ;outputdebug gui %name%_%param%_edit = enable ;outputdebug gui %name%_%param%_edit = %A_LoopField% param := n = 0 } } } } } collect_parameters: ; this is where the parameters are turned from vmkb_x into : parameters_mkbitmap total := function_collect("tess","l","1") parameters_tesseract := total total := function_collect("gocr","p","1") total := % total function_collect("gocr","l","1") total := % total function_collect("gocr","d","1") total := % total function_collect("gocr","s","1") total := % total function_collect("gocr","m","1") total := % total function_collect("gocr","a","1") parameters_gocr := total total := function_collect("mkb","i") total := % total function_collect("mkb","f","1") total := % total function_collect("mkb","s","1") total := % total function_collect("mkb","t","1") total := % total function_collect("mkb","n","1") total := % total function_collect("mkb","b","1") total := % total function_collect("mkb","l") total := % total function_collect("mkb","3") total := % total function_collect("mkb","g") parameters_mkbitmap := total total := function_collect("pot","z") total := % total function_collect("pot","o","1") total := % total function_collect("pot","r","1") total := % total function_collect("pot","t","1") total := % total function_collect("pot","a","1") total := % total function_collect("pot","n","1") total := % total function_collect("pot","u","1") total := % total function_collect("pot","i") parameters_potrace := total total := function_collect("ncon","autocontrast") total := % total function_collect("ncon","autolevels") total := % total function_collect("ncon","contrast","1") total := % total function_collect("ncon","dither") total := % total function_collect("ncon","deinter","1") total := % total function_collect("ncon","edetail") total := % total function_collect("ncon","efocus") total := % total function_collect("ncon","eedge","1") total := % total function_collect("ncon","equalize") total := % total function_collect("ncon","floyd") parameters_nconvert := total return function_collect(name,switch,edit=0) { param := %name%_%switch% if param = 1 { if edit = 0 variables = % " -" switch " " else variables = % " -" switch " " %name%_%switch%_edit return variables } } button_ok: GUI, submit, nohide gosub collect_parameters GUI, destroy IniWrite, %parameters_nconvert%, %ini_file%, parameters, nconvert IniWrite, %parameters_mkbitmap%, %ini_file%, parameters, mkbitmap IniWrite, %parameters_potrace%, %ini_file%, parameters, potrace IniWrite, %parameters_tesseract%, %ini_file%, parameters, tesseract IniWrite, %parameters_gocr%, %ini_file%, parameters, gocr return menu: ifexist %app_icon% Menu, Tray, Icon, %app_icon% Menu, Tray, Tip, %app_name% %app_version% Menu, tray, NoStandard Menu, tray, add, %app_name% %app_version%, menu_reload Menu, tray, add Menu, tray, add, Capture, capture_toggle Menu, tray, default, Capture Menu, tray, add Menu, tray, add, Open Ini file, open_ini Menu, tray, add, Preferences and settings, gui Menu, tray, add if A_IsCompiled <> 1 { Menu, StandardMenu, Standard Menu, tray, add, Standard menu options, :StandardMenu Menu, tray, add } Menu, tray, add, Over, about Menu, tray, add, Einde, menu_exit return open_ini: ifexist %ini_file% run %ini_file% return menu_reload: reload menu_exit: gosub OnExit capture_toggle: if capture_mode = 1 gosub capture_off else gosub capture_on return capture_on: capture_mode = 1 hotkey Lbutton , capture, on hotkey escape , capture_off, on Menu, tray, Check, Capture settimer , tooltip_start , 50 SetSystemCursor("IDC_CROSS") ; sets the mouse cursor to a big + return capture_off: ToolTip ; clears any tooltip that may be showing capture_mode = 0 hotkey Lbutton , capture, off hotkey escape , capture_off, off Menu, tray, Uncheck, Capture gosub RestoreCursors ; restores the mouse cursor settimer , tooltip_start , off return capture: ;=== step 0 ======================================================================== ; Before we do anything, read the variables, maybe they changed since the start of the script gosub read_variables ;=== step 1 ======================================================================== ; Allow the user to select an area for the OCR and save selected area without cursor in clipboard if ( clipboard <> "" ) OR ( test <> 1 ) gosub get_area gosub capture_off ; to turn the active mode to off ;=== step 2 ======================================================================== ; Clean up the temporary files that may have been left behind FileDelete %tmpfolder%\output_*.* ;=== step 3 ======================================================================== ; 3a: NConvert: Convert the clipboard to an image file RunWait , "%app_nconvert%" %parameters_nconvert% %parameters_nconvert_override% -overwrite -out bmp -o output_1_nconvert.bmp -clipboard, %tmpfolder%, hide ; 3b: MKBitmap: transform images into bitmaps with scaling and filtering RunWait , "%app_mkbitmap%" %parameters_mkbitmap% %parameters_mkbitmap_override% -o output_2_mkbitmap.pbm output_1_nconvert.bmp, %tmpfolder%, hide ; 3c: Potrace: transform bitmaps into vector graphics. RunWait , "%app_potrace%" %parameters_potrace% %parameters_potrace_override% -g -o output_3_potrace.pgm output_2_mkbitmap.pbm, %tmpfolder%, hide if ocr_engine = gocr { ; 3d: NConvert: Convert the clipboard to an image file RunWait , "%app_nconvert%" -overwrite -out pnm -o output_4_nconvert.pnm output_3_potrace.pgm, %tmpfolder%, hide ; 3e: GOCR: The actual OCR RunWait , "%app_gocr%" %parameters_gocr% %parameters_gocr_override% -i output_4_nconvert.pnm -o output_gocr.txt, %tmpfolder%, hide } else ; this is the default: Tesseract { ; 3d: NConvert: Convert the clipboard to an image file RunWait , "%app_nconvert%" -overwrite -out tiff -o output_4_nconvert.tif output_3_potrace.pgm, %tmpfolder%, hide ; 3e: Tesseract: The actual OCR RunWait , "%app_tesseract%" %parameters_tesseract% %parameters_tesseract_override% output_4_nconvert.tif output_tesseract, %tmpfolder%, hide } ;=== step 4 ======================================================================== ; Read the OCR contents to the clipboard if ocr_engine = gocr FileRead OCR_text, %tmpfolder%\output_gocr.txt else FileRead OCR_text, %tmpfolder%\output_tesseract.txt if NoLineReturn = 1 StringReplace, OCR_text, OCR_text, `r`n, , All if OCR_text = finish_status = Error`, no text was detected. else { finish_status = De tekst is herkend en op je klembord gezet.`nDit bericht sluit automatisch na %sec% seconden.`n`n%OCR_text% clipboard := OCR_text } n := 5000 SetTimer, tooltip_finish, 50 SetTimer, RemoveToolTip, 5000 if test = 1 { if ocr_engine = gocr run %tmpfolder%\output_gocr.txt else run %tmpfolder%\output_tesseract.txt } if CleanTemporaryOutput = 1 FileDelete %tmpfolder%\output_*.* return tooltip_start: Tooltip, Maak een kader om de te herkennen tekst.`nDruk op Escape om te annuleren.,%tx%,%ty% return tooltip_finish: n -= 100 sec := ceil(n/1000) MouseGetPos, xpos, ypos xpos += 16 ypos += 16 if sec > 1 Tooltip , %finish_status%, %xpos%, %ypos%, else Tooltip return RemoveToolTip: SetTimer, RemoveToolTip, Off SetTimer, tooltip_finish, Off ToolTip return ;===Description======================================================================== ; Source: Screen clipping script. Saves selected area to clipboard. http://www.autohotkey.com/forum/viewtopic.php?t=49950 ;===Functions========================================================================== CaptureScreen(aRect) { StringSplit, rt, aRect, `,, %A_Space%%A_Tab% nL := rt1 nT := rt2 nW := rt3 - rt1 nH := rt4 - rt2 znW := rt5 znH := rt6 mDC := DllCall("CreateCompatibleDC", "Uint", 0) hBM := CreateDIBSection(mDC, nW, nH) oBM := DllCall("SelectObject", "Uint", mDC, "Uint", hBM) hDC := DllCall("GetDC", "Uint", 0) DllCall("BitBlt", "Uint", mDC, "int", 0, "int", 0, "int", nW, "int", nH, "Uint", hDC, "int", nL, "int", nT, "Uint", 0x40000000 | 0x00CC0020) DllCall("ReleaseDC", "Uint", 0, "Uint", hDC) DllCall("SelectObject", "Uint", mDC, "Uint", oBM) DllCall("DeleteDC", "Uint", mDC) SetClipboardData(hBM) } CreateDIBSection(hDC, nW, nH, bpp = 32, ByRef pBits = "") { NumPut(VarSetCapacity(bi, 40, 0), bi) NumPut(nW, bi, 4) NumPut(nH, bi, 8) NumPut(bpp, NumPut(1, bi, 12, "UShort"), 0, "Ushort") NumPut(0, bi,16) Return DllCall("gdi32\CreateDIBSection", "Uint", hDC, "Uint", &bi, "Uint", 0, "UintP", pBits, "Uint", 0, "Uint", 0) } SetClipboardData(hBitmap) { DllCall("GetObject", "Uint", hBitmap, "int", VarSetCapacity(oi,84,0), "Uint", &oi) hDIB := DllCall("GlobalAlloc", "Uint", 2, "Uint", 40+NumGet(oi,44)) pDIB := DllCall("GlobalLock", "Uint", hDIB) DllCall("RtlMoveMemory", "Uint", pDIB, "Uint", &oi+24, "Uint", 40) DllCall("RtlMoveMemory", "Uint", pDIB+40, "Uint", NumGet(oi,20), "Uint", NumGet(oi,44)) DllCall("GlobalUnlock", "Uint", hDIB) DllCall("DeleteObject", "Uint", hBitmap) DllCall("OpenClipboard", "Uint", 0) DllCall("EmptyClipboard") DllCall("SetClipboardData", "Uint", 8, "Uint", hDIB) DllCall("CloseClipboard") } get_area: CoordMode, Mouse ,Screen CoordMode, Tooltip ,Screen MouseGetPos, MX, MY Gui, 2: +AlwaysOnTop -caption +Border +ToolWindow +LastFound WinSet, Transparent, 80 Gui, 2:Color, lime ; shut tooltip_start off settimer , tooltip_start , off tooltip While, (GetKeyState("LButton", "p")) { MouseGetPos, MXend, MYend Send {control up} w := abs(MX - MXend) h := abs(MY - MYend) If ( MX < MXend ) X := MX Else X := MXend tx := MX + 16 If ( MY < MYend ) { Y := MY tY := MY - 36 } Else { Y := MYend tY := MY + 16 } Gui, 2:Show, x%X% y%Y% w%w% h%h% MouseGetPos, xpos, ypos Tooltip, Maak een kader om de te herkennen tekst.,%tx%,%ty% Sleep, 10 } ToolTip gosub RestoreCursors ; restores the mouse cursor MouseGetPos, MXend, MYend Gui, 2:Destroy If ( MX > MXend ) { temp := MX MX := MXend MXend := temp } If ( MY > MYend ) { temp := MY MY := MYend MYend := temp } Area = %MX%, %MY%, %MXend%, %MYend% Sleep, 100 ; if omitted, GUI sometimes stays in picture CaptureScreen(Area) ; Saves selected area without cursor in Clipboard. return OnExit: ToolTip Suspend gosub RestoreCursors ; restores the mouse cursor ExitApp ; -------------- ; below is just to change the mouse cursor so it's clear when the capture mode is active ; source: http://www.autohotkey.com/forum/viewtopic.php?t=35600 SetSystemCursor( Cursor = "", cx = 0, cy = 0 ) { BlankCursor := 0, SystemCursor := 0, FileCursor := 0 ; init SystemCursors = 32512IDC_ARROW,32513IDC_IBEAM,32514IDC_WAIT,32515IDC_CROSS ,32516IDC_UPARROW,32640IDC_SIZE,32641IDC_ICON,32642IDC_SIZENWSE ,32643IDC_SIZENESW,32644IDC_SIZEWE,32645IDC_SIZENS,32646IDC_SIZEALL ,32648IDC_NO,32649IDC_HAND,32650IDC_APPSTARTING,32651IDC_HELP If Cursor = ; empty, so create blank cursor { VarSetCapacity( AndMask, 32*4, 0xFF ), VarSetCapacity( XorMask, 32*4, 0 ) BlankCursor = 1 ; flag for later } Else If SubStr( Cursor,1,4 ) = "IDC_" ; load system cursor { Loop, Parse, SystemCursors, `, { CursorName := SubStr( A_Loopfield, 6, 15 ) ; get the cursor name, no trailing space with substr CursorID := SubStr( A_Loopfield, 1, 5 ) ; get the cursor id SystemCursor = 1 If ( CursorName = Cursor ) { CursorHandle := DllCall( "LoadCursor", Uint,0, Int,CursorID ) Break } } If CursorHandle = ; invalid cursor name given { Msgbox,, SetCursor, Error: Invalid cursor name CursorHandle = Error } } Else If FileExist( Cursor ) { SplitPath, Cursor,,, Ext ; auto-detect type If Ext = ico uType := 0x1 Else If Ext in cur,ani uType := 0x2 Else ; invalid file ext { Msgbox,, SetCursor, Error: Invalid file type CursorHandle = Error } FileCursor = 1 } Else { Msgbox,, SetCursor, Error: Invalid file path or cursor name CursorHandle = Error ; raise for later } If CursorHandle != Error { Loop, Parse, SystemCursors, `, { If BlankCursor = 1 { Type = BlankCursor %Type%%A_Index% := DllCall( "CreateCursor" , Uint,0, Int,0, Int,0, Int,32, Int,32, Uint,&AndMask, Uint,&XorMask ) CursorHandle := DllCall( "CopyImage", Uint,%Type%%A_Index%, Uint,0x2, Int,0, Int,0, Int,0 ) DllCall( "SetSystemCursor", Uint,CursorHandle, Int,SubStr( A_Loopfield, 1, 5 ) ) } Else If SystemCursor = 1 { Type = SystemCursor CursorHandle := DllCall( "LoadCursor", Uint,0, Int,CursorID ) %Type%%A_Index% := DllCall( "CopyImage" , Uint,CursorHandle, Uint,0x2, Int,cx, Int,cy, Uint,0 ) CursorHandle := DllCall( "CopyImage", Uint,%Type%%A_Index%, Uint,0x2, Int,0, Int,0, Int,0 ) DllCall( "SetSystemCursor", Uint,CursorHandle, Int,SubStr( A_Loopfield, 1, 5 ) ) } Else If FileCursor = 1 { Type = FileCursor %Type%%A_Index% := DllCall( "LoadImageA" , UInt,0, Str,Cursor, UInt,uType, Int,cx, Int,cy, UInt,0x10 ) DllCall( "SetSystemCursor", Uint,%Type%%A_Index%, Int,SubStr( A_Loopfield, 1, 5 ) ) } } } } return RestoreCursors: SPI_SETCURSORS := 0x57 DllCall( "SystemParametersInfo", UInt,SPI_SETCURSORS, UInt,0, UInt,0, UInt,0 ) return /* comparison between Tesseract and GOCR with the same image files: --------------- Tesseract For two years I spent my early mornings walking the streets of West Oakland in the San Francisco Bay Area. lt is a neighborhood steeped in history and diversity, from ship workers to blues musicians. Yet, as freeways were built and factories moved in, the neighborhood became cut off from the rest of city and left isolated and forgotten by many. As I spent time photographing in West Oakland, I began to hnd beauty in the unique and improvised envimnment that was born from the neighborhoods very isolation. Sometimes it was a sad and hard beauty, but often it was hopeful and timeless. I also found intimate moments of ritual that stem from the neighborhood's mixed rural Southem and Latino heritage. These photographs describe the stories and spaces that I found on my walks through West Oakland. --------------- GOCR for mo years t spent my early mornings wa lking the streets ot West Oakland in the San francisco 8ay Area. lt is a neighborhood steeped in hi_oN and diversiN, trom ship workers to blues m_sicians. Yet, as freeways were buitt and tactories moved in, the neighborhood became cut off trom the rest of ciN and le_ isolated and torgottenbymany. As l sp$nt _m_ photogr8phing in We_ 08_l8nd, I beg8n to F_nd be8uN in _8 uniqu8 8nd impro_sed 8nvi_nme___w8s born trom _8 neighbomood's _N isol8_on. Same_mes _ w8s 8 s8d 8nd h8rd b$8u_, but o_en it w8s hop$ful 8nd tim$lest l 8lso tound i_m8te mome_ _ r0' 8l th8t stem trom lh_ neighbomood's mixed _r8l Southem 8nd __no hent8g8. mes_ photogr8phs descnb_ lh_ _ones 8nd sp8ces __ I tound on my w8lks _rough Wen 08tI8nd. */