← AgenticGHX · Learn
Interactive explainer · Computer graphics

One flyer, two kinds of image

Our weekly-talk flyer lives in this repository twice: a 1,421 KB PNG and an 843 KB PDF. The smaller file keeps its words razor-sharp at any zoom, forever. It also has 72 DPI pixels smuggled inside it — coarser than the PNG it beats. Every number on this page is measured from those two files, and together they explain what an image actually is.

Lesson progress 0%
0

One flyer, two files

Every image on every screen is one of two things: a raster — a grid of coloured dots — or a vector — a list of instructions for drawing shapes. Most people meet the difference the day a logo prints blurry on a banner. We can meet it somewhere closer to home: the same AgenticGHX flyer, exported both ways by the same pipeline, sitting in our repository.

finn-flyer.png · raster
2160 × 2700 pixels, frozen. Every part of it — words included — is dots.
finn-flyer.pdf · "vector"
Text stored as instructions plus embedded fonts. The quotes around "vector" are Section 3.

The PDF is 40% smaller. Now zoom both files into the flyer's biggest word — a placeholder, as it happens — at exactly the same magnification. The words below are the two files rendering the same region of the same design:

The flyer's headline text rendered at 4x zoom from the PDF

Tap the buttons to flip between the two files. Same region, same zoom, rendered by the same tool. Look at the edges of the small grey line — the PDF's letters stay clean; the PNG's are already softening, and they only get worse from here.

The smaller file has the sharper text — at any zoom, because instructions can be redrawn at whatever size you ask. That looks like a clean victory for vector. It is about 80% of one, and the missing 20% is the most useful part of this page.

Every number here is measured. The two files above are the real production artefacts — you can download both at the bottom of the page and check. The script that measured them, build-images-data.py, is committed in the same repository, and re-running it rebuilds this page's data.
1

Raster, under the hood: a grid of numbers

A raster image stores no shapes, no letters, no "background" — only a grid of pixels, and for each pixel, numbers: how much red, green and blue. That is the entire representation. Here is an actual window of the PNG, 22 pixels wide, taken where the big word meets the background — tap any pixel to read its real stored values:

Tap a pixel above to see the numbers the file actually stores for it.

These 308 colour values were read straight out of finn-flyer.png at the left edge of the big word. The cream pixels are the letter; the dark ones are the background; the in-between ones on the boundary are anti-aliasing — the file's only way to fake a smooth edge with square dots.

Multiply the grid out and you get the file's true weight. Three bytes per pixel, before any trickery:

2160 × 2700 pixels × 3 bytes = 16.7 MB of raw numbers
size of finn-flyer.png on disk = 1.4 MB

The 12× gap is lossless compression: PNG finds repetition in the numbers (that huge near-black background is very repetitive) and stores the pattern instead of the copies. Unpack it and you get every pixel back exactly. JPEG, in the next sections, makes the other trade: it throws detail away for a smaller file, and what it throws away never comes back.

This is why raster images have a native size. The grid is the picture. Display it bigger than the grid and something has to invent the missing dots — which is the softness you saw in Section 0.

2

Vector, under the hood: a list of instructions

A vector image stores what you meant: rectangles, curves, text, colours — as instructions a renderer executes at whatever size it is asked. The national flag of Ghana, as an SVG our build script generates, is short enough to read in full. This is the entire file:

loading flag.svg…
Flag of Ghana rendered from a 398-byte SVG
· the SVG above, drawn at any size from the same bytes
A 150-pixel-wide PNG of the flag, stretched
· a 150 px PNG of the same flag, stretched to match
Scale 300px

Drag the slider. The SVG side re-executes its four drawing instructions at the new size — edges stay perfect. The PNG side has only its 150×100 grid of dots, so the browser stretches them into visible blocks. Neither file changes; only the size you demand of it.

The byte economics follow directly. Those 398 bytes of SVG draw a flag at billboard size. A PNG of the same flag at just 1620 pixels wide costs 14 KB — 36× more — and still has a native size it cannot exceed. When a design is made of shapes, flat colour and text, instructions beat dots by orders of magnitude.

The obvious lazy reading — "so vector is better" — dies in Section 4. Try to imagine the drawing instructions for a photograph of a face: there aren't any. The two families exist because the world produces two kinds of picture.
3

Inside the "vector" PDF: a hybrid, measured

Now for the quotes around "vector". Our flyer PDF was produced by Chrome's print-to-PDF from an HTML design. Opening it up and listing what is actually inside:

raster images embedded in the one-page PDF
resolution of its full-page image layers, in pixels per printed inch
real fonts embedded — the text is genuinely vector
characters of selectable text stored as text

Every raster layer the PDF carries, with the resolution it works out to on the page. The PNG export of this same flyer is 192 DPI everywhere — so the PDF's big image layers are 2.7× coarser than the "worse" file.

So the honest anatomy is: the words are instructions, the pictures are pixels — CSS gradients and effects got flattened into 72 DPI images at print time, and the speaker photo was embedded at exactly the 323×404 pixels it arrived as. Which makes a prediction: zoom into the photo in both files, and the PDF's advantage should vanish completely. Same region, same zoom, once more:

the speaker photo, both files, same zoom
The flyer's photo region rendered at 4x zoom from the PDF

Flip between them. No amount of tapping makes one sharper: both files bottom out at the same 323×404 photo. The PNG's copy is a little smoother, the PDF's a little blockier — different resampling of identical information.

That is the general law hiding in this flyer: a file format cannot add information. Text survives in the PDF because the instructions were never lost. The photo is identical in both because both inherited the same pixels. And the gradients are worse in the PDF than the PNG because the print pipeline rasterized them early, at 72 DPI. "Is it a vector file?" is the wrong question — the right one is "what happened to each layer on the way in?"

Why PDFs are like this. PDF was designed to reproduce a page faithfully, whatever that takes — so the format happily mixes vector text, vector shapes and embedded rasters in one file. SVG can do the same (an SVG can contain a PNG). "Vector format" really means "format that can carry instructions" — it is a capability, not a guarantee.
4

File formats, mapped to their families

Formats are just containers for one family or the other — plus rules about compression. The raster ones differ mainly in what they throw away. Here are the same pixels through every mainstream encoder — toggle between our two specimens, because the winner changes:

FormatFamilyLoses data?Reach for it when…
JPEGrasterlossyphotographs going to screens; universal support
PNGrasterlosslessscreenshots, UI, text-on-image, transparency
WebP / AVIFrastereither modethe web, when you control the pipeline — same quality, far fewer bytes
GIFraster256 colours maxonly for simple animation; never for photos
SVGvectorlosslesslogos, icons, diagrams, flags — anything made of shapes
PDFhybriddepends on each layerdocuments and print, where text must stay text
TIFF / RAW / HEICrastervariesprint masters and camera originals — the "keep everything" end
5

What makes each kind — and which one you are secretly using

You rarely choose a family; the tool chooses it the moment the image is born. Cameras can only measure light on a grid — the world arrives as raster. Design tools work in shapes — designs are born vector, even when their users never hear the word:

Born as pixels (raster)

  • Phone and camera photos — a sensor grid measuring light
  • Screenshots — a copy of the screen's pixel grid
  • Scans — a sensor dragged across paper
  • Photoshop, GIMP, Krita, phone editors — tools that edit pixel grids
  • AI image generators — they output pixel grids too

Born as instructions (vector)

  • Figma, Illustrator, Inkscape — shape-and-path editors
  • Canva — vector under the hood, though it exports you a PNG
  • Fonts — every glyph is a tiny vector drawing
  • Code — HTML/CSS, SVG, matplotlib, plotting libraries
  • This flyer — born as of HTML/CSS

The flyer's true source is neither the PNG nor the PDF — it is the HTML file, which is smaller than both and can regenerate either at any resolution, any time. That file is the design; the exports are photographs of it.

The habit that follows: keep the file the design was born in — the Canva/Figma link, the SVG, the HTML — and treat every PNG or JPEG you export as a disposable copy for one specific use. The export can always be remade from the source. The source can never be remade from the export, which is Section 7.
6

What editing really does

Edit a vector and you edit the instructions: move a point, retype a word, change fill="#ce1126". Nothing else is touched, and nothing decays. Edit a raster and you overwrite the numbers in the grid. Every filter you have ever used is arithmetic on that grid — most of them are a tiny matrix called a kernel, slid across every pixel, replacing it with a weighted mix of its neighbours:

The photo's pixels, untouched.

Runs live on the photo from the flyer, in your browser. "Blur" averages each pixel with its neighbours; "sharpen" pushes it away from them; "find edges" keeps only where neighbours disagree. Every photo filter you own is a recipe like this.

Because raster edits overwrite the grid, what matters is what happens when you save. With a lossless format, nothing. With JPEG, each save re-approximates the image — and the folk wisdom says every save compounds the damage. We measured it, and the folk wisdom is half right. Twenty-five re-saves of the speaker photo at quality 85, two ways:

plain re-save (grid aligned) — lost over 24 further saves 1 px crop before each save — lost, and still falling

Quality measured as PSNR against the original — higher is closer; every −6 dB is roughly "the error doubled". Both chains save at the same quality setting, the same number of times. The only difference is a one-pixel crop before each save.

The mechanism: JPEG compresses in 8×8 pixel blocks. Open a JPEG and re-save it unchanged and the blocks line up, so the encoder mostly re-makes the same decisions — after 25 saves our photo had lost just 0.17 dB. But crop, rotate, screenshot or re-frame between saves and the block grid moves: every save becomes a first save on fresh data. One pixel of drift per generation cost 12.2 dB — the error grew roughly four-fold — and each additional share keeps digging. That is the real reason a flyer that has been through a few rounds of forwarding-with-edits looks the way it does.

7

Conversion: the one-way door

Vector → raster is called rasterization, and it is routine: pick a resolution, execute the instructions, keep the dots. It happens every time a vector is displayed at all — your screen is a raster device. Ask our one PDF for the flyer at four different resolutions:

One source file, any output size, decided at conversion time. Note the 300 DPI row: more pixels than the original 192 DPI export (3375 wide against 2160) yet fewer bytes — because the 72 DPI layers inside don't grow any sharper, and smoothly invented dots compress well. More dots is not more detail (Section 3's law again).

Raster → vector is a different animal. The instructions were never in the file, so software has to guess them from the dots — it is called tracing, and here is the standard tool, potrace, run on both our specimens:

The flyer, auto-traced to black-and-white vector shapes
The flyer, traced of SVG. The letterforms survive as shapes (they were shapes once); every photo, gradient and colour is gone.
The speaker photo, auto-traced to black-and-white vector shapes
The photo, traced of SVG. Infinitely scalable, perfectly crisp, and the photograph is simply no longer in it.

potrace 1.16 in its standard single-threshold black-and-white mode. Colour tracing exists and does better on flat-colour art — on photographs it produces the same lesson with more steps.

So the door only swings one way. Keep sources vector for as long as possible; rasterize as the last step, per destination — and when someone hands you a JPEG of a logo and asks for "the vector version", you now know that is a redraw job, not a conversion.

The wrapper trap. Putting a PNG inside an SVG or PDF file does not vectorize anything — you get a raster in a vector coat, like the gradients inside our flyer PDF. If tracing or wrapping could truly recover instructions from dots, Section 3's photo would have looked better in the PDF. It didn't, and it can't.
8

Where I was wrong — twice

This page's plan had a cleaner story in it, and the measurements broke it in two places. Both corrections taught more than the draft would have.

Wrong the first time: the headline. The draft said the PDF was "863 KB and sharp at any size." Twenty lines of inspection code killed the second half: six embedded raster layers, full-page ones at 72 DPI — the "sharp at any size" file carries pictures at about a third of the PNG's resolution, and the photo zoom in Section 3 shows the two files bottoming out identically. The lesson that replaced the headline is better than the headline: vector-ness is a property of layers, not of files, and the only way to know what a file really holds is to look inside it.

Wrong the second time: I expected tracing to bloat. The plan predicted the traced photo would "explode" into a huge SVG. The opposite happened — 35 KB of SVG against the photo's 57 KB of JPEG, a smaller file. What exploded was the information, not the bytes: the trace is crisp, scalable and no longer a photograph. A smaller file had destroyed the image. That corrected a lazy equation this page might otherwise have taught you: file size is not fidelity — in either direction.

The method that caught both: measure before asserting, and when the measurement disagrees with the story, the story loses. Both wrong claims felt obviously true. Both were checkable in under a minute. Nearly everything written about image formats online asserts the equivalent claims without checking them.

Check your understanding

Five questions across the key ideas.
The lesson at a glance
✓ Measured, not estimated

Where these numbers come from

Every figure was computed by website/scripts/build-images-data.py from the artefacts in this repository, offline, and written into this page as data. The zoom evidence was rendered by the same script. Encoder versions are recorded in the data blob because byte counts depend on them. Built . The two artefacts themselves: the PNG (1.4 MB) · the PDF (843 KB).

    Same discipline, different question

    Where this sits: this is the second AgenticGHX explainer measured entirely from artefacts we own. The first thing we ever measured this way was text itself — the token tax shows the same sentence costing 2.55× more in Ga than English, and the compute gap prices the hardware all of these pixels run on.

    The sequel to this page: when vector stops winning takes the same two families and asks which one to choose — across a logo, a chart and Ghana's 260 districts — and finds the exact point where the usual advice reverses.

    This is one of the interactive explainers we make at AgenticGHX — talks, learning tracks, and research out of Ghana.

    More from AgenticGHX Learn →