So, When I am taking an exam that requires me to read a full PDF, and in this case 400+ pages. I found this neat little trick.
https://pdf2jpg.net Convert’s any PDF less than 25MB to thumbnail images.
Using this way, I then target the folder full of the pictures and it dumps all the data to a text file.
Then I use the dumped data to translates from Google translator from English to English then I click the Microphone to start to read the text.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 |
Imports Tesseract Imports System.Threading Imports System.Runtime.InteropServices Imports System.IO Public Class Form1 Public Const MOD_ALT As Integer = &H1 'Alt key Public Const WM_HOTKEY As Integer = &H312 <DllImport("User32.dll")> Public Shared Function RegisterHotKey(ByVal hwnd As IntPtr, ByVal id As Integer, ByVal fsModifiers As Integer, ByVal vk As Integer) As Integer End Function <DllImport("User32.dll")> Public Shared Function UnregisterHotKey(ByVal hwnd As IntPtr, ByVal id As Integer) As Integer End Function <DllImport("dwmapi.dll", PreserveSig:=False)> Public Shared Function DwmIsCompositionEnabled() As Boolean End Function <DllImport("dwmapi.dll", PreserveSig:=False)> Public Shared Sub DwmEnableComposition(ByVal bEnable As Boolean) End Sub <DllImport("user32.dll", EntryPoint:="GetCursorInfo")> Public Shared Function GetCursorInfo(ByRef pci As CURSORINFO) As Boolean End Function <DllImport("user32.dll", EntryPoint:="CopyIcon")> Public Shared Function CopyIcon(ByVal hIcon As IntPtr) As IntPtr End Function <DllImport("user32.dll", EntryPoint:="GetIconInfo")> Public Shared Function GetIconInfo(ByVal hIcon As IntPtr, ByRef piconinfo As ICONINFO) As Boolean End Function Dim aeroIsEnabled As Boolean Dim b As Bitmap Dim graphics As Graphics Dim StartPoint As New Point(0, 0) Dim ScreenShotSize As Drawing.Size Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message) If m.Msg = WM_HOTKEY Then Dim id As IntPtr = m.WParam Select Case (id.ToString) Case "100" Debug.WriteLine("You pressed ALT+S key combination") If StartPoint.IsEmpty Then StartPoint = GetCursorPosition() Debug.WriteLine(StartPoint) Else Dim MyEndPoint As Point = GetCursorPosition() Debug.WriteLine(MyEndPoint) Dim MyTwoPoints As New Point(MyEndPoint.X - StartPoint.X, MyEndPoint.Y - StartPoint.Y) ScreenShotSize = New Size(MyTwoPoints) Debug.WriteLine(ScreenShotSize) 'CaptureScreenshot(New Point(0, 0), PictureBox1.Size) 'This resizes the Background of the image to scale If True Then b = New Bitmap(PictureBox1.Size.Width, PictureBox1.Size.Height) Else b = New Bitmap(MyEndPoint.X - StartPoint.X, MyEndPoint.Y - StartPoint.Y) End If 'ResizeImage(b, b.Width * 3, b.Height * 3) PictureBox1.Image = b graphics = Graphics.FromImage(b) ' graphics.Clear(Color.Transparent) graphics.CopyFromScreen(StartPoint, New Point(0, 0), ScreenShotSize) Dim output As New Bitmap(ScreenShotSize.Width * 2, ScreenShotSize.Height * 2) Using g As Graphics = Graphics.FromImage(output) g.DrawImage(b, 0, 0, PictureBox1.Size.Width * 2, PictureBox1.Size.Height * 2) End Using PictureBox1.Image = output 'PictureBox1.Image.Save("./saved.tiff", System.Drawing.Imaging.ImageFormat.Tiff) 'ResizeImage(b, b.Width * 3, b.Height * 3) ' StartPoint = New Point(0, 0) Application.DoEvents() translateFromMemory(ConvertToByteArray(output)) 'translateFromFile("./saved.tiff") 'translateFromMemory(ConvertToByteArray(New Bitmap(ScreenShotSize.Width, ScreenShotSize.Height, graphics))) End If Case "200" MessageBox.Show("You pressed ALT+C key combination") End Select End If MyBase.WndProc(m) End Sub Public Shared Function ConvertToByteArray(ByVal value As Bitmap) As Byte() Dim ms = New System.IO.MemoryStream value.Save(ms, System.Drawing.Imaging.ImageFormat.Tiff) ' Use appropriate format here Dim bytes = ms.ToArray() Return bytes End Function #Region " ResizeImage " Public Overloads Shared Function ResizeImage(SourceImage As Drawing.Image, TargetWidth As Int32, TargetHeight As Int32) As Drawing.Bitmap Dim bmSource = New Drawing.Bitmap(SourceImage) Return ResizeImage(bmSource, TargetWidth, TargetHeight) End Function Public Overloads Shared Function ResizeImage(bmSource As Drawing.Bitmap, TargetWidth As Int32, TargetHeight As Int32) As Drawing.Bitmap Dim bmDest As New Drawing.Bitmap(TargetWidth, TargetHeight, Drawing.Imaging.PixelFormat.Format32bppArgb) Dim nSourceAspectRatio = bmSource.Width / bmSource.Height Dim nDestAspectRatio = bmDest.Width / bmDest.Height Dim NewX = 0 Dim NewY = 0 Dim NewWidth = bmDest.Width Dim NewHeight = bmDest.Height If nDestAspectRatio = nSourceAspectRatio Then 'same ratio ElseIf nDestAspectRatio > nSourceAspectRatio Then 'Source is taller NewWidth = Convert.ToInt32(Math.Floor(nSourceAspectRatio * NewHeight)) NewX = Convert.ToInt32(Math.Floor((bmDest.Width - NewWidth) / 2)) Else 'Source is wider NewHeight = Convert.ToInt32(Math.Floor((1 / nSourceAspectRatio) * NewWidth)) NewY = Convert.ToInt32(Math.Floor((bmDest.Height - NewHeight) / 2)) End If Using grDest = Drawing.Graphics.FromImage(bmDest) With grDest .CompositingQuality = Drawing.Drawing2D.CompositingQuality.HighQuality .InterpolationMode = Drawing.Drawing2D.InterpolationMode.HighQualityBicubic .PixelOffsetMode = Drawing.Drawing2D.PixelOffsetMode.HighQuality .SmoothingMode = Drawing.Drawing2D.SmoothingMode.AntiAlias .CompositingMode = Drawing.Drawing2D.CompositingMode.SourceOver .DrawImage(bmSource, NewX, NewY, NewWidth, NewHeight) End With End Using Return bmDest End Function #End Region Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load ' Add any initialization after the InitializeComponent() call. 'b = New Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height) b = New Bitmap(PictureBox1.Size.Width, PictureBox1.Size.Height) PictureBox1.Image = b graphics = Graphics.FromImage(b) Me.DisableAero() RegisterHotKey(Me.Handle, 100, MOD_ALT, Keys.S) 'PictureBox1.SizeMode = PictureBoxSizeMode.StretchImage 'translateFromFile("./saved.tiff") End Sub Private Sub Form1_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) _ Handles MyBase.FormClosing UnregisterHotKey(Me.Handle, 100) UnregisterHotKey(Me.Handle, 200) End Sub Private Sub DisableAero() Try aeroIsEnabled = DwmIsCompositionEnabled() If aeroIsEnabled = True Then DwmEnableComposition(False) End If Catch ex As Exception End Try End Sub Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick 'Timer1.Stop() CaptureScreenshot(New Point(0, 0), PictureBox1.Size) 'Timer1.Start() End Sub Private Function CaptureScreenshot(startPoint As Point, DrawingSize As Size) As Boolean Try If b IsNot Nothing Then 'graphics.CopyFromScreen(Screen.PrimaryScreen.Bounds.Location, New Point(0, 0), Screen.PrimaryScreen.Bounds.Size) 'Dim newDrawingSize As New System.Drawing.Size(PictureBox1.Size) 'graphics.CopyFromScreen(New Point(x, y), startPoint, DrawingSize) 'graphics.CopyFromScreen(startPoint, New Point(0, 0), DrawingSize, CopyPixelOperation.SourceAnd) graphics.CopyFromScreen(startPoint, New Point(0, 0), DrawingSize) If False Then Dim x As Integer Dim y As Integer Dim cursorBmp As Bitmap = CaptureCursor(x, y) 'Draws Cursor on picture graphics.DrawImage(cursorBmp, x, y) cursorBmp.Dispose() 'Cursor.Draw(graphics, New Rectangle(Cursor.Position, Cursor.Size)) End If Me.Refresh() End If Catch ex As Exception End Try End Function Private Shared Function CaptureCursor(ByRef x As Integer, ByRef y As Integer) As Bitmap Dim bmp As Bitmap Dim hicon As IntPtr Dim ci As New CURSORINFO() Dim icInfo As ICONINFO ci.cbSize = Marshal.SizeOf(ci) If GetCursorInfo(ci) Then hicon = CopyIcon(ci.hCursor) If GetIconInfo(hicon, icInfo) Then x = ci.ptScreenPos.X - CInt(icInfo.xHotspot) y = ci.ptScreenPos.Y - CInt(icInfo.yHotspot) Dim ic As Icon = Icon.FromHandle(hicon) bmp = ic.ToBitmap() ic.Dispose() Return bmp End If End If Return Nothing End Function Private Shared Function GetCursorPosition() As Point Dim hicon As IntPtr Dim ci As New CURSORINFO() Dim icInfo As ICONINFO Dim x, y As Integer ci.cbSize = Marshal.SizeOf(ci) If GetCursorInfo(ci) Then hicon = CopyIcon(ci.hCursor) If GetIconInfo(hicon, icInfo) Then x = ci.ptScreenPos.X - CInt(icInfo.xHotspot) y = ci.ptScreenPos.Y - CInt(icInfo.yHotspot) Return New Point(x, y) End If End If Return Nothing End Function <StructLayout(LayoutKind.Sequential)> Public Structure CURSORINFO Public cbSize As Int32 Public flags As Int32 Public hCursor As IntPtr Public ptScreenPos As Point End Structure <StructLayout(LayoutKind.Sequential)> Public Structure ICONINFO Public fIcon As Boolean Public xHotspot As Int32 Public yHotspot As Int32 Public hbmMask As IntPtr Public hbmColor As IntPtr End Structure Private Sub translateFromMemory(ByteArray As Byte()) 'Dim testImagePath = "./phototest.tif" Dim testImagePath = "./page1b.png" Try Using engine = New TesseractEngine("./tessdata", "eng", EngineMode.Default) 'Using img = Pix.LoadFromFile(testImagePath) Using img = Pix.LoadTiffFromMemory(ByteArray) Using page = engine.Process(img) Dim text = page.GetText() Console.WriteLine("Mean confidence: {0}", page.GetMeanConfidence()) Console.WriteLine("Text (GetText): " & vbCr & vbLf & "{0}", text) Console.WriteLine("Text (iterator):") Using iter = page.GetIterator() iter.Begin() Do Do Do Do If iter.IsAtBeginningOf(PageIteratorLevel.Block) Then Console.WriteLine("<BLOCK>") End If TextBox1.Text &= (iter.GetText(PageIteratorLevel.Word)) TextBox1.Text &= (" ") If iter.IsAtFinalOf(PageIteratorLevel.TextLine, PageIteratorLevel.Word) Then TextBox1.Text &= vbCrLf End If Loop While iter.[Next](PageIteratorLevel.TextLine, PageIteratorLevel.Word) If iter.IsAtFinalOf(PageIteratorLevel.Para, PageIteratorLevel.TextLine) Then Console.WriteLine() End If Loop While iter.[Next](PageIteratorLevel.Para, PageIteratorLevel.TextLine) Loop While iter.[Next](PageIteratorLevel.Block, PageIteratorLevel.Para) Loop While iter.[Next](PageIteratorLevel.Block) End Using End Using End Using End Using Catch ex As Exception Trace.TraceError(ex.ToString()) Console.WriteLine("Unexpected Error: " + ex.Message) Console.WriteLine("Details: ") Console.WriteLine(ex.ToString()) End Try Console.Write("Press any key to continue . . . ") End Sub Private Sub translateFromFile(testImagePath As String, sw As IO.StreamWriter) Try Using engine = New TesseractEngine("./tessdata", "eng", EngineMode.Default) Using img = Pix.LoadFromFile(testImagePath) Using page = engine.Process(img) Dim text = page.GetText() Console.WriteLine("Mean confidence: {0}", page.GetMeanConfidence()) Console.WriteLine("Text (GetText): " & vbCr & vbLf & "{0}", text) Console.WriteLine("Text (iterator):") Using iter = page.GetIterator() iter.Begin() Do Do Do Do If iter.IsAtBeginningOf(PageIteratorLevel.Block) Then Console.WriteLine("<BLOCK>") End If 'TextBox1.Text &= (iter.GetText(PageIteratorLevel.Word)) 'TextBox1.Text &= (" ") sw.Write(iter.GetText(PageIteratorLevel.Word) & (" ")) If iter.IsAtFinalOf(PageIteratorLevel.TextLine, PageIteratorLevel.Word) Then sw.WriteLine() End If Loop While iter.[Next](PageIteratorLevel.TextLine, PageIteratorLevel.Word) If iter.IsAtFinalOf(PageIteratorLevel.Para, PageIteratorLevel.TextLine) Then Console.WriteLine() End If Loop While iter.[Next](PageIteratorLevel.Para, PageIteratorLevel.TextLine) Loop While iter.[Next](PageIteratorLevel.Block, PageIteratorLevel.Para) Loop While iter.[Next](PageIteratorLevel.Block) End Using End Using End Using End Using Catch ex As Exception Trace.TraceError(ex.ToString()) Console.WriteLine("Unexpected Error: " + ex.Message) Console.WriteLine("Details: ") Console.WriteLine(ex.ToString()) End Try Console.Write("Press any key to continue . . . ") End Sub Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Timer1.Interval = 1000 Timer1.Enabled = True End Sub Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click If (FolderBrowserDialog1.ShowDialog() = DialogResult.OK) Then Using sw As StreamWriter = File.AppendText(FolderBrowserDialog1.SelectedPath & "\Output.txt") For Each MyFile As String In IO.Directory.GetFiles(FolderBrowserDialog1.SelectedPath) translateFromFile(MyFile, sw) Application.DoEvents() Next End Using End If End Sub End Class |