There are three different jobs hiding in this one, and they need different tools. The text is easy whenever the PDF has real text in it. The pictures can be taken out exactly as they were put in, byte for byte, but only with a command. Whole pages as images is a render, which any of these routes can do.
The text of a three-page report, pulled out in the browser.
poppler's command-line tools do all three. Install with brew install poppler
on a Mac or apt install poppler-utils on Debian and Ubuntu.
pdftotext report.pdf report.txt # the text
pdfimages -all report.pdf img # the pictures, as they were stored
pdftoppm -png -r 150 report.pdf page # every page as a 150 dpi PNG
Get the text
pdftotext writes the text in reading order. On our three-page sample report
(poppler 25.03.0) it found 197 words, the same 197 the browser tool finds.
Add -layout when the position on the page matters, such as a table or two
columns side by side. Without it, the bar chart's labels come out as a list,
values first and then the months:
92k
74k
61k
55k
48k
42k
Jan
Feb
With -layout, each value sits over its month again, as it does on the page:
pdftotext -layout report.pdf report.txt
74k
61k
55k
48k
42k
Jan Feb Mar Apr May Jun
Use -f 2 -l 4 to take only pages 2 to 4. Add a single - instead of a file
name to print the text to the terminal.
On a Mac without poppler, open the PDF in Preview, press ⌘A and ⌘C, and paste it where you need it. For a long document, a file is easier to check than a clipboard.
In the browser
- Open PDF to Text and drop the PDF on the page. The text is read straight away; there is nothing to set.
- Check the line under the file name: pages, words and characters. A number of words far too low for the document means some pages are scans.
- Press Copy text, or Download .txt for a UTF-8 file named after the PDF.
The tool keeps the PDF's line breaks, but on our sample it also put an empty
line after every line of a paragraph, as the picture above shows, so the
.txt comes out double-spaced. Columns and tables come out as running text,
like pdftotext without -layout: for a table, use the command.
Get the pictures out, at their original quality
pdfimages -list shows every picture stored in the PDF without writing
anything:
pdfimages -list report.pdf
page num type width height color comp bpc enc interp object ID x-ppi y-ppi size ratio
--------------------------------------------------------------------------------------------
1 0 image 1200 800 rgb 3 8 jpeg no 7 0 184 184 31.0K 1.1%
Then -all writes each one in the format it is stored in. A JPEG comes out as
the original .jpg, not decoded and saved again:
pdfimages -all report.pdf img
That wrote one file, img-000.jpg, 1200 by 800 pixels and 31,752 bytes. Its
SHA-256 matched the image stream inside the PDF exactly, so nothing was lost.
Without -all, pdfimages decodes every picture to PPM, which is large and
no better. Add -p to put the page number in each file name.
The sample report has a photo on page 1 and a bar chart on page 2, but
pdfimages lists one picture. The chart is drawn as shapes, like most charts,
diagrams and logos made in Office or a design app, so there is no image to
extract. To get it, render the page and crop it.
None of our browser tools pulls embedded pictures out of a PDF. PDF to JPG and
PDF to PNG render pages, which is the next section. If you need the photo as
it was sent, pdfimages is the route.
Turn whole pages into images
This is a render: each page is drawn at the resolution you choose, text, pictures and charts together, and saved as one image.
pdftoppm -png -r 150 report.pdf page
That wrote page-1.png to page-3.png, each 1240 by 1755 pixels (A4 at
150 dpi), at 177 KB, 67 KB and 60 KB. Use -jpeg instead of -png for
photo-heavy pages, -r 300 to print, and -f 2 -l 2 for one page.
Pick the resolution, then every page becomes a PNG.
In the browser
- Open PDF to PNG for text and diagrams, or PDF to JPG for scans and photos, and drop the PDF in. Every page appears as a thumbnail.
- Under Resolution, pick Screen (96 dpi), Standard (150 dpi, the default) or High (300 dpi). PDF to JPG also has a JPG quality slider, at 92% to start.
- Every page is exported unless you select some. Click a thumbnail to pick it, Shift-click for a range, Ctrl or Cmd-click to add one.
- Press Convert 3 to PNG (the number follows your selection). One page
downloads as
report-page-1.png; several come as one ZIP.
What each route gives you
On the same three-page report (a photo on page 1, a drawn chart on page 2):
| Route | What you get | The photo | The chart |
|---|---|---|---|
pdfimages -all |
1 file, the stored JPEG | 1200 × 800, byte-identical | Not there |
pdftoppm -png -r 150 |
3 pages, 1240 × 1755 | Part of page 1, redrawn | Part of page 2 |
| PDF to PNG, Standard | 3 pages, 1239 × 1754 | Part of page 1, redrawn | Part of page 2 |
| PDF to JPG, High | 3 pages, 2479 × 3508 | Part of page 1, scaled up | Part of page 2 |
The photo is stored at 1200 by 800 and placed at 184 PPI. Rendering the page at 300 dpi makes the photo's area on the page bigger in pixels, but there is no detail in it that the 1200 by 800 original did not have.
If you get no text: the PDF is a scan
A scanner, or a phone app that "scans" a document, saves each page as one picture. There is no text in the file, only an image of it. To test, we turned the first page of the report into a picture-only PDF:
pdftotext scan.pdf -
It printed nothing at all: the output is a single form-feed character, the
page break, and no words. PDF to Text shows No selectable text found. This
PDF may be a scan, so try an OCR tool instead. pdffonts scan.pdf makes
the same point from the other side: it lists no fonts.
The honest answer is OCR, which reads the letters off the picture.
ocrmypdf puts an invisible text layer behind each page and keeps the page
looking the same, so the result is still a PDF you can search and copy from:
brew install ocrmypdf # or: apt install ocrmypdf
ocrmypdf scan.pdf searchable.pdf
pdftotext searchable.pdf searchable.txt
With ocrmypdf 16.7.0 and Tesseract 5.5.0, every word of the body text came back right. It missed the white-on-purple heading and the small grey caption under the photo: 56 of the page's 72 words. Low contrast and small type are where OCR fails, so read the result before you rely on it.
On a PDF with a text layer it stops with PriorOcrFoundError: page already has text!. For a document that is part text, part scanned pages, use
--skip-text to OCR only the pages that need it.
On a Mac, Preview can do this too. Apple's instructions: open the scanned PDF, choose File › Export… and select Embed Text. The option only appears when Preview has found no text in the document. See Embed text in a PDF.
None of our tools does OCR. PDF to Text reads the text that is in the file and tells you when there is none.
Which to use
- The text, any device: PDF to Text, then Copy
or Download. Use
pdftotext -layoutfor tables and columns. - A photo or logo as it was sent:
pdfimages -all. Nothing in the browser does this. - A page as a picture: PDF to PNG for documents, PDF to JPG for scans, or
pdftoppmfor a folder of PDFs. - A scan:
ocrmypdfor Preview's Embed Text first, then any of the above.
When you have the .txt, it opens in any editor. Images from pdfimages and
the page renders open in any image viewer, and the ZIP from the browser tools
unpacks with a double-click.