DEV Community

xiaomei Lu
xiaomei Lu

Posted on

PDF, image & video chores: the CLI one-liner + a browser fallback for each

You need to convert one file. Just one.

A teammate sends a .heic screenshot and your image viewer shrugs. The contact form needs a PDF under 5 MB and yours is 11. You recorded a 40 MB screen capture and the bug tracker only accepts GIFs. You don't want to brew install a tool you'll use once, and you really don't want to drop a half-confidential document into the first sketchy "free converter" Google surfaces.

So here's the cheat sheet I keep coming back to: for each common file chore, the CLI one-liner if you live in a terminal, and a no-install browser tool when you don't (or when you're on someone else's machine). I'll be honest about which is better for what — and at the end, which ones run on your own machine vs. on a server.

Disclosure: I build the browser tools I link to (bestaifinds.com). The CLI commands are the real recommendation; the web tools are the fallback for when you can't install anything.


PDFs

Get a PDF under an email/upload limit

gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/ebook \
   -dNOPAUSE -dQUIET -dBATCH -sOutputFile=out.pdf in.pdf
Enter fullscreen mode Exit fullscreen mode

Ghostscript's /ebook preset is the sweet spot — /screen for brutal compression, /printer to keep quality (the PDFSETTINGS docs list what each one does). No Ghostscript handy? → compress it in the browser.

Pull the text out of a PDF (to grep / parse / diff)

pdftotext in.pdf out.txt        # ships with poppler-utils
Enter fullscreen mode Exit fullscreen mode

Indispensable for log-style PDFs and a quick grep. pdftotext (and pdfunite below) come from poppler.

Merge / split

pdfunite a.pdf b.pdf c.pdf merged.pdf       # poppler
qpdf --split-pages in.pdf page.pdf          # -> page-1.pdf, page-2.pdf, ...
Enter fullscreen mode Exit fullscreen mode

qpdf inserts the page number before the extension automatically. No install? → merge in the browser.


Images

Shrink images / ship WebP

cwebp -q 80 photo.png -o photo.webp         # libwebp, lossy by default
cwebp -lossless ui.png -o ui.webp           # for screenshots / flat UI / line art
Enter fullscreen mode Exit fullscreen mode

Over a photographic PNG, lossy WebP at q80 often saves 60–80%; over an already-compressed JPEG, expect more like 20–35% (sometimes less — you're re-encoding existing artifacts). Use -lossless (or -near_lossless) for screenshots and logos, where lossy q80 shows visible ringing. It clears Lighthouse's "next-gen formats" / "efficiently encode images" opportunities and trims LCP. cwebp options → No install? → compress images in the browser.

A note on magick input.jpg -quality 80 out.jpg: re-encoding an already-compressed JPEG to a fixed quality only helps if the original was saved higher than q80 — otherwise it adds a generation of loss and can make the file bigger. For an existing JPEG, reach for a lossless optimizer (jpegtran, jpegoptim) or convert to WebP instead.

Remove a background (avatars, OG images, READMEs)

rembg i input.png output.png    # pip install "rembg[cpu]" first; downloads a model on first run
Enter fullscreen mode Exit fullscreen mode

rembg is great, but it's a Python dep + a model download for a 10-second job. For one image: → remove a background in the browser (the model runs client-side — more on that below).

OCR — image/screenshot → text

tesseract screenshot.png out    # writes out.txt
Enter fullscreen mode Exit fullscreen mode

Tesseract is excellent if it's installed.

That iPhone .heic nobody can open

magick photo.heic photo.jpg          # ImageMagick built with libheif
heif-convert photo.heic photo.jpg    # ships with libheif (Debian: libheif-examples; Homebrew: libheif)
Enter fullscreen mode Exit fullscreen mode

libheif does the actual HEIC decoding under both.


Video

MP4 → GIF (for a PR demo or a bug repro)

ffmpeg -i clip.mp4 -vf "fps=12,scale=480:-1:flags=lanczos" clip.gif
Enter fullscreen mode Exit fullscreen mode

For crisp colors, generate a palette first — ffmpeg's high-quality GIF guide walks through palettegen/paletteuse; worth it for screen recordings. No ffmpeg? → MP4 to GIF in the browser.

Rip the audio: MP4 → MP3

ffmpeg -i talk.mp4 -q:a 0 -map a talk.mp3
Enter fullscreen mode Exit fullscreen mode

The honest part: what runs where

"Free online converter" usually means your file gets uploaded to someone's box. That matters for anything remotely confidential. So here's the straight answer for the browser tools I linked above (I build them, so I checked the actual code path):

Runs entirely in your browser — the file itself is never uploaded:
image compress / resize / format-convert, PNG→WebP, OCR (Tesseract compiled to the browser), background removal (an in-browser ML model), and PDF merge / split / to-JPG / from-JPG (via pdf-lib and pdf.js, both running in your browser). Open DevTools → Network and you'll see the file is never POSTed — the only fetch is the background-removal model, downloaded once, then everything runs locally.

Runs server-side, then deletes after processing:
PDF compression (Ghostscript/qpdf), PDF→text, HEIC→JPG (ImageMagick), and all video work (ffmpeg) — these need real binaries no browser ships. For anything sensitive, prefer the CLI here.

That distinction is the whole reason I dislike most converter sites: they don't tell you. So now you know which is which.


TL;DR

  • Living in a terminal already? The CLI one-liners above cover almost all of these chores.
  • On a borrowed machine, or it's a one-off? The browser tools skip the install.
  • Care about privacy? Use the client-side tools or the CLI for anything you wouldn't email.

The browser tools are all free and signup-free at bestaifinds.com. I built the site partly because I was tired of choosing between installing yet another dependency and trusting a random upload box. If there's a file chore you do constantly that I missed, drop it in the comments — genuinely useful for deciding what to build next.

Top comments (0)