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.

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

Leave a Reply

Your email address will not be published. Required fields are marked *

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax