Private by design. Processed in your browser on your device. No account required. How it works

OCR PDF to Text

Extract text from scanned PDFs with private, browser-based OCR. Choose page ranges, language, and cleanup strength, then review confidence hints before downloading a TXT file.
Works with PDF files.
{{ pdfFile.name }}
File size: {{ inputSizeLabel }}
Pages: {{ pageCount }}
PDF preview
{{ pageRangeError || pageRangeSummary }}
Language packs download on first use.
{{ selectedQualityDescription }}
{{ warningMessage }}
Page {{ activePageLabel }} {{ stageLabel }}
{{ page.number }}
{{ errorMessage }}
Choose a PDF to start OCR
We'll show extracted text here as soon as you upload a file.
Working
OCR is running
Scanning page {{ activePageLabel }}. {{ stageLabel || 'Preparing OCR...' }}
{{ overallProgress.toFixed(0) }}% complete
OCR note
Review the scan settings
{{ warningMessage }}
OCR is running
OCR complete
OCR starts automatically
Scanning page {{ activePageLabel }}. {{ stageLabel || 'Preparing OCR...' }}
Copy or download the extracted text below.
Your PDF is loaded. Text will appear below as each page finishes.
{{ overallProgress.toFixed(0) }}% complete
{{ pageRangeSummary }}
Language: {{ selectedLanguageLabel }}
Cleanup: {{ qualityOptions.find((preset) => preset.id === selectedQualityPreset)?.label }}
Average confidence {{ averageConfidenceLabel }}
Words detected {{ ocrStats.totalWords }}
Review pages {{ lowConfidencePagesLabel }}
Lower-confidence pages usually come from faint scans, skew, or heavy compression. Try a stronger cleanup preset or rescan those pages if critical fields look off.
OCR summary
Review the extracted text before download
{{ ocrComplete ? 'The text output is ready. Use the summary to spot pages that may need another OCR pass.' : 'OCR text appears here as each page finishes scanning.' }}
  • Average confidence: {{ ocrStats ? averageConfidenceLabel : "Pending" }}
  • Words detected: {{ ocrStats ? ocrStats.totalWords : 0 }}
  • Review pages: {{ ocrStats ? lowConfidencePagesLabel : 0 }}
{{ ocrComplete ? 'Copy or download the extracted text from this panel.' : 'The text updates here as OCR finishes each page.' }}
Use the extracted text next
OCR PDF downloads a plain TXT file. These links open separate workflows for the original PDF; they do not turn the TXT result into another document.

How to OCR a PDF

Choose a PDF

Drop in a PDF and we will scan each page for text.

Download the TXT file

Save the extracted text as a simple TXT document.

Page-by-page OCR

Scan each PDF page in order for dependable text extraction.

Multiple OCR languages

Switch languages to better match the document you are scanning.

Cleanup presets

Use sharper-text or difficult-scan cleanup modes when the source is faint or noisy.

TXT export

Download the extracted text as a clean TXT file.

Progress and cancel

See OCR progress and stop processing if needed.

Scanned document ready

Best for PDFs that are photos or scans of documents.

Confidence-aware review

See which pages may need a manual review after OCR completes.

Private by default

OCR runs in your browser on your device, not on a server.

Mobile-friendly

Extract text on desktop or mobile without installs.

Frequently Asked Questions

No. OCR runs in your browser, so files stay on your device.

Yes. This tool is designed for scanned or image-based PDFs.

English, Spanish, French, German, Italian, Portuguese, Dutch, Japanese, Korean, and Simplified Chinese are available.

You will get a plain TXT file with optional page separators.

Those pages likely contain faint scans, skewed text, or heavy compression. Review them after OCR or try a stronger cleanup preset.

Large PDFs, higher cleanup presets, and high-resolution scans take longer to process because the OCR engine has more detail to analyze.

Helpful Tips

Tip

Choose the right OCR language first

Matching the language to the document usually improves names, headings, and punctuation before you ever download the TXT file.
Tip

Scan only the pages you need

If you only need a section of a long PDF, use a page range so OCR runs faster and the result is easier to review.
Tip

Review low-confidence pages after export

Pages marked as low confidence often come from faint scans, skewed pages, or dense layouts. Those are the best places to double-check.

Learn More

Learn more

What OCR works best on

OCR is strongest on clear scans with straight lines, readable contrast, and one main language. Blurry pages, handwriting, and layered graphics are harder to interpret.

Learn more

How cleanup presets help

Cleanup presets adjust how the page is prepared before recognition. Balanced works well for most files, while sharper-text and difficult-scan presets can improve weak scans at the cost of extra processing.

Learn more

Where to go after OCR

If you need editable Word output instead of plain text, try PDF to Word. If you only need certain pages first, use Split PDF before OCR.

JPEGConvert logo

Need a hand with your file?

JPEGConvert.com keeps the workflow simple: upload, convert, and download. For the best results, start with the highest-quality source file you have.

About the team | Contact support


(function() { const title = document.querySelector('h1'); const actionRegion = document.querySelector('.action-container, .action-body'); if (!title || !actionRegion || title.querySelector('.tool-hero-mark')) return; const path = window.location.pathname.replace(/\/$/, ''); if (!path || path === '/' || path.startsWith('/converters') || path === '/about' || path === '/contact' || path === '/support' || path === '/privacy-policy') { return; } const lowerKey = path.replace(/^\/(video|audio)\//, '').replace(/^\//, '').toLowerCase(); if (!lowerKey) return; let category = 'image'; if (path.startsWith('/video/')) category = 'video'; if (path.startsWith('/audio/')) category = 'audio'; const isUtility = lowerKey.includes('ascii') || lowerKey === 'check-my-file' || lowerKey.includes('resizer') || lowerKey.includes('metadata') || lowerKey.includes('compress') || lowerKey.includes('base64') || lowerKey.includes('background') || lowerKey.includes('crop') || lowerKey.includes('watermark') || lowerKey.includes('remove-pages') || lowerKey.includes('unlock') || lowerKey.includes('protect') || lowerKey.includes('editor') || lowerKey.includes('excel') || lowerKey.includes('upscale') || lowerKey.includes('merge') || lowerKey.includes('split') || lowerKey.includes('ocr') || lowerKey.includes('sign') || lowerKey.includes('trim') || lowerKey.includes('favicon'); if (category === 'image' && isUtility) category = 'tool'; const labelMap = { jpg: 'JPG', jpeg: 'JPEG', png: 'PNG', gif: 'GIF', svg: 'SVG', pdf: 'PDF', heic: 'HEIC', jfif: 'JFIF', webp: 'WEBP', bmp: 'BMP', ico: 'ICO', word: 'DOCX', docx: 'DOCX', excel: 'Excel', xls: 'XLS', xlsx: 'Excel', mp4: 'MP4', mov: 'MOV', avi: 'AVI', mp3: 'MP3', aac: 'AAC', flac: 'FLAC', wav: 'WAV', webm: 'WEBM', cr2: 'CR2', arw: 'ARW', nef: 'NEF', raf: 'RAF' }; const formatLabel = (value) => labelMap[value] || value.toUpperCase(); function getFormatMeta(key) { if (key === 'check-my-file') { return {primary: 'Check', secondary: 'File', connector: 'dot'}; } const directMatch = key.match(/^([a-z0-9]+)-to-([a-z0-9]+)$/); const convertMatch = key.match(/^convert-([a-z0-9]+)-to-([a-z0-9]+)$/); const convertToMatch = key.match(/^convert-to-([a-z0-9]+)$/); if (directMatch) { return {primary: formatLabel(directMatch[1]), secondary: formatLabel(directMatch[2]), connector: 'arrow'}; } if (convertMatch) { return {primary: formatLabel(convertMatch[1]), secondary: formatLabel(convertMatch[2]), connector: 'arrow'}; } if (convertToMatch) { return {primary: 'Any', secondary: formatLabel(convertToMatch[1]), connector: 'arrow'}; } if (key.startsWith('compress-')) { return {primary: 'Compress', secondary: formatLabel(key.replace('compress-', '')), connector: 'dot'}; } if (key.includes('base64') && key.includes('decode')) { return {primary: 'Base64', secondary: 'Decode', connector: 'dot'}; } if (key.startsWith('base64-to-')) { return {primary: 'Base64', secondary: formatLabel(key.replace('base64-to-', '')), connector: 'arrow'}; } if (key.includes('-to-base64')) { const from = key.replace('convert-', '').replace('-to-base64', ''); return {primary: formatLabel(from), secondary: 'Base64', connector: 'arrow'}; } if (key.includes('base64')) { return {primary: 'Base64', secondary: 'Encode', connector: 'dot'}; } if (key.includes('ascii')) { return {primary: 'ASCII', secondary: 'Art', connector: 'dot'}; } if (key.includes('resizer')) { return {primary: 'Resize', secondary: 'Pixels', connector: 'dot'}; } if (key.includes('remove-pages')) { return {primary: 'Remove', secondary: 'Pages', connector: 'dot'}; } if (key.includes('crop') && key.includes('pdf')) { return {primary: 'Crop', secondary: 'PDF', connector: 'dot'}; } if (key.includes('pdf-editor')) { return {primary: 'Edit', secondary: 'PDF', connector: 'dot'}; } if (key.includes('unlock')) { return {primary: 'Unlock', secondary: 'PDF', connector: 'dot'}; } if (key.includes('protect')) { return {primary: 'Protect', secondary: 'PDF', connector: 'dot'}; } if (key.includes('pdf') && key.includes('metadata')) { return {primary: 'Clean', secondary: 'Metadata', connector: 'dot'}; } if (key.includes('metadata')) { return {primary: 'EXIF', secondary: 'Clean', connector: 'dot'}; } if (key.includes('background')) { return {primary: 'Remove', secondary: 'Background', connector: 'dot'}; } if (key.includes('crop')) { return {primary: 'Crop', secondary: 'Image', connector: 'dot'}; } if (key.includes('watermark')) { return {primary: 'Watermark', secondary: 'Image', connector: 'dot'}; } if (key.includes('upscale')) { return {primary: 'Upscale', secondary: 'Image', connector: 'dot'}; } if (key.includes('merge')) { return {primary: 'Merge', secondary: 'PDF', connector: 'dot'}; } if (key.includes('split')) { return {primary: 'Split', secondary: 'PDF', connector: 'dot'}; } if (key.includes('ocr')) { return {primary: 'OCR', secondary: 'PDF', connector: 'dot'}; } if (key.includes('sign')) { return {primary: 'Sign', secondary: 'PDF', connector: 'dot'}; } if (key.includes('trim')) { return {primary: 'Trim', secondary: 'Video', connector: 'dot'}; } return {primary: 'Tool', secondary: '', connector: 'dot'}; } function getIconClass(key, categoryName) { const toFormat = key.split('-to-')[1]; if (key === 'check-my-file') return 'bi-file-earmark-check'; if (key.includes('ascii')) return 'bi-textarea-t'; if (key.includes('resizer')) return 'bi-aspect-ratio'; if (key.includes('metadata')) return 'bi-shield-slash'; if (key.includes('compress')) return 'bi-file-earmark-zip'; if (key.includes('base64')) return 'bi-journal-code'; if (key.includes('background')) return 'bi-scissors'; if (key.includes('crop')) return 'bi-crop'; if (key.includes('watermark')) return 'bi-type'; if (key.includes('remove-pages')) return 'bi-trash'; if (key.includes('unlock')) return 'bi-unlock'; if (key.includes('protect')) return 'bi-lock'; if (key.includes('editor')) return 'bi-pencil-square'; if (key.includes('excel')) return 'bi-file-earmark-spreadsheet'; if (key.includes('upscale')) return 'bi-arrows-angle-expand'; if (key.includes('merge')) return 'bi-files'; if (key.includes('split')) return 'bi-scissors'; if (key.includes('ocr')) return 'bi-file-earmark-text'; if (key.includes('sign')) return 'bi-pen'; if (key.includes('trim')) return 'bi-scissors'; if (toFormat) { switch (toFormat) { case 'jpg': case 'jpeg': return 'bi-filetype-jpg'; case 'png': return 'bi-filetype-png'; case 'gif': return 'bi-filetype-gif'; case 'svg': return 'bi-filetype-svg'; case 'pdf': return 'bi-filetype-pdf'; case 'word': case 'docx': return 'bi-file-earmark-word'; case 'xls': case 'xlsx': case 'excel': return 'bi-file-earmark-spreadsheet'; case 'heic': return 'bi-filetype-heic'; case 'webp': return 'bi-filetype-webp'; case 'bmp': return 'bi-filetype-bmp'; case 'ico': return 'bi-file-image'; case 'mp4': return 'bi-filetype-mp4'; case 'mov': return 'bi-filetype-mov'; case 'mp3': return 'bi-filetype-mp3'; case 'wav': return 'bi-filetype-wav'; case 'avi': return 'bi-filetype-avi'; default: return 'bi-file-earmark-image'; } } if (categoryName === 'video') return 'bi-film'; if (categoryName === 'audio') return 'bi-music-note-beamed'; if (categoryName === 'image') return 'bi-file-earmark-image'; return 'bi-gear'; } const formatMeta = getFormatMeta(lowerKey); const connectorIcon = formatMeta.connector === 'arrow' ? 'bi-arrow-right-short' : 'bi-dot'; const iconClass = getIconClass(lowerKey, category); const mark = document.createElement('span'); mark.className = `tool-hero-mark converter-mark converter-mark--${category}`; const iconWrap = document.createElement('span'); iconWrap.className = 'converter-mark__icon'; const icon = document.createElement('i'); icon.className = iconClass; iconWrap.appendChild(icon); mark.appendChild(iconWrap); const formatWrap = document.createElement('span'); formatWrap.className = 'converter-format'; const primary = document.createElement('span'); primary.className = 'format-pill'; primary.textContent = formatMeta.primary; formatWrap.appendChild(primary); if (formatMeta.secondary) { const connector = document.createElement('span'); connector.className = 'format-connector'; const connectorIconEl = document.createElement('i'); connectorIconEl.className = connectorIcon; connector.appendChild(connectorIconEl); formatWrap.appendChild(connector); const secondary = document.createElement('span'); secondary.className = 'format-pill format-pill--secondary'; secondary.textContent = formatMeta.secondary; formatWrap.appendChild(secondary); } mark.appendChild(formatWrap); title.classList.add('tool-hero-title'); title.prepend(mark); })();