Advertisement
WarPie90

Untitled

Aug 6th, 2014
456
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 14.74 KB | None | 0 0
  1. program TesseractTool;
  2. //{$DEFINE NO_TESS}
  3.  
  4. {$IFNDEF NO_TESS}
  5. {$loadlib libTesseract}
  6. {$ENDIF}
  7.  
  8. const
  9.   VERSION = '1.00';
  10.   TESS_DATA_PATH = AppPath + 'tessdata';
  11.   TESS_LANGUAGE = 'eng';
  12.  
  13. type
  14.   TFileMenu = record
  15.     Menu: TMenuItem;
  16.   end;
  17.  
  18. type
  19.   TImageMenu = record
  20.     Menu: TMenuItem;
  21.     LoadClientImage: TMenuItem;
  22.     LoadImage: TMenuItem;
  23.     LoadFromClipboard: TMenuItem;
  24.   end;
  25.  
  26. type
  27.   TThresholdSettings = record
  28.     gb: TGroupBox;
  29.     btnApply: TButton;
  30.     cbInvert: TCheckBox;
  31.     seAmount: TSpinEdit;
  32.     cbMethod: TComboBox;
  33.     lbl, lbl2, lbl3: TLabel;
  34.   end;
  35.  
  36. type
  37.   TResizeSettings = record
  38.     gb: TGroupBox;
  39.     seWidth, seHeight: TSpinEdit;
  40.     lbl1, lbl2: TLabel;
  41.     btnResize: TButton;
  42.   end;
  43.  
  44. type
  45.   TDrawnBox = record
  46.     Cols: TIntegerArray;
  47.     Points: TPointArray;
  48.     Drawn: Boolean;
  49.   end;
  50.  
  51. var
  52.   frm: TForm;
  53.   sb: TScrollBox;
  54.   memo: TMemo;
  55.   pnl: TPanel;
  56.   img: TImage;
  57.   MainMenu: record Menu: TMainMenu; FileMenu: TFileMenu; ImageMenu: TImageMenu; end;
  58.   btnTesseract: TButton;
  59.   ThresholdSett: TThresholdSettings;
  60.   ResizeSett: TResizeSettings;
  61.  
  62.   DrawnBox: TDrawnBox;
  63.   SelectedBox: TBox;
  64.  
  65.  
  66.   boxStarted: Boolean;
  67.   boxPoint, LastPos: TPoint;
  68.  
  69. var
  70.   LoadedBMP: TMufasaBitmap; // Orginal loaded bitmap
  71.   currBMP: TMufasaBitmap;
  72.  
  73. var
  74.   TessPtr: Pointer = nil;
  75.   TessIsSetup: Boolean = False;
  76.  
  77. procedure Debug(const Str: String);
  78. begin
  79.   memo.getLines().add(Str);
  80. end;
  81.  
  82. procedure Tess_Setup();
  83. var
  84.   Time: UInt64 := GetTickCount64();
  85. begin
  86. {$IFNDEF NO_TESS}
  87.   TessPtr := Tesseract_Create();
  88.  
  89.   if (TessPtr = nil) then
  90.     Debug('ERROR: Failed to create a tesseract instance')
  91.   else begin
  92.     if (Tesseract_Init(TessPtr, TESS_DATA_PATH, TESS_LANGUAGE) <> 0) then
  93.       Debug('ERROR: Unable to initizalse tesseract, check Simba console for more infomation')
  94.     else begin
  95.       TessIsSetup := True;
  96.       Debug(Format('Tesseract setup in %d ms', [GetTickCount64() - Time]));
  97.     end;
  98.   end;
  99. {$ENDIF}
  100. end;
  101.  
  102. procedure Tess_Free();
  103. begin
  104. {$IFNDEF NO_TESS}
  105.   if (not TessIsSetup) then
  106.     Exit();
  107.  
  108.   Tesseract_End(TessPtr);
  109.   Tesseract_Delete(TessPtr);
  110.   TessPtr := nil;
  111.   TessIsSetup := False;
  112. {$ENDIF}
  113. end;
  114.  
  115. function Tess_GetText(const BMP: TMufasaBitmap): String;
  116. var
  117.   i: integer;
  118.   textLen: UInt32;
  119.   textPtr: PChar;
  120. begin
  121. {$IFNDEF NO_TESS}
  122.   Result := '';
  123.  
  124.   try
  125.     Tesseract_SetImage(TessPtr, BMP.getData(), BMP.getWidth(), bmp.getHeight(), 4, Integer(BMP.getWidth() * 4));
  126.     textPtr := Tesseract_GetUTF8Text(TessPtr, textLen);
  127.  
  128.     setLength(result, textLen);
  129.     if (textLen > 0) then
  130.     begin
  131.       for i := 1 to textLen do
  132.         result[i] := textPtr[i - 1]^;
  133.     end;
  134.   finally
  135.     Tesseract_FreeUTF8Text(textPtr);
  136.     Tesseract_Clear(TessPtr);
  137.   end;
  138. {$ENDIF}
  139. end;
  140.  
  141. procedure DrawMufasaBitmap(var BMP: TMufasaBitmap; const NewBMP: Boolean = True);
  142. var
  143.   i, h: Integer;
  144.   TBmp: TBitmap;
  145. begin
  146.   img.setWidth(Max(sb.getWidth(), BMP.getWidth()));
  147.   img.setHeight(Max(sb.getHeight(), BMP.getHeight()));
  148.   img.getPicture().Clear();
  149.   TBMP := BMP.ToTBitmap();
  150.   img.getPicture().setBitmap(TBMP);
  151.   TBMP.Free();
  152.   if (NewBMP) then
  153.   begin
  154.     if (CurrBMP <> nil) then
  155.       CurrBMP.Free();
  156.     CurrBMP := BMP.Copy();
  157.   end;
  158. end;
  159.  
  160. procedure LoadClientImage(Sender: TObject); Native;
  161. var
  162.   BMP: TMufasaBitmap;
  163.   W, H: Integer;
  164. begin
  165.   with (Client.getIOManager()) do
  166.   begin
  167.     if (not TargetValid) then
  168.     begin
  169.       Debug('Target isn''t vaild!!');
  170.       Exit();
  171.     end;
  172.  
  173.     GetDimensions(W, H);
  174.     BMP.Init();
  175.     BMP.CopyClientToBitmap(Client.getIOManager(), True, 0, 0, W-1, H-1);
  176.     DrawMufasaBitmap(BMP);
  177.     if (LoadedBMP <> nil) then
  178.       LoadedBMP.Free();
  179.     LoadedBMP := BMP.Copy();
  180.     BMP.Free();
  181.     Debug('Loaded client image');
  182.   end;
  183. end;
  184.  
  185. procedure LoadImage(Sender: TObject); Native;
  186. var
  187.   fl: TOpenDialog;
  188.   bmp: TMufasaBitmap;
  189. begin
  190.   fl.Init(frm);
  191.   fl.setFilter('Graphic (*.bmp;*.xpm;*.png;*.pbm;*.pgm;*.ppm;*.ico;*.icns;*.cur;*.jpg;*.jpeg;*.jpe;*.jfif)|*.bmp;*.xpm;*.png;*.pbm;*.pgm;*.ppm;*.ico;*.icns;*.cur;*.jpg;*.jpeg;*.jpe;*.jfif|Bitmaps (*.bmp)|*.bmp|Pixmap (*.xpm)|*.xpm|Portable Network Graphic (*.png)|*.png|Portable PixMap (*.pbm;*.pgm;*.ppm)|*.pbm;*.pgm;*.ppm|Icon (*.ico)|*.ico|OSX Icon Resource (*.icns)|*.icns|Cursor (*.cur)|*.cur|Joint Picture Expert Group (*.jpg;*.jpeg;*.jpe;*.jfif)|*.jpg;*.jpeg;*.jpe;*.jfif|All files (*.*)|*.*|');
  192.   fl.setOptions([ofFileMustExist]);
  193.   fl.setInitialDir(AppPath);
  194.  
  195.   if (fl.Execute) then
  196.   begin
  197.     bmp.Init();
  198.     bmp.LoadFromFile(fl.getFileName());
  199.     DrawMufasaBitmap(bmp);
  200.     if (LoadedBMP <> nil) then
  201.       LoadedBMP.Free();
  202.     LoadedBMP := BMP.Copy();
  203.     bmp.Free();
  204.   end;
  205.  
  206.   fl.Free();
  207. end;
  208.  
  209. procedure LoadFromClipboard(Sender: TObject); Native;
  210. var
  211.   TBMP: TBitmap;
  212.   BMP: TMufasaBitmap;
  213. begin
  214.   if (LoadedBMP <> nil) then
  215.     LoadedBMP.Free();
  216.  
  217.   LoadedBMP.Init();
  218.   TBMP.Init();
  219.  
  220.   try
  221.     TBMP.LoadFromClipboardFormat();
  222.   except
  223.     Debug('Failed to load from clipboard: Wrong format!');
  224.     TBMP.Free();
  225.     Exit();
  226.   end;
  227.  
  228.   LoadedBMP.LoadFromTBitmap(TBMP);
  229.   DrawMufasaBitmap(LoadedBMP);
  230.   TBMP.Free();
  231. end;
  232.  
  233. procedure CanvasSetPixelInv(Canvas:TCanvas; TPA:TPointArray);
  234. var color:TRGB32; i:Integer;
  235. begin
  236.   for i:=0 to High(TPA) do
  237.   begin
  238.     color := TRGB32(Canvas.GetPixel(TPA[i].x,TPA[i].y));
  239.     color.R := color.R xor 255;
  240.     color.G := color.G xor 255;
  241.     color.B := color.B xor 255;
  242.     Canvas.SetPixel(TPA[i].x,TPA[i].y,TColor(color));
  243.   end;
  244. end;
  245.  
  246.  
  247. (*--| Event handling |--------------------------------------------------------*)
  248. procedure onNotifyEvent(Sender: TObject); Native;
  249. var
  250.   Time: UInt64 := GetTickCount64();
  251.   Str: String;
  252.   Lines: TStringArray;
  253.   i: Integer;
  254.   Method: TBmpThreshMethod;
  255.   Invert: Boolean;
  256. begin
  257.   case (Sender) of
  258.     btnTesseract:
  259.       begin
  260.         Str := Tess_GetText(CurrBMP);
  261.         Debug(Format('Tesseract took %d ms (%dx%d)', [GetTickCount64() - Time, img.getPicture().getBitmap().getWidth(), img.getPicture().getBitmap().getHeight()]));
  262.         Debug('Result: ');
  263.  
  264.         Lines := Explode(#10, Str);
  265.         for i := 0 to High(Lines) do
  266.         begin
  267.           Str := Trim(Lines[i]);
  268.  
  269.           if (Str <> '') then
  270.             Debug('-' + Str);
  271.         end;
  272.       end;
  273.     ThresholdSett.btnApply:
  274.       begin
  275.         case (ThresholdSett.cbMethod.getCaption()) of
  276.           'TM_Mean': Method := TM_Mean;
  277.           'TM_MinMax': Method := TM_MinMax;
  278.         end;
  279.  
  280.         case (ThresholdSett.cbInvert.getState()) of
  281.           cbChecked: Invert := True;
  282.           cbUnchecked: Invert := False;
  283.         end;
  284.  
  285.         CurrBMP.ThresholdAdaptive(0, 255, Invert, Method, ThresholdSett.seAmount.getValue());
  286.         Debug(Format('Threshold took %d ms (%dx%d)', [GetTickCount64() - Time, img.getPicture().getBitmap().getWidth(), img.getPicture().getBitmap().getHeight()]));
  287.         DrawMufasaBitmap(CurrBMP, False);
  288.       end;
  289.   end;
  290. end;
  291.  
  292. procedure onKeyEvent(Sender: TObject; var Key: Word; Shift: TShiftState); Native;
  293. begin
  294.   case Key of
  295.     VK_Z:
  296.       if (ssCtrl in Shift) then
  297.       begin
  298.         DebugLn('Undo');
  299.       end;
  300.     VK_Y:
  301.       if (ssCtrl in Shift) then
  302.       begin
  303.         DebugLn('Redo');
  304.       end;
  305.   end;
  306. end;
  307.  
  308. procedure onImgMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); Native;
  309. begin
  310.   if (not BoxStarted) then
  311.   begin
  312.     BoxStarted := True;
  313.     BoxPoint := Point(X, Y);
  314.   end else begin
  315.     SelectedBox := TBox([BoxPoint.x, BoxPoint.y, LastPos.x, LastPos.y]);
  316.     BoxStarted := False;
  317.   end;
  318. end;
  319.  
  320. procedure onImgMouseMove(Sender: TObject; Shift: TShiftState; x, y: Integer); Native;
  321. var
  322.   c: TCanvas;
  323.   BoxToDraw: TBox;
  324.  
  325.   function DashedEdgeFromBox(B:TBox): TPointArray;
  326.   var i:Integer;
  327.   begin
  328.     for i:=B.x1 to B.x2 do
  329.       if (i mod 4 <> 0) then
  330.       begin
  331.         Result := Result + Point(i,b.y1);
  332.         Result := Result + Point(i,b.y2);
  333.       end;
  334.     Inc(B.Y1); Dec(B.Y2);
  335.     for i:=B.y1 to B.y2 do
  336.       if (i mod 4 <> 0) then
  337.       begin
  338.         Result := Result + Point(b.x1,i);
  339.         Result := Result + Point(b.x2,i);
  340.       end;
  341.   end;
  342. begin
  343.   if (not BoxStarted) then
  344.     Exit();
  345.  
  346.   c := img.getCanvas();
  347.   if (DrawnBox.Drawn) then
  348.     c.SetPixels(DrawnBox.Points, DrawnBox.Cols);
  349.  
  350.   BoxToDraw := TBox([BoxPoint.x, BoxPoint.y, x, y]);
  351.  
  352.   if (BoxToDraw.X1 > BoxToDraw.X2) then
  353.     Swap(BoxToDraw.X1, BoxToDraw.X2);
  354.   if (BoxToDraw.Y1 > BoxToDraw.Y2) then
  355.     Swap(BoxToDraw.Y1,BoxToDraw.Y2);
  356.  
  357.   DrawnBox.Points := DashedEdgeFromBox(BoxToDraw);
  358.   DrawnBox.Cols := c.GetPixels(DrawnBox.Points);
  359.   CanvasSetPixelInv(c,DrawnBox.Points);
  360.  
  361.   DrawnBox.Drawn := True;
  362.   LastPos := TPoint([x, y]);
  363. end;
  364.  
  365. procedure Resize(Sender: TObject); Native;
  366. var
  367.   tmp: TMufasaBitmap;
  368.   NewW, NewH: Integer;
  369.   Time: UInt64 := GetTickCount64();
  370. begin
  371.   tmp := LoadedBMP.Copy();
  372.  
  373.   NewW := tmp.getWidth() * ResizeSett.seWidth.getValue();
  374.   NewH := tmp.getHeight() * ResizeSett.seHeight.getValue();
  375.   DebugLn(Format('NewW %d, NewH %d', [NewW, NewH]));
  376.  
  377.   tmp.ResizeEx(RM_Bilinear, NewW, NewH);
  378.   DrawMufasaBitmap(tmp);
  379.   tmp.Free();
  380.  
  381.   Debug(Format('Resized Image (%d, %d) > (%d, %d) in %d ms', [LoadedBMP.getWidth(), LoadedBMP.getHeight(), NewW, NewH, GetTickCount64() - Time]));
  382. end;
  383.  
  384. procedure Create_Form(); Native;
  385. var
  386.   i: Integer;
  387. begin
  388.   frm.Init(nil);
  389.   with (frm) do
  390.   begin
  391.     setCaption('Tesseract Tool (v'+VERSION+') - By Olly');
  392.     setWidth(800);
  393.     setHeight(600);
  394.     setPosition(poScreenCenter);
  395.     setOnKeyDown(onKeyEvent);
  396.     setOnShow(LoadClientImage);
  397.     getConstraints().setMinHeight(600);
  398.     getConstraints().setMinWidth(800);
  399.     setKeyPreview(True);
  400.   end;
  401.  
  402.   MainMenu.Menu.Init(frm);
  403.   with (MainMenu) do
  404.   begin
  405.     FileMenu.Menu := Menu.AddMenu('File');
  406.  
  407.     ImageMenu.Menu := Menu.AddMenu('Image');
  408.     ImageMenu.LoadClientImage := ImageMenu.Menu.AddMenu('Load Client Image');
  409.     ImageMenu.LoadClientImage.setOnClick(LoadClientImage);
  410.     ImageMenu.LoadImage := ImageMenu.Menu.AddMenu('Load Image');
  411.     ImageMenu.LoadImage.setOnClick(LoadImage);
  412.     ImageMenu.LoadFromClipboard := ImageMenu.Menu.AddMenu('Load From Clipboard');
  413.     ImageMenu.LoadFromClipboard.setOnClick(LoadFromClipboard);
  414.   end;
  415.  
  416.   sb.Init(frm);
  417.   with (sb) do
  418.   begin
  419.     setParent(frm);
  420.     setAlign(alClient);
  421.     setBorderStyle(bsNone);
  422.   end;
  423.  
  424.   img.Init(frm);
  425.   with (img) do
  426.   begin
  427.     setParent(sb);
  428.     setWidth(1500);
  429.     setHeight(1500);
  430.     setCursor(crCross);
  431.     setCenter(True);
  432.     setOnMouseMove(onImgMouseMove);
  433.     setOnMouseDown(onImgMouseDown);
  434.   end;
  435.  
  436.   pnl.Init(frm);
  437.   with (pnl) do
  438.   begin
  439.     setParent(frm);
  440.     setHeight(150);
  441.     setAlign(alBottom);
  442.     setBevelOuter(bvLowered);
  443.   end;
  444.  
  445.   memo.Init(frm);
  446.   with (memo) do
  447.   begin
  448.     setReadOnly(True);
  449.     setParent(pnl);
  450.     setHeight(100);
  451.     setAlign(alBottom);
  452.     setScrollBars(ssAutoVertical);
  453.     Debug('Tesseract Tool Version ' + VERSION);
  454.     Debug('Hot Keys: Ctrl + Z = Undo | Ctrl + Y = Redo');
  455.   end;
  456.  
  457.   btnTesseract.Init(frm);
  458.   with (btnTesseract) do
  459.   begin
  460.     setParent(pnl);
  461.     setAlign(alClient);
  462.     setCaption('Tesseract!');
  463.     setOnClick(onNotifyEvent);
  464.   end;
  465.  
  466.   with (ThresholdSett) do
  467.   begin
  468.     gb.Init(frm);
  469.     with (gb) do
  470.     begin
  471.       setParent(pnl);
  472.       setAlign(alLeft);
  473.       setWidth(350);
  474.       setCaption('Threshold');
  475.     end;
  476.  
  477.     lbl.Init(frm);
  478.     with (lbl) do
  479.     begin
  480.       setParent(gb);
  481.       setLeft(5);
  482.       setTop(5);
  483.       setWidth(lbl.getCanvas().TextWidth('Invert') + 10);
  484.       setCaption('Invert');
  485.     end;
  486.  
  487.     cbInvert.Init(frm);
  488.     with (cbInvert) do
  489.     begin
  490.       setParent(gb);
  491.       setTop(lbl.getTop() - 1);
  492.       setLeft(lbl.getLeft() + lbl.getWidth());
  493.     end;
  494.  
  495.     lbl2.Init(frm);
  496.     with (lbl2) do
  497.     begin
  498.       setParent(gb);
  499.       setLeft((cbInvert.getLeft() + cbInvert.getHeight()));
  500.       setTop(lbl.getTop());
  501.       setWidth(lbl.getCanvas().TextWidth('Method') + 5);
  502.       setCaption('Method');
  503.     end;
  504.  
  505.     cbMethod.Init(frm);
  506.     with (cbMethod) do
  507.     begin
  508.       setParent(gb);
  509.       setTop(1);
  510.       setLeft((lbl2.getLeft() + lbl2.getWidth()) + 5);
  511.       setWidth(cbMethod.getCanvas().TextWidth('TM_MinMax') + 25);
  512.       setReadOnly(True);
  513.       getItems().Add('TM_Mean');
  514.       getItems().Add('TM_MinMax');
  515.       setCaption('TM_Mean');
  516.     end;
  517.  
  518.     lbl3.Init(frm);
  519.     with (lbl3) do
  520.     begin
  521.       setParent(gb);
  522.       writeln(cbMethod.getWidth());
  523.       setLeft((cbMethod.getLeft() + cbMethod.getWidth()) + 7);
  524.       setTop(lbl.getTop());
  525.       setCaption('Amount');
  526.       setWidth(lbl.getCanvas().TextWidth('Amount') + 5);
  527.     end;
  528.  
  529.     seAmount.Init(frm);
  530.     with (seAmount) do
  531.     begin
  532.       setParent(gb);
  533.       setTop(1);
  534.       setLeft((lbl3.getLeft() + lbl3.getWidth()) + 7);
  535.       setMinValue(-255);
  536.       setMaxValue(255);
  537.     end;
  538.  
  539.     btnApply.Init(frm);
  540.     with (btnApply) do
  541.     begin
  542.       setParent(gb);
  543.       setLeft((seAmount.getLeft() + seAmount.getWidth()) + 8);
  544.       setCaption('Apply Threshold');
  545.       setOnClick(onNotifyEvent);
  546.       setWidth(frm.getCanvas().TextWidth('Apply Threshold') + 25);
  547.     end;
  548.  
  549.     gb.setWidth((btnApply.getLeft() + btnApply.getWidth()) + 10);
  550.   end;
  551.  
  552.   with (ResizeSett) do
  553.   begin
  554.     gb.Init(frm);
  555.     with (gb) do
  556.     begin
  557.       setParent(pnl);
  558.       setAlign(alLeft);
  559.       setWidth(220);
  560.       setCaption('Resize');
  561.     end;
  562.  
  563.     lbl1.Init(frm);
  564.     with (lbl1) do
  565.     begin
  566.       setParent(gb);
  567.       setTop(5);
  568.       setLeft(5);
  569.       setCaption('W');
  570.     end;
  571.  
  572.     seWidth.Init(frm);
  573.     with (seWidth) do
  574.     begin
  575.       setParent(gb);
  576.       setTop(2);
  577.       setValue(1);
  578.       setLeft(lbl1.getCanvas().TextWidth('W') + 10);
  579.     end;
  580.  
  581.     lbl2.Init(frm);
  582.     with (lbl2) do
  583.     begin
  584.       setParent(gb);
  585.       setTop(5);
  586.       setLeft((seWidth.getLeft() + seWidth.getWidth()) + 8);
  587.       setCaption('H ');
  588.     end;
  589.  
  590.     seHeight.Init(frm);
  591.     with (seHeight) do
  592.     begin
  593.       setParent(gb);
  594.       setTop(2);
  595.       setValue(1);
  596.       setLeft((seWidth.getLeft() + seWidth.getWidth()) + lbl2.getCanvas().TextWidth('H') + 15);
  597.     end;
  598.  
  599.     btnResize.Init(frm);
  600.     with (btnResize) do
  601.     begin
  602.       setParent(gb);
  603.       setTop(1);
  604.       setWidth(lbl1.getCanvas().TextWidth('Resize') + 25);
  605.       setLeft((seHeight.getLeft() + seHeight.getWidth()) + 8);
  606.       setCaption('Resize');
  607.       setOnClick(Resize);
  608.     end;
  609.   end;
  610.  
  611.   try
  612.     Tess_Setup();
  613.     frm.ShowModal();
  614.   finally
  615.     frm.Free();
  616.     Tess_Free();
  617.     if (LoadedBMP <> nil) then
  618.       LoadedBMP.Free();
  619.     if (CurrBMP <> nil) then
  620.       CurrBMP.Free();
  621.   end;
  622. end;
  623.  
  624. begin
  625.   Sync(Create_Form);
  626. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement